From geek4civic at gmail.com Mon Mar 28 00:47:03 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Mon, 28 Mar 2011 14:47:03 +0900 Subject: [llvm-commits] [cfe-dev] Broken "not" and platform file paths In-Reply-To: References: Message-ID: John, On Thu, Mar 17, 2011 at 3:40 AM, John Thompson wrote: > Index: utils/not/not.cpp > =================================================================== > --- utils/not/not.cpp?(revision 127522) > +++ utils/not/not.cpp?(working copy) > @@ -15,6 +15,11 @@ > ?int main(int argc, const char **argv) { > ?? sys::Path Program = sys::Program::FindProgramByName(argv[1]); > > +#if defined(_MSC_VER) > +? if (strstr(Program.c_str(), ".exe") == NULL) > +??? Program.appendSuffix("exe"); > +#endif > + > ?? std::string ErrMsg; > ?? int Result = sys::Program::ExecuteAndWait(Program, argv + 1, 0, 0, 0, 0, > ???????????????????????????????????????????? &ErrMsg); I don't think it would be a right fix. - sys::Program::FindProgramByName() should canonicalize a pathname - sys::Program::ExecuteAndWait() should accept "x:/path/to/foo" (without .exe). Even if this patch were the right fix, I don't understand why this is MSC-specific. It might be _WIN32 not _MSC_VER. ...Takumi From geek4civic at gmail.com Mon Mar 28 01:27:06 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Mon, 28 Mar 2011 06:27:06 -0000 Subject: [llvm-commits] [llvm] r128403 - /llvm/trunk/docs/GettingStarted.html Message-ID: <20110328062706.A6B2A2A6C12C@llvm.org> Author: chapuni Date: Mon Mar 28 01:27:06 2011 New Revision: 128403 URL: http://llvm.org/viewvc/llvm-project?rev=128403&view=rev Log: docs/GettingStarted.html: Add blurb "--enable-shared" on cygming. Modified: llvm/trunk/docs/GettingStarted.html Modified: llvm/trunk/docs/GettingStarted.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/GettingStarted.html?rev=128403&r1=128402&r2=128403&view=diff ============================================================================== --- llvm/trunk/docs/GettingStarted.html (original) +++ llvm/trunk/docs/GettingStarted.html Mon Mar 28 01:27:06 2011 @@ -268,7 +268,8 @@ MinGW/Win32 x861,6, - 8, 10 + 8, 10, + 11 GCC 3.4.X, binutils 2.20 @@ -337,9 +338,8 @@ before any Windows-based versions such as Strawberry Perl and ActivePerl, as these have Windows-specifics that will cause the build to fail. -
  • In general, LLVM modules requiring dynamic linking can - not be built on Windows. However, you can build LLVM tools using - "make tools-only".
  • +
  • To use LLVM modules on Win32-based system, + you may configure LLVM with "--enable-shared".
  • From geek4civic at gmail.com Mon Mar 28 01:27:12 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Mon, 28 Mar 2011 06:27:12 -0000 Subject: [llvm-commits] [llvm] r128404 - /llvm/trunk/docs/GettingStarted.html Message-ID: <20110328062713.2C5002A6C12D@llvm.org> Author: chapuni Date: Mon Mar 28 01:27:12 2011 New Revision: 128404 URL: http://llvm.org/viewvc/llvm-project?rev=128404&view=rev Log: docs/GettingStarted.html: [PR8850] Add a note for x86_64-w64-mingw32. Modified: llvm/trunk/docs/GettingStarted.html Modified: llvm/trunk/docs/GettingStarted.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/GettingStarted.html?rev=128404&r1=128403&r2=128404&view=diff ============================================================================== --- llvm/trunk/docs/GettingStarted.html (original) +++ llvm/trunk/docs/GettingStarted.html Mon Mar 28 01:27:12 2011 @@ -312,6 +312,11 @@ Itanium (IA-64) HP aCC + + Windows x64 + x86-64 + mingw-w64's GCC-4.5.x12 +

    Notes:

    @@ -340,6 +345,8 @@ build to fail.
  • To use LLVM modules on Win32-based system, you may configure LLVM with "--enable-shared".
  • +
  • To compile SPU backend, you need to add + "LDFLAGS=-Wl,--stack,16777216" to configure.
  • From baldrick at free.fr Mon Mar 28 03:27:03 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 28 Mar 2011 10:27:03 +0200 Subject: [llvm-commits] [llvm] r128388 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineSelect.cpp test/Transforms/InstCombine/select.ll In-Reply-To: <20110327195123.44A382A6C12E@llvm.org> References: <20110327195123.44A382A6C12E@llvm.org> Message-ID: <4D904657.7000901@free.fr> Hi Nick, > Teach the transformation that moves binary operators around selects to preserve > the subclass optional data. you sometimes used tabs instead of spacing for indenting. Ciao, Duncan. From clchiou at gmail.com Mon Mar 28 05:23:13 2011 From: clchiou at gmail.com (Che-Liang Chiou) Date: Mon, 28 Mar 2011 10:23:13 -0000 Subject: [llvm-commits] [llvm] r128405 - in /llvm/trunk/lib/Target/PTX: PTXISelLowering.cpp PTXInstrInfo.cpp PTXInstrInfo.td Message-ID: <20110328102313.9DCFD2A6C12C@llvm.org> Author: clchiou Date: Mon Mar 28 05:23:13 2011 New Revision: 128405 URL: http://llvm.org/viewvc/llvm-project?rev=128405&view=rev Log: ptx: clean up branch code a bit Modified: llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Modified: llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp?rev=128405&r1=128404&r2=128405&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp Mon Mar 28 05:23:13 2011 @@ -56,8 +56,6 @@ llvm_unreachable("Unimplemented operand"); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); - case ISD::BRCOND: - return LowerGlobalAddress(Op, DAG); } } Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp?rev=128405&r1=128404&r2=128405&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp Mon Mar 28 05:23:13 2011 @@ -247,11 +247,15 @@ } unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { - unsigned count; - for (count = 0; IsAnyKindOfBranch(MBB.back()); ++count) - MBB.pop_back(); + unsigned count = 0; + while (!MBB.empty()) + if (IsAnyKindOfBranch(MBB.back())) { + MBB.pop_back(); + ++count; + } else + break; DEBUG(dbgs() << "RemoveBranch: MBB: " << MBB.getName().str() << "\n"); - DEBUG(dbgs() << "RemoveBranch: count: " << count << "\n"); + DEBUG(dbgs() << "RemoveBranch: remove " << count << " branch inst\n"); return count; } @@ -262,12 +266,12 @@ const SmallVectorImpl &Cond, DebugLoc DL) const { DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n"); - DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: " - << TBB->getName().str() << "\n"; - else dbgs() << "InsertBranch: TBB: (NULL)\n"); - DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: " - << FBB->getName().str() << "\n"; - else dbgs() << "InsertBranch: FBB: (NULL)\n"); + DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: " << TBB->getName().str() + << "\n"; + else dbgs() << "InsertBranch: TBB: (NULL)\n"); + DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: " << FBB->getName().str() + << "\n"; + else dbgs() << "InsertBranch: FBB: (NULL)\n"); DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond.size() << "\n"); assert(TBB && "TBB is NULL"); Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.td?rev=128405&r1=128404&r2=128405&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Mon Mar 28 05:23:13 2011 @@ -618,12 +618,11 @@ } let isBranch = 1, isTerminator = 1 in { - // FIXME: should be able to write a pattern for brcond, but can't use - // a two-value operand where a dag node expects two operands. :( - // NOTE: ARM & PowerPC backend also report the same problem + // FIXME: The pattern part is blank because I cannot (or do not yet know + // how to) use the first operand of PredicateOperand (a Preds register) here def BRAdp : InstPTX<(outs), (ins brtarget:$d), "bra\t$d", - [/*(brcond bb:$d, Preds:$p, i32imm:$c)*/]>; + [/*(brcond pred:$_p, bb:$d)*/]>; } let isReturn = 1, isTerminator = 1, isBarrier = 1 in { From jay.foad at gmail.com Mon Mar 28 08:03:10 2011 From: jay.foad at gmail.com (Jay Foad) Date: Mon, 28 Mar 2011 13:03:10 -0000 Subject: [llvm-commits] [llvm] r128406 - in /llvm/trunk/lib/Transforms/InstCombine: InstCombinePHI.cpp InstructionCombining.cpp Message-ID: <20110328130310.36ED82A6C12C@llvm.org> Author: foad Date: Mon Mar 28 08:03:10 2011 New Revision: 128406 URL: http://llvm.org/viewvc/llvm-project?rev=128406&view=rev Log: Make more use of PHINode::getNumIncomingValues(). Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp?rev=128406&r1=128405&r2=128406&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp Mon Mar 28 08:03:10 2011 @@ -82,7 +82,7 @@ if (LHSVal == 0) { NewLHS = PHINode::Create(LHSType, FirstInst->getOperand(0)->getName() + ".pn"); - NewLHS->reserveOperandSpace(PN.getNumOperands()/2); + NewLHS->reserveOperandSpace(PN.getNumIncomingValues()); NewLHS->addIncoming(InLHS, PN.getIncomingBlock(0)); InsertNewInstBefore(NewLHS, PN); LHSVal = NewLHS; @@ -91,7 +91,7 @@ if (RHSVal == 0) { NewRHS = PHINode::Create(RHSType, FirstInst->getOperand(1)->getName() + ".pn"); - NewRHS->reserveOperandSpace(PN.getNumOperands()/2); + NewRHS->reserveOperandSpace(PN.getNumIncomingValues()); NewRHS->addIncoming(InRHS, PN.getIncomingBlock(0)); InsertNewInstBefore(NewRHS, PN); RHSVal = NewRHS; @@ -341,7 +341,7 @@ // correct type, and PHI together all of the LHS's of the instructions. PHINode *NewPN = PHINode::Create(FirstLI->getOperand(0)->getType(), PN.getName()+".in"); - NewPN->reserveOperandSpace(PN.getNumOperands()/2); + NewPN->reserveOperandSpace(PN.getNumIncomingValues()); Value *InVal = FirstLI->getOperand(0); NewPN->addIncoming(InVal, PN.getIncomingBlock(0)); @@ -447,7 +447,7 @@ // correct type, and PHI together all of the LHS's of the instructions. PHINode *NewPN = PHINode::Create(FirstInst->getOperand(0)->getType(), PN.getName()+".in"); - NewPN->reserveOperandSpace(PN.getNumOperands()/2); + NewPN->reserveOperandSpace(PN.getNumIncomingValues()); Value *InVal = FirstInst->getOperand(0); NewPN->addIncoming(InVal, PN.getIncomingBlock(0)); Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=128406&r1=128405&r2=128406&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Mon Mar 28 08:03:10 2011 @@ -601,7 +601,7 @@ // Okay, we can do the transformation: create the new PHI node. PHINode *NewPN = PHINode::Create(I.getType(), ""); - NewPN->reserveOperandSpace(PN->getNumOperands()/2); + NewPN->reserveOperandSpace(PN->getNumIncomingValues()); InsertNewInstBefore(NewPN, *PN); NewPN->takeName(PN); From rafael.espindola at gmail.com Mon Mar 28 08:54:13 2011 From: rafael.espindola at gmail.com (=?ISO-8859-1?Q?Rafael_=C1vila_de_Esp=EDndola?=) Date: Mon, 28 Mar 2011 09:54:13 -0400 Subject: [llvm-commits] [Review request][PATCH] MC: Recognize alignment stuff on PECOFF. In-Reply-To: References: Message-ID: <4D909305.5030300@gmail.com> > I have not written comments in sources, though, I would like you all > to review my patch to confirm whether I would take the *right* way or > not, please. Looks reasonable, but without updating the parser and adding a test it is hard to be sure. Also, it might be better to add an empty implementation to MCStreamer instead of making it pure virtual. IMHO we have many pure virtuals in MCStreamer that could reasonably have an empty implementation. > Checked on msvc10, cygwin-1.7, msysgit and mingw-w64-20101129. > > ...Takumi > > Cheers, Rafael From baldrick at free.fr Mon Mar 28 10:04:33 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 28 Mar 2011 15:04:33 -0000 Subject: [llvm-commits] [dragonegg] r128408 - /dragonegg/trunk/freebsd/OS.h Message-ID: <20110328150433.635152A6C12C@llvm.org> Author: baldrick Date: Mon Mar 28 10:04:33 2011 New Revision: 128408 URL: http://llvm.org/viewvc/llvm-project?rev=128408&view=rev Log: It seems that freebsd has heard of PIC :) Patch by "dim". Modified: dragonegg/trunk/freebsd/OS.h Modified: dragonegg/trunk/freebsd/OS.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/freebsd/OS.h?rev=128408&r1=128407&r2=128408&view=diff ============================================================================== --- dragonegg/trunk/freebsd/OS.h (original) +++ dragonegg/trunk/freebsd/OS.h Mon Mar 28 10:04:33 2011 @@ -23,4 +23,11 @@ #ifndef DRAGONEGG_OS_H #define DRAGONEGG_OS_H +/* Yes, we support PIC codegen for FreeBSD targets! */ +#define LLVM_SET_TARGET_OPTIONS(argvec) \ + if (flag_pic) \ + argvec.push_back ("--relocation-model=pic"); \ + else \ + argvec.push_back ("--relocation-model=static"); + #endif /* DRAGONEGG_OS_H */ From stuart at apple.com Mon Mar 28 12:12:53 2011 From: stuart at apple.com (Stuart Hastings) Date: Mon, 28 Mar 2011 17:12:53 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r128412 - in /llvm-gcc-4.2/trunk: ./ gcc/fold-const.c Message-ID: <20110328171253.E41822A6C12C@llvm.org> Author: stuart Date: Mon Mar 28 12:12:53 2011 New Revision: 128412 URL: http://llvm.org/viewvc/llvm-project?rev=128412&view=rev Log: Merge 128411 into trunk. Modified: llvm-gcc-4.2/trunk/ (props changed) llvm-gcc-4.2/trunk/gcc/fold-const.c Propchange: llvm-gcc-4.2/trunk/ ------------------------------------------------------------------------------ svn:mergeinfo = /llvm-gcc-4.2/branches/Apple/Morbo:128411 Modified: llvm-gcc-4.2/trunk/gcc/fold-const.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/fold-const.c?rev=128412&r1=128411&r2=128412&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/fold-const.c (original) +++ llvm-gcc-4.2/trunk/gcc/fold-const.c Mon Mar 28 12:12:53 2011 @@ -4307,13 +4307,11 @@ if (TREE_INT_CST_HIGH (high) == hi && TREE_INT_CST_LOW (high) == lo) { - if (TYPE_UNSIGNED (etype)) - { - etype = lang_hooks.types.signed_type (etype); - exp = fold_convert (etype, exp); - } - return fold_build2 (GT_EXPR, type, exp, - build_int_cst (etype, 0)); + /* LLVM LOCAL begin 9186245 */ + if (!TYPE_UNSIGNED(etype)) + return fold_build2 (GT_EXPR, type, exp, + build_int_cst (etype, 0)); + /* LLVM LOCAL end 9186245 */ } } From nicholas at mxc.ca Mon Mar 28 12:48:26 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 28 Mar 2011 17:48:26 -0000 Subject: [llvm-commits] [llvm] r128413 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Message-ID: <20110328174826.3641A2A6C12C@llvm.org> Author: nicholas Date: Mon Mar 28 12:48:26 2011 New Revision: 128413 URL: http://llvm.org/viewvc/llvm-project?rev=128413&view=rev Log: Remove tabs I accidentally added. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=128413&r1=128412&r2=128413&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Mon Mar 28 12:48:26 2011 @@ -227,16 +227,16 @@ Instruction *NewSel = SelectInst::Create(SI.getCondition(), OOp, C); InsertNewInstBefore(NewSel, SI); NewSel->takeName(TVI); - BinaryOperator *TVI_BO = cast(TVI); + BinaryOperator *TVI_BO = cast(TVI); BinaryOperator *BO = BinaryOperator::Create(TVI_BO->getOpcode(), FalseVal, NewSel); - if (isa(BO)) - BO->setIsExact(TVI_BO->isExact()); - if (isa(BO)) { - BO->setHasNoUnsignedWrap(TVI_BO->hasNoUnsignedWrap()); - BO->setHasNoSignedWrap(TVI_BO->hasNoSignedWrap()); - } - return BO; + if (isa(BO)) + BO->setIsExact(TVI_BO->isExact()); + if (isa(BO)) { + BO->setHasNoUnsignedWrap(TVI_BO->hasNoUnsignedWrap()); + BO->setHasNoSignedWrap(TVI_BO->hasNoSignedWrap()); + } + return BO; } } } @@ -266,13 +266,13 @@ BinaryOperator *FVI_BO = cast(FVI); BinaryOperator *BO = BinaryOperator::Create(FVI_BO->getOpcode(), TrueVal, NewSel); - if (isa(BO)) - BO->setIsExact(FVI_BO->isExact()); - if (isa(BO)) { - BO->setHasNoUnsignedWrap(FVI_BO->hasNoUnsignedWrap()); - BO->setHasNoSignedWrap(FVI_BO->hasNoSignedWrap()); - } - return BO; + if (isa(BO)) + BO->setIsExact(FVI_BO->isExact()); + if (isa(BO)) { + BO->setHasNoUnsignedWrap(FVI_BO->hasNoUnsignedWrap()); + BO->setHasNoSignedWrap(FVI_BO->hasNoSignedWrap()); + } + return BO; } } } From nicholas at mxc.ca Mon Mar 28 12:52:51 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 28 Mar 2011 10:52:51 -0700 Subject: [llvm-commits] [llvm] r128388 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineSelect.cpp test/Transforms/InstCombine/select.ll In-Reply-To: <4D904657.7000901@free.fr> References: <20110327195123.44A382A6C12E@llvm.org> <4D904657.7000901@free.fr> Message-ID: <4D90CAF3.4030503@mxc.ca> Duncan Sands wrote: > Hi Nick, > >> Teach the transformation that moves binary operators around selects to preserve >> the subclass optional data. > > you sometimes used tabs instead of spacing for indenting. Ew. Thanks for catching that! Nick From stuart at apple.com Mon Mar 28 13:21:53 2011 From: stuart at apple.com (Stuart Hastings) Date: Mon, 28 Mar 2011 18:21:53 -0000 Subject: [llvm-commits] [test-suite] r128414 - in /test-suite/trunk/SingleSource/Regression/C++: 2011-03-28-Bitfield.cpp 2011-03-28-Bitfield.reference_output Message-ID: <20110328182153.436552A6C12C@llvm.org> Author: stuart Date: Mon Mar 28 13:21:53 2011 New Revision: 128414 URL: http://llvm.org/viewvc/llvm-project?rev=128414&view=rev Log: Test case for 128412. Added: test-suite/trunk/SingleSource/Regression/C++/2011-03-28-Bitfield.cpp test-suite/trunk/SingleSource/Regression/C++/2011-03-28-Bitfield.reference_output Added: test-suite/trunk/SingleSource/Regression/C++/2011-03-28-Bitfield.cpp URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Regression/C%2B%2B/2011-03-28-Bitfield.cpp?rev=128414&view=auto ============================================================================== --- test-suite/trunk/SingleSource/Regression/C++/2011-03-28-Bitfield.cpp (added) +++ test-suite/trunk/SingleSource/Regression/C++/2011-03-28-Bitfield.cpp Mon Mar 28 13:21:53 2011 @@ -0,0 +1,39 @@ +// The G++ FE does some constant-folding at -O1 and above; it +// recognizes the 1,2,3 test can be converted into a range expression +// ((signed char)(op.datatype-1) < 3). Alas, it generated an +// ambiguous conversion that was mis-interpreted by the GCC=>LLVM +// translation phase. +#include + +typedef struct _operation { + unsigned int datatype : 3; + +} operation; + +operation op; + +void __attribute__ ((__noinline__)) +init() { + op.datatype = 4; +} + + +int main( int argc, char *argv[] ) +{ + init(); + if( (1 == op.datatype) || + (2 == op.datatype) || + (3 == op.datatype) ) + { + printf( "1, 2 or 3: FAIL\n" ); + } + else if (4 == op.datatype) + { + printf( "4: PASS\n" ); + return 0; + } + else + printf( "Not 1,2,3 or 4: FAIL\n" ); + return -1; +} + Added: test-suite/trunk/SingleSource/Regression/C++/2011-03-28-Bitfield.reference_output URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Regression/C%2B%2B/2011-03-28-Bitfield.reference_output?rev=128414&view=auto ============================================================================== --- test-suite/trunk/SingleSource/Regression/C++/2011-03-28-Bitfield.reference_output (added) +++ test-suite/trunk/SingleSource/Regression/C++/2011-03-28-Bitfield.reference_output Mon Mar 28 13:21:53 2011 @@ -0,0 +1,2 @@ +4: PASS +exit 0 From enderby at apple.com Mon Mar 28 13:25:07 2011 From: enderby at apple.com (Kevin Enderby) Date: Mon, 28 Mar 2011 18:25:07 -0000 Subject: [llvm-commits] [llvm] r128415 - in /llvm/trunk: include/llvm-c/Disassembler.h lib/MC/MCDisassembler/Disassembler.cpp lib/MC/MCDisassembler/Disassembler.h Message-ID: <20110328182507.360A42A6C12C@llvm.org> Author: enderby Date: Mon Mar 28 13:25:07 2011 New Revision: 128415 URL: http://llvm.org/viewvc/llvm-project?rev=128415&view=rev Log: Again adding a C API to the disassembler for use by such tools as Darwin's otool(1), this time with the needed fix for case sensitive file systems :) . This is a work in progress as the interface for producing symbolic operands is not done. But a hacked prototype using information from the object file's relocation entiries and replacing immediate operands with MCExpr's has been shown to work with no changes to the instrucion printer. These APIs will be moved into a dynamic library at some point. Added: llvm/trunk/include/llvm-c/Disassembler.h llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp llvm/trunk/lib/MC/MCDisassembler/Disassembler.h Added: llvm/trunk/include/llvm-c/Disassembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Disassembler.h?rev=128415&view=auto ============================================================================== --- llvm/trunk/include/llvm-c/Disassembler.h (added) +++ llvm/trunk/include/llvm-c/Disassembler.h Mon Mar 28 13:25:07 2011 @@ -0,0 +1,106 @@ +/*===-- llvm-c/Disassembler.h - Disassembler Public C Interface ---*- C -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This header provides public interface to a disassembler library. *| +|* LLVM provides an implementation of this interface. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#ifndef LLVM_C_DISASSEMBLER_H +#define LLVM_C_DISASSEMBLER_H 1 + +#include +#include + +/** + * An opaque reference to a disassembler context. + */ +typedef void *LLVMDisasmContextRef; + +/** + * The type for the operand information call back function. This is called to + * get the symbolic information for an operand of an instruction. Typically + * this is from the relocation information, symbol table, etc. That block of + * information is saved when the disassembler context is created and passed to + * the call back in the DisInfo parameter. The instruction containing operand + * is at the PC parameter. For some instruction sets, there can be more than + * one operand with symbolic information. To determine the symbolic operand + * infomation for each operand, the bytes for the specific operand in the + * instruction are specified by the Offset parameter and its byte widith is the + * size parameter. For instructions sets with fixed widths and one symbolic + * operand per instruction, the Offset parameter will be zero and Size parameter + * will be the instruction width. The information is returned in TagBuf and is + * Triple specific with its specific information defined by the value of + * TagType for that Triple. If symbolic information is returned the function + * returns 1 else it returns 0. + */ +typedef int (*LLVMOpInfoCallback)(void *DisInfo, + uint64_t PC, + uint64_t Offset, + uint64_t Size, + int TagType, + void *TagBuf); + +/** + * The type for the symbol lookup function. This may be called by the + * disassembler for such things like adding a comment for a PC plus a constant + * offset load instruction to use a symbol name instead of a load address value. + * It is passed the block information is saved when the disassembler context is + * created and a value of a symbol to look up. If no symbol is found NULL is + * to be returned. + */ +typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo, + uint64_t SymbolValue); + +#ifdef __cplusplus +extern "C" { +#endif /* !defined(__cplusplus) */ + +/** + * Create a disassembler for the TripleName. Symbolic disassembly is supported + * by passing a block of information in the DisInfo parameter and specifing the + * TagType and call back functions as described above. These can all be passed + * as NULL. If successfull this returns a disassembler context if not it + * returns NULL. + */ +extern LLVMDisasmContextRef +LLVMCreateDisasm(const char *TripleName, + void *DisInfo, + int TagType, + LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp); + +/** + * Dispose of a disassembler context. + */ +extern void +LLVMDisasmDispose(LLVMDisasmContextRef DC); + +/** + * Disassmble a single instruction using the disassembler context specified in + * the parameter DC. The bytes of the instuction are specified in the parameter + * Bytes, and contains at least BytesSize number of bytes. The instruction is + * at the address specified by the PC parameter. If a valid instruction can be + * disassembled its string is returned indirectly in OutString which whos size + * is specified in the parameter OutStringSize. This function returns the + * number of bytes in the instruction or zero if there was no valid instruction. + */ +extern size_t +LLVMDisasmInstruction(LLVMDisasmContextRef DC, + uint8_t *Bytes, + uint64_t BytesSize, + uint64_t PC, + char *OutString, + size_t OutStringSize); + +#ifdef __cplusplus +} +#endif /* !defined(__cplusplus) */ + +#endif /* !defined(LLVM_C_DISASSEMBLER_H) */ Added: llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp?rev=128415&view=auto ============================================================================== --- llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp (added) +++ llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp Mon Mar 28 13:25:07 2011 @@ -0,0 +1,169 @@ +//===-- lib/MC/Disassembler.cpp - Disassembler Public C Interface -*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "Disassembler.h" +#include +#include "llvm-c/Disassembler.h" + +#include +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCDisassembler.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/Target/TargetRegistry.h" +#include "llvm/Target/TargetAsmInfo.h" // FIXME. +#include "llvm/Target/TargetMachine.h" // FIXME. +#include "llvm/Target/TargetSelect.h" +#include "llvm/Support/MemoryObject.h" + +namespace llvm { +class Target; +} // namespace llvm +using namespace llvm; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// +// LLVMCreateDisasm() creates a disassembler for the TripleName. Symbolic +// disassembly is supported by passing a block of information in the DisInfo +// parameter and specifing the TagType and call back functions as described in +// the header llvm-c/Disassembler.h . The pointer to the block and the +// functions can all be passed as NULL. If successfull this returns a +// disassembler context if not it returns NULL. +// +LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, + int TagType, LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp) { + // Initialize targets and assembly printers/parsers. + llvm::InitializeAllTargetInfos(); + // FIXME: We shouldn't need to initialize the Target(Machine)s. + llvm::InitializeAllTargets(); + llvm::InitializeAllAsmPrinters(); + llvm::InitializeAllAsmParsers(); + llvm::InitializeAllDisassemblers(); + + // Get the target. + std::string Error; + const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); + assert(TheTarget && "Unable to create target!"); + + // Get the assembler info needed to setup the MCContext. + const MCAsmInfo *MAI = TheTarget->createAsmInfo(TripleName); + assert(MAI && "Unable to create target asm info!"); + + // Package up features to be passed to target/subtarget + std::string FeaturesStr; + + // FIXME: We shouldn't need to do this (and link in codegen). + // When we split this out, we should do it in a way that makes + // it straightforward to switch subtargets on the fly. + TargetMachine *TM = TheTarget->createTargetMachine(TripleName, FeaturesStr); + assert(TM && "Unable to create target machine!"); + + // Get the target assembler info needed to setup the context. + const TargetAsmInfo *tai = new TargetAsmInfo(*TM); + assert(tai && "Unable to create target assembler!"); + + // Set up the MCContext for creating symbols and MCExpr's. + MCContext *Ctx = new MCContext(*MAI, tai); + assert(Ctx && "Unable to create MCContext!"); + + // Set up disassembler. + const MCDisassembler *DisAsm = TheTarget->createMCDisassembler(); + assert(DisAsm && "Unable to create disassembler!"); + + // Set up the instruction printer. + int AsmPrinterVariant = MAI->getAssemblerDialect(); + MCInstPrinter *IP = TheTarget->createMCInstPrinter(*TM, AsmPrinterVariant, + *MAI); + assert(IP && "Unable to create instruction printer!"); + + LLVMDisasmContext *DC = new LLVMDisasmContext(TripleName, DisInfo, TagType, + GetOpInfo, SymbolLookUp, + TheTarget, MAI, TM, tai, Ctx, + DisAsm, IP); + assert(DC && "Allocation failure!"); + return DC; +} + +// +// LLVMDisasmDispose() disposes of the disassembler specified by the context. +// +void LLVMDisasmDispose(LLVMDisasmContextRef DCR){ + LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; + delete DC; +} + +namespace { +// +// The memory object created by LLVMDisasmInstruction(). +// +class DisasmMemoryObject : public MemoryObject { +private: + uint8_t *Bytes; + uint64_t Size; + uint64_t BasePC; +public: + DisasmMemoryObject(uint8_t *bytes, uint64_t size, uint64_t basePC) : + Bytes(bytes), Size(size), BasePC(basePC) {} + + uint64_t getBase() const { return BasePC; } + uint64_t getExtent() const { return Size; } + + int readByte(uint64_t Addr, uint8_t *Byte) const { + if (Addr - BasePC >= Size) + return -1; + *Byte = Bytes[Addr - BasePC]; + return 0; + } +}; +} // namespace + +// +// LLVMDisasmInstruction() disassmbles a single instruction using the +// disassembler context specified in the parameter DC. The bytes of the +// instuction are specified in the parameter Bytes, and contains at least +// BytesSize number of bytes. The instruction is at the address specified by +// the PC parameter. If a valid instruction can be disassembled its string is +// returned indirectly in OutString which whos size is specified in the +// parameter OutStringSize. This function returns the number of bytes in the +// instruction or zero if there was no valid instruction. If this function +// returns zero the caller will have to pick how many bytes they want to step +// over by printing a .byte, .long etc. to continue. +// +size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes, + uint64_t BytesSize, uint64_t PC, char *OutString, + size_t OutStringSize){ + LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; + // Wrap the pointer to the Bytes, BytesSize and PC in a MemoryObject. + DisasmMemoryObject MemoryObject(Bytes, BytesSize, PC); + + uint64_t Size; + MCInst Inst; + const MCDisassembler *DisAsm = DC->getDisAsm(); + MCInstPrinter *IP = DC->getIP(); + if (!DisAsm->getInstruction(Inst, Size, MemoryObject, PC, /*REMOVE*/ nulls())) + return 0; + + std::string InsnStr; + raw_string_ostream OS(InsnStr); + raw_ostream &Out = OS; + IP->printInst(&Inst, Out); + + std::string p; + p = OS.str(); + snprintf(OutString, OutStringSize, "%s", p.c_str()); + return Size; +} + +#ifdef __cplusplus +} +#endif // __cplusplus Added: llvm/trunk/lib/MC/MCDisassembler/Disassembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/Disassembler.h?rev=128415&view=auto ============================================================================== --- llvm/trunk/lib/MC/MCDisassembler/Disassembler.h (added) +++ llvm/trunk/lib/MC/MCDisassembler/Disassembler.h Mon Mar 28 13:25:07 2011 @@ -0,0 +1,90 @@ +//===------------- Disassembler.h - LLVM Disassembler -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interface for the Disassembly library's disassembler +// context. The disassembler is responsible for producing strings for +// individual instructions according to a given architecture and disassembly +// syntax. +// +//===----------------------------------------------------------------------===// +#include "llvm-c/Disassembler.h" +#include +#include "llvm/ADT/OwningPtr.h" + +namespace llvm { +class TargetAsmInfo; +class MCContext; +class MCAsmInfo; +class MCDisassembler; +class MCInstPrinter; +class Target; +class TargetMachine; + +// +// This is the disassembler context returned by LLVMCreateDisasm(). +// +class LLVMDisasmContext { +private: + // + // The passed parameters when the disassembler context is created. + // + // The TripleName for this disassembler. + std::string TripleName; + // The pointer to the caller's block of symbolic information. + void *DisInfo; + // The Triple specific symbolic information type returned by GetOpInfo. + int TagType; + // The function to get the symbolic information for operands. + LLVMOpInfoCallback GetOpInfo; + // The function to look up a symbol name. + LLVMSymbolLookupCallback SymbolLookUp; + // + // The objects created and saved by LLVMCreateDisasm() then used by + // LLVMDisasmInstruction(). + // + // The LLVM target corresponding to the disassembler. + // FIXME: using llvm::OwningPtr causes a malloc error + // when this LLVMDisasmContext is deleted. + const Target *TheTarget; + // The assembly information for the target architecture. + llvm::OwningPtr MAI; + // The target machine instance. + llvm::OwningPtr TM; + // The disassembler for the target architecture. + // FIXME: using llvm::OwningPtr causes a malloc + // error when this LLVMDisasmContext is deleted. + const TargetAsmInfo *Tai; + // The assembly context for creating symbols and MCExprs. + llvm::OwningPtr Ctx; + // The disassembler for the target architecture. + llvm::OwningPtr DisAsm; + // The instruction printer for the target architecture. + llvm::OwningPtr IP; + +public: + LLVMDisasmContext(std::string tripleName, void *disInfo, int tagType, + LLVMOpInfoCallback getOpInfo, + LLVMSymbolLookupCallback symbolLookUp, + const Target *theTarget, const MCAsmInfo *mAI, + llvm::TargetMachine *tM, const TargetAsmInfo *tai, + llvm::MCContext *ctx, const MCDisassembler *disAsm, + MCInstPrinter *iP) : TripleName(tripleName), + DisInfo(disInfo), TagType(tagType), GetOpInfo(getOpInfo), + SymbolLookUp(symbolLookUp), TheTarget(theTarget), Tai(tai) { + TM.reset(tM); + MAI.reset(mAI); + Ctx.reset(ctx); + DisAsm.reset(disAsm); + IP.reset(iP); + } + const MCDisassembler *getDisAsm() const { return DisAsm.get(); } + MCInstPrinter *getIP() { return IP.get(); } +}; + +} // namespace llvm From aggarwa4 at illinois.edu Mon Mar 28 13:31:06 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 28 Mar 2011 18:31:06 -0000 Subject: [llvm-commits] [poolalloc] r128416 - in /poolalloc/trunk/test/dsa/callgraph: table_dispatch.ll table_dispatch1.ll Message-ID: <20110328183107.038C52A6C12C@llvm.org> Author: aggarwa4 Date: Mon Mar 28 13:31:06 2011 New Revision: 128416 URL: http://llvm.org/viewvc/llvm-project?rev=128416&view=rev Log: New examples for call graph resolution. Added: poolalloc/trunk/test/dsa/callgraph/table_dispatch.ll poolalloc/trunk/test/dsa/callgraph/table_dispatch1.ll Added: poolalloc/trunk/test/dsa/callgraph/table_dispatch.ll URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/callgraph/table_dispatch.ll?rev=128416&view=auto ============================================================================== --- poolalloc/trunk/test/dsa/callgraph/table_dispatch.ll (added) +++ poolalloc/trunk/test/dsa/callgraph/table_dispatch.ll Mon Mar 28 13:31:06 2011 @@ -0,0 +1,132 @@ +; Example from Milanova, Rountev, and Ryder(Precise Call graphs for C programs with Function Pointers) +; Because table in const, func1, and func2 get inlined into main +;RUN: dsaopt %s -dsa-bu -analyze -check-callees=main,func1,func2 + +; ModuleID = 'tt1.o' +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-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +%struct.parse_table = type { i8*, i32 ()* } + + at table = internal constant [2 x %struct.parse_table] [%struct.parse_table { i8* getelementptr inbounds ([6 x i8]* @.str, i64 0, i64 0), i32 ()* @func1 }, %struct.parse_table { i8* getelementptr inbounds ([6 x i8]* @.str1, i64 0, i64 0), i32 ()* @func2 }], align 32 ; <[2 x %struct.parse_table]*> [#uses=2] + at .str = private constant [6 x i8] c"name1\00", align 1 ; <[6 x i8]*> [#uses=1] + at .str1 = private constant [6 x i8] c"name2\00", align 1 ; <[6 x i8]*> [#uses=1] + +define internal i32 @func1() nounwind { +entry: + %retval = alloca i32 ; [#uses=2] + %0 = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i32 1, i32* %0, align 4 + %1 = load i32* %0, align 4 ; [#uses=1] + store i32 %1, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + ret i32 %retval1 +} + +define internal i32 @func2() nounwind { +entry: + %retval = alloca i32 ; [#uses=2] + %0 = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i32 2, i32* %0, align 4 + %1 = load i32* %0, align 4 ; [#uses=1] + store i32 %1, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + ret i32 %retval1 +} + +define internal i32 ()* @find_p_func(i8* %s) nounwind { +entry: + %s_addr = alloca i8* ; [#uses=2] + %retval = alloca i32 ()* ; [#uses=2] + %0 = alloca i32 ()* ; [#uses=3] + %i = alloca i32 ; [#uses=6] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i8* %s, i8** %s_addr + store i32 0, i32* %i, align 4 + br label %bb3 + +bb: ; preds = %bb3 + %1 = load i32* %i, align 4 ; [#uses=1] + %2 = sext i32 %1 to i64 ; [#uses=1] + %3 = getelementptr inbounds [2 x %struct.parse_table]* @table, i64 0, i64 %2 ; <%struct.parse_table*> [#uses=1] + %4 = getelementptr inbounds %struct.parse_table* %3, i32 0, i32 0 ; [#uses=1] + %5 = load i8** %4, align 8 ; [#uses=1] + %6 = load i8** %s_addr, align 8 ; [#uses=1] + %7 = call i32 (...)* bitcast (i32 (i8*, i8*)* @strcmp to i32 (...)*)(i8* %5, i8* %6) nounwind readonly ; [#uses=1] + %8 = icmp eq i32 %7, 0 ; [#uses=1] + br i1 %8, label %bb1, label %bb2 + +bb1: ; preds = %bb + %9 = load i32* %i, align 4 ; [#uses=1] + %10 = sext i32 %9 to i64 ; [#uses=1] + %11 = getelementptr inbounds [2 x %struct.parse_table]* @table, i64 0, i64 %10 ; <%struct.parse_table*> [#uses=1] + %12 = getelementptr inbounds %struct.parse_table* %11, i32 0, i32 1 ; [#uses=1] + %13 = load i32 ()** %12, align 8 ; [#uses=1] + store i32 ()* %13, i32 ()** %0, align 8 + br label %bb5 + +bb2: ; preds = %bb + %14 = load i32* %i, align 4 ; [#uses=1] + %15 = add nsw i32 %14, 1 ; [#uses=1] + store i32 %15, i32* %i, align 4 + br label %bb3 + +bb3: ; preds = %bb2, %entry + %16 = load i32* %i, align 4 ; [#uses=1] + %17 = icmp sle i32 %16, 1 ; [#uses=1] + br i1 %17, label %bb, label %bb4 + +bb4: ; preds = %bb3 + store i32 ()* null, i32 ()** %0, align 8 + br label %bb5 + +bb5: ; preds = %bb4, %bb1 + %18 = load i32 ()** %0, align 8 ; [#uses=1] + store i32 ()* %18, i32 ()** %retval, align 8 + br label %return + +return: ; preds = %bb5 + %retval6 = load i32 ()** %retval ; [#uses=1] + ret i32 ()* %retval6 +} + +declare i32 @strcmp(i8*, i8*) nounwind readonly + +define i32 @main(i32 %argc, i8** %argv) nounwind { +entry: + %argc_addr = alloca i32 ; [#uses=1] + %argv_addr = alloca i8** ; [#uses=2] + %retval = alloca i32 ; [#uses=1] + %parse_func = alloca i32 ()* ; [#uses=3] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i32 %argc, i32* %argc_addr + store i8** %argv, i8*** %argv_addr + %0 = load i8*** %argv_addr, align 8 ; [#uses=1] + %1 = getelementptr inbounds i8** %0, i64 1 ; [#uses=1] + %2 = load i8** %1, align 1 ; [#uses=1] + %3 = call i32 ()* (i8*)* @find_p_func(i8* %2) nounwind ; [#uses=1] + store i32 ()* %3, i32 ()** %parse_func, align 8 + %4 = load i32 ()** %parse_func, align 8 ; [#uses=1] + %5 = icmp ne i32 ()* %4, null ; [#uses=1] + br i1 %5, label %bb, label %bb1 + +bb: ; preds = %entry + %6 = load i32 ()** %parse_func, align 8 ; [#uses=1] + %7 = call i32 %6() nounwind ; [#uses=0] + br label %bb1 + +bb1: ; preds = %bb, %entry + br label %return + +return: ; preds = %bb1 + %retval2 = load i32* %retval ; [#uses=1] + ret i32 %retval2 +} Added: poolalloc/trunk/test/dsa/callgraph/table_dispatch1.ll URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/callgraph/table_dispatch1.ll?rev=128416&view=auto ============================================================================== --- poolalloc/trunk/test/dsa/callgraph/table_dispatch1.ll (added) +++ poolalloc/trunk/test/dsa/callgraph/table_dispatch1.ll Mon Mar 28 13:31:06 2011 @@ -0,0 +1,131 @@ +; Example from Milanova, Rountev, and Ryder(Precise Call graphs for C programs with Function Pointers) +; Because table is not const, func1, and func2 do not get inlined into main +; ModuleID = 'tt.o' +;RUN: dsaopt %s -dsa-bu -analyze -check-callees=main,func1,func2 +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-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +%struct.parse_table = type { i8*, i32 ()* } + + at table = internal global [2 x %struct.parse_table] [%struct.parse_table { i8* getelementptr inbounds ([6 x i8]* @.str, i64 0, i64 0), i32 ()* @func1 }, %struct.parse_table { i8* getelementptr inbounds ([6 x i8]* @.str1, i64 0, i64 0), i32 ()* @func2 }], align 32 ; <[2 x %struct.parse_table]*> [#uses=2] + at .str = private constant [6 x i8] c"name1\00", align 1 ; <[6 x i8]*> [#uses=1] + at .str1 = private constant [6 x i8] c"name2\00", align 1 ; <[6 x i8]*> [#uses=1] + +define internal i32 @func1() nounwind { +entry: + %retval = alloca i32 ; [#uses=2] + %0 = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i32 1, i32* %0, align 4 + %1 = load i32* %0, align 4 ; [#uses=1] + store i32 %1, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + ret i32 %retval1 +} + +define internal i32 @func2() nounwind { +entry: + %retval = alloca i32 ; [#uses=2] + %0 = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i32 2, i32* %0, align 4 + %1 = load i32* %0, align 4 ; [#uses=1] + store i32 %1, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + ret i32 %retval1 +} + +define internal i32 ()* @find_p_func(i8* %s) nounwind { +entry: + %s_addr = alloca i8* ; [#uses=2] + %retval = alloca i32 ()* ; [#uses=2] + %0 = alloca i32 ()* ; [#uses=3] + %i = alloca i32 ; [#uses=6] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i8* %s, i8** %s_addr + store i32 0, i32* %i, align 4 + br label %bb3 + +bb: ; preds = %bb3 + %1 = load i32* %i, align 4 ; [#uses=1] + %2 = sext i32 %1 to i64 ; [#uses=1] + %3 = getelementptr inbounds [2 x %struct.parse_table]* @table, i64 0, i64 %2 ; <%struct.parse_table*> [#uses=1] + %4 = getelementptr inbounds %struct.parse_table* %3, i32 0, i32 0 ; [#uses=1] + %5 = load i8** %4, align 8 ; [#uses=1] + %6 = load i8** %s_addr, align 8 ; [#uses=1] + %7 = call i32 (...)* bitcast (i32 (i8*, i8*)* @strcmp to i32 (...)*)(i8* %5, i8* %6) nounwind readonly ; [#uses=1] + %8 = icmp eq i32 %7, 0 ; [#uses=1] + br i1 %8, label %bb1, label %bb2 + +bb1: ; preds = %bb + %9 = load i32* %i, align 4 ; [#uses=1] + %10 = sext i32 %9 to i64 ; [#uses=1] + %11 = getelementptr inbounds [2 x %struct.parse_table]* @table, i64 0, i64 %10 ; <%struct.parse_table*> [#uses=1] + %12 = getelementptr inbounds %struct.parse_table* %11, i32 0, i32 1 ; [#uses=1] + %13 = load i32 ()** %12, align 8 ; [#uses=1] + store i32 ()* %13, i32 ()** %0, align 8 + br label %bb5 + +bb2: ; preds = %bb + %14 = load i32* %i, align 4 ; [#uses=1] + %15 = add nsw i32 %14, 1 ; [#uses=1] + store i32 %15, i32* %i, align 4 + br label %bb3 + +bb3: ; preds = %bb2, %entry + %16 = load i32* %i, align 4 ; [#uses=1] + %17 = icmp sle i32 %16, 1 ; [#uses=1] + br i1 %17, label %bb, label %bb4 + +bb4: ; preds = %bb3 + store i32 ()* null, i32 ()** %0, align 8 + br label %bb5 + +bb5: ; preds = %bb4, %bb1 + %18 = load i32 ()** %0, align 8 ; [#uses=1] + store i32 ()* %18, i32 ()** %retval, align 8 + br label %return + +return: ; preds = %bb5 + %retval6 = load i32 ()** %retval ; [#uses=1] + ret i32 ()* %retval6 +} + +declare i32 @strcmp(i8*, i8*) nounwind readonly + +define i32 @main(i32 %argc, i8** %argv) nounwind { +entry: + %argc_addr = alloca i32 ; [#uses=1] + %argv_addr = alloca i8** ; [#uses=2] + %retval = alloca i32 ; [#uses=1] + %parse_func = alloca i32 ()* ; [#uses=3] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i32 %argc, i32* %argc_addr + store i8** %argv, i8*** %argv_addr + %0 = load i8*** %argv_addr, align 8 ; [#uses=1] + %1 = getelementptr inbounds i8** %0, i64 1 ; [#uses=1] + %2 = load i8** %1, align 1 ; [#uses=1] + %3 = call i32 ()* (i8*)* @find_p_func(i8* %2) nounwind ; [#uses=1] + store i32 ()* %3, i32 ()** %parse_func, align 8 + %4 = load i32 ()** %parse_func, align 8 ; [#uses=1] + %5 = icmp ne i32 ()* %4, null ; [#uses=1] + br i1 %5, label %bb, label %bb1 + +bb: ; preds = %entry + %6 = load i32 ()** %parse_func, align 8 ; [#uses=1] + %7 = call i32 %6() nounwind ; [#uses=0] + br label %bb1 + +bb1: ; preds = %bb, %entry + br label %return + +return: ; preds = %bb1 + %retval2 = load i32* %retval ; [#uses=1] + ret i32 %retval2 +} From johnny.chen at apple.com Mon Mar 28 13:41:58 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 28 Mar 2011 18:41:58 -0000 Subject: [llvm-commits] [llvm] r128417 - in /llvm/trunk: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h test/MC/Disassembler/ARM/arm-tests.txt Message-ID: <20110328184158.BD7382A6C12C@llvm.org> Author: johnny Date: Mon Mar 28 13:41:58 2011 New Revision: 128417 URL: http://llvm.org/viewvc/llvm-project?rev=128417&view=rev Log: Fix ARM disassembly for PLD/PLDW/PLI which suffers from code rot and add some test cases. Add comments to ThumbDisassemblerCore.h for recent change made for t2PLD disassembly. Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128417&r1=128416&r2=128417&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Mon Mar 28 13:41:58 2011 @@ -2893,8 +2893,8 @@ unsigned short NumOps, unsigned &NumOpsAdded, BO B) { // Preload Data/Instruction requires either 2 or 3 operands. - // PLDi, PLDWi, PLIi: addrmode_imm12 - // PLDr[a|m], PLDWr[a|m], PLIr[a|m]: ldst_so_reg + // PLDi12, PLDWi12, PLIi12: addrmode_imm12 + // PLDrs, PLDWrs, PLIrs: ldst_so_reg MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn)))); @@ -2903,10 +2903,19 @@ || Opcode == ARM::PLIi12) { unsigned Imm12 = slice(insn, 11, 0); bool Negative = getUBit(insn) == 0; + + // A8.6.118 PLD (literal) PLDWi12 with Rn=PC is transformed to PLDi12. + if (Opcode == ARM::PLDWi12 && slice(insn, 19, 16) == 0xF) { + DEBUG(errs() << "Rn == '1111': PLDWi12 morphed to PLDi12\n"); + MI.setOpcode(ARM::PLDi12); + } + // -0 is represented specially. All other values are as normal. + int Offset = Negative ? -1 * Imm12 : Imm12; if (Imm12 == 0 && Negative) - Imm12 = INT32_MIN; - MI.addOperand(MCOperand::CreateImm(Imm12)); + Offset = INT32_MIN; + + MI.addOperand(MCOperand::CreateImm(Offset)); NumOpsAdded = 2; } else { MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, Modified: llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h?rev=128417&r1=128416&r2=128417&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h Mon Mar 28 13:41:58 2011 @@ -1799,8 +1799,12 @@ // A8.6.117 Encoding T2: add = FALSE unsigned Imm8 = getImm8(insn); Offset = -1 * Imm8; - } else // The i12 forms. See, for example, A8.6.117 Encoding T1. + } else { + // The i12 forms. See, for example, A8.6.117 Encoding T1. + // Note that currently t2PLDi12 also handles the previously named t2PLDpci + // opcode, that's why we use decodeImm12(insn) which returns +/- imm12. Offset = decodeImm12(insn); + } MI.addOperand(MCOperand::CreateImm(Offset)); } ++OpIdx; Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=128417&r1=128416&r2=128417&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Mon Mar 28 13:41:58 2011 @@ -190,3 +190,12 @@ # CHECK: umull r1, r2, r3, r4 0x93 0x14 0x82 0xe0 + +# CHECK: pld [pc, #-0] +0x00 0xf0 0x1f 0xf5 + +# CHECK: pli [pc, #-0] +0x00 0xf0 0x5f 0xf4 + +# CHECK: pli [r3, r1, lsl #2] +0x01 0xf1 0xd3 0xf6 From baldrick at free.fr Mon Mar 28 14:44:58 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 28 Mar 2011 19:44:58 -0000 Subject: [llvm-commits] [dragonegg] r128420 - in /dragonegg/trunk: ADT/ ADT/IntervalList.h ADT/Range.h Makefile Message-ID: <20110328194458.9D54E2A6C12C@llvm.org> Author: baldrick Date: Mon Mar 28 14:44:58 2011 New Revision: 128420 URL: http://llvm.org/viewvc/llvm-project?rev=128420&view=rev Log: Add some utility classes for manipulating bit ranges. Added: dragonegg/trunk/ADT/ dragonegg/trunk/ADT/IntervalList.h dragonegg/trunk/ADT/Range.h Modified: dragonegg/trunk/Makefile Added: dragonegg/trunk/ADT/IntervalList.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/ADT/IntervalList.h?rev=128420&view=auto ============================================================================== --- dragonegg/trunk/ADT/IntervalList.h (added) +++ dragonegg/trunk/ADT/IntervalList.h Mon Mar 28 14:44:58 2011 @@ -0,0 +1,215 @@ +//=--------- IntervalList.h - List of disjoint intervals ----------*- C++ -*-=// +// +// Copyright (C) 2011 Duncan Sands. +// +// This file is part of DragonEgg. +// +// DragonEgg is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later version. +// +// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with +// DragonEgg; see the file COPYING. If not, write to the Free Software +// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. +// +//===----------------------------------------------------------------------===// +// This file declares a utility class for maintaining a collection of pairwise +// disjoint intervals. +//===----------------------------------------------------------------------===// + +#ifndef DRAGONEGG_INTERVALLIST_H +#define DRAGONEGG_INTERVALLIST_H + +#include "Range.h" +#include "llvm/ADT/SmallVector.h" + +/// IntervalList - Maintains a list of disjoint intervals. Type 'T' represents +/// an interval, and should have a getRange method which returns a range of 'U' +/// values. In addition it should provide ChangeRangeTo for growing, shrinking +/// and otherwise changing the shape of the interval; and JoinWith for replacing +/// the interval with the convex hull of its union with another interval (which +/// is guaranteed to be disjoint from the original). +template +class IntervalList { + typedef typename llvm::SmallVector List; + typedef typename List::iterator iterator; + + List Intervals; + // The actual intervals. Always disjoint, sorted and non-empty. + + /// CmpFirst - Compare intervals based on where they start. + static bool CmpFirst(const T &L, const T &R) { + return L.getRange().getFirst() < R.getRange().getFirst(); + } + + /// CmpLast - Compare intervals based on where they stop. + static bool CmpLast(const T &L, const T &R) { + return L.getRange().getLast() < R.getRange().getLast(); + } + + /// isSane - Return true if the intervals are non-empty, disjoint and + /// sorted. + bool isSane() const { + for (unsigned i = 0, e = Intervals.size(); i < e; ++i) { + if (Intervals[i].getRange().empty()) + return false; + if (i && Intervals[i].getRange().getFirst() < + Intervals[i-1].getRange().getLast()) + return false; + } + return true; + } + +public: + + /// AddInterval - Add the given interval to the list. If it overlaps any + /// existing intervals then the existing intervals are pruned by removing + /// exactly the parts of them that overlap the new interval. If the added + /// interval is empty then it will be discarded. + void AddInterval(const T &S); + + /// getNumIntervals - Return the number of intervals in the list. + unsigned getNumIntervals() const { + return Intervals.size(); + } + + /// getInterval - Return the interval with the given index. + T getInterval(unsigned Idx) { + return Intervals[Idx]; + } + + /// AlignBoundaries - Ensure that all intervals begin and end on a multiple of + /// the given value. + void AlignBoundaries(unsigned Alignment); +}; + +/// AddInterval - Add the given interval to the list. If it overlaps any +/// existing intervals then the existing intervals are pruned by removing +/// exactly the parts of them that overlap the new interval. If the added +/// interval is empty then it will be discarded. +template +void IntervalList::AddInterval(const T &Interval) { + const Range NewRange = Interval.getRange(); + + // If the new interval is empty then there is no point in adding it. + if (NewRange.empty()) + return; + + // If this is the first interval then it cannot overlap any others. + if (Intervals.empty()) { + Intervals.push_back(Interval); + return; + } + + // Check for overlap with existing intervals. + iterator Lo = std::lower_bound(Intervals.begin(), Intervals.end(), Interval, + CmpFirst); + iterator Hi = std::upper_bound(Intervals.begin(), Intervals.end(), Interval, + CmpLast); + if (Lo < Hi) { + // Intervals with index in [Lo, Hi) are those completely covered by the new + // interval. Throw them away. + for (iterator I = Lo; I != Hi; ++I) + assert(NewRange.contains(I->getRange()) && "Old interval not covered!"); + Intervals.erase(Lo, Hi); + Hi = Lo; + } else if (Hi < Lo) { + // The new interval is contained in Hi with an excedent at each end. Chop + // the old interval into two pieces (the lower and upper parts) and insert + // the new interval between them. + const Range OldRange = Hi->getRange(); + assert(OldRange.contains(NewRange) && "New interval not contained in old!"); + const Range LowerRange(OldRange.getFirst(), NewRange.getFirst()); + const Range UpperRange(NewRange.getLast(), OldRange.getLast()); + assert(!LowerRange.empty() && !UpperRange.empty() && "Degenerate end!"); + T UpperPart = *Hi; + Hi->ChangeRangeTo(LowerRange); + UpperPart.ChangeRangeTo(UpperRange); + Lo = Intervals.insert(Lo, UpperPart); + Intervals.insert(Lo, Interval); + assert(isSane() && "Interval added wrong!"); + return; + } + assert(Lo == Hi); + // Check for overlap with the preceding interval. + if (Lo != Intervals.begin()) { + const iterator Prev = Lo - 1; + const Range PrevRange = Prev->getRange(); + if (NewRange.getFirst() < PrevRange.getLast()) + // Shrink the previous interval to remove the overlap. + Prev->ChangeRangeTo(Range(PrevRange.getFirst(), NewRange.getFirst())); + } + // Check for overlap with the following interval. + if (Lo != Intervals.end()) { + const iterator Next = Lo; + const Range NextRange = Next->getRange(); + if (NextRange.getFirst() < NewRange.getLast()) + // Shrink the next interval to remove the overlap. + Next->ChangeRangeTo(Range(NewRange.getLast(), NextRange.getLast())); + } + // The new interval is now disjoint from any existing intervals. Insert it. + Intervals.insert(Lo, Interval); + assert(isSane() && "Interval added wrong!"); +} + +/// AlignBoundaries - Ensure that all intervals begin and end on a multiple of +/// the given value. +template +void IntervalList::AlignBoundaries(unsigned Alignment) { + assert(Alignment > 0 && "Alignment should be positive!"); + for (iterator SI = Intervals.begin(); SI != Intervals.end(); ++SI) { + T &Interval = *SI; + Range OrigRange = Interval.getRange(); + + // Round the start of the interval down and the end of the interval up to + // the nearest multiple of the alignment. + U RoundedFirst = OrigRange.getFirst() - (OrigRange.getFirst() % Alignment); + U RoundedLast = OrigRange.getLast() + Alignment - 1; + RoundedLast -= RoundedLast % Alignment; + Range AlignedRange(RoundedFirst, RoundedLast); + + // There is nothing to do if the interval is already aligned. + if (OrigRange == AlignedRange) + continue; + + // Merge in all following intervals that start before RoundedLast. + iterator Next = SI + 1; + for (; Next != Intervals.end() && Next->getRange().getFirst() < RoundedLast; + ++Next) + Interval.JoinWith(*Next); + assert(Interval.getRange().getFirst() == OrigRange.getFirst() && + "Merging at end changed start!"); + + // If merging caused the interval to extend beyond RoundedLast then chop the + // interval in two at RoundedLast. This stops intervals getting huge due to + // repeated merging. + if (Interval.getRange().getLast() > RoundedLast) { + Range LowerR(OrigRange.getFirst(), RoundedLast); + Range UpperR(RoundedLast, Interval.getRange().getLast()); + // We must have merged in at least the next interval. Reuse it to hold + // the part we chop off the end. + T &J = *(SI + 1) = Interval; + // Chop the end off the original interval so that it stops at RoundedLast + // and at the same time extend the start of the original interval down to + // the alignment boundary. + Interval.ChangeRangeTo(AlignedRange); + // Chop the start off the new (following) interval so that it begins at + // RoundedLast. + J.ChangeRangeTo(UpperR); + // Delete any other merged intervals. + Intervals.erase(SI + 2, Next); + } else { + // The interval didn't grow beyond the original alignment boundary. Round + // it to those boundaries. + Interval.ChangeRangeTo(AlignedRange); + // Delete any merged intervals. + Intervals.erase(SI + 1, Next); + } + } +} + +#endif /* DRAGONEGG_INTERVALLIST_H */ Added: dragonegg/trunk/ADT/Range.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/ADT/Range.h?rev=128420&view=auto ============================================================================== --- dragonegg/trunk/ADT/Range.h (added) +++ dragonegg/trunk/ADT/Range.h Mon Mar 28 14:44:58 2011 @@ -0,0 +1,106 @@ +//=------------------ Range.h - Interval of values ----------------*- C++ -*-=// +// +// Copyright (C) 2011 Duncan Sands. +// +// This file is part of DragonEgg. +// +// DragonEgg is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later version. +// +// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with +// DragonEgg; see the file COPYING. If not, write to the Free Software +// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. +// +//===----------------------------------------------------------------------===// +// This file declares a utility class for representing an interval of values. +//===----------------------------------------------------------------------===// + +#ifndef DRAGONEGG_RANGE_H +#define DRAGONEGG_RANGE_H + +/// Range - Represents the interval [First, Last). +template +class Range { + T First, Last; +public: + Range() : First(0), Last(0) {} + Range(T first, T last) : First(first), Last(last) {} + + bool operator==(const Range &other) const { + return (empty() && other.empty()) || + (First == other.First && Last == other.Last); + } + + /// empty - Return whether the range is empty. + bool empty() const { + return Last <= First; + } + + /// getFirst - Return the value defining the start of the range. + T getFirst() const { + assert(!empty() && "An empty range has no starting value!"); + return First; + } + + /// getLast - Return the value defining the end of the range. + T getLast() const { + assert(!empty() && "An empty range has no ending value!"); + return Last; + } + + /// getWidth - Return the number of values in the range. + T getWidth() const { + return empty() ? 0 : Last - First; + } + + /// contains - Return true if the given range is contained in this one. + bool contains(Range r) const { + if (r.empty()) + return true; + if (empty()) + return false; + return First <= r.First && Last >= r.Last; + } + + /// intersects - Return true if the given range intersects this one. + bool intersects(Range r) const { + if (empty() || r.empty()) + return false; + return r.First < Last && r.Last > First; + } + + /// Displace - Return the range obtained by adding the given offset. + Range Displace(T Offset) const { + if (empty()) + return Range(); + assert(((Offset >= 0 && First + Offset >= First && Last + Offset >= Last) || + (Offset < 0 && First + Offset < First && Last + Offset < Last)) && + "Displacement wrapped range!"); + return Range(First + Offset, Last + Offset); + } + + /// Join - Return the smallest range containing this range and the given one. + Range Join(Range other) const { + if (empty()) + return other; + if (other.empty()) + return *this; + return Range(First < other.First ? First : other.First, + Last > other.Last ? Last : other.Last); + } + + /// Meet - Return the intersection of this range and the given one. + Range Meet(Range other) const { + if (empty() || other.empty()) + return Range(); + return Range(First > other.First ? First : other.First, + Last < other.Last ? Last : other.Last); + } +}; + +#endif /* DRAGONEGG_RANGE_H */ Modified: dragonegg/trunk/Makefile URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Makefile?rev=128420&r1=128419&r2=128420&view=diff ============================================================================== --- dragonegg/trunk/Makefile (original) +++ dragonegg/trunk/Makefile Mon Mar 28 14:44:58 2011 @@ -52,7 +52,7 @@ -MD -MP \ -DIN_GCC -DREVISION=\"$(REVISION)\" \ -DGCC_MAJOR=$(GCC_MAJOR) -DGCC_MINOR=$(GCC_MINOR) \ - -I$(SRC_DIR) -I$(GCC_PLUGIN_DIR)/include + -I$(SRC_DIR) -I$(SRC_DIR)/ADT -I$(GCC_PLUGIN_DIR)/include LD_OPTIONS+=$(shell $(LLVM_CONFIG) --ldflags) $(LDFLAGS) From dpatel at apple.com Mon Mar 28 15:00:34 2011 From: dpatel at apple.com (Devang Patel) Date: Mon, 28 Mar 2011 20:00:34 -0000 Subject: [llvm-commits] [debuginfo-tests] r128421 - in /debuginfo-tests/trunk: dbg-arg.ll dbg-declare.ll dbg-declare2.ll local-var.ll local-var2.ll Message-ID: <20110328200035.0A9582A6C12C@llvm.org> Author: dpatel Date: Mon Mar 28 15:00:34 2011 New Revision: 128421 URL: http://llvm.org/viewvc/llvm-project?rev=128421&view=rev Log: These tests are x86_64 specific. Modified: debuginfo-tests/trunk/dbg-arg.ll debuginfo-tests/trunk/dbg-declare.ll debuginfo-tests/trunk/dbg-declare2.ll debuginfo-tests/trunk/local-var.ll debuginfo-tests/trunk/local-var2.ll Modified: debuginfo-tests/trunk/dbg-arg.ll URL: http://llvm.org/viewvc/llvm-project/debuginfo-tests/trunk/dbg-arg.ll?rev=128421&r1=128420&r2=128421&view=diff ============================================================================== --- debuginfo-tests/trunk/dbg-arg.ll (original) +++ debuginfo-tests/trunk/dbg-arg.ll Mon Mar 28 15:00:34 2011 @@ -1,6 +1,6 @@ ; This test case checks debug info during register moves for an argument. -; RUN: %clang -mllvm -fast-isel=false %s -c -o %t.o -; RUN: %clang %t.o -o %t.out +; RUN: %clang -arch x86_64 -mllvm -fast-isel=false %s -c -o %t.o +; RUN: %clang -arch x86_64 %t.o -o %t.out ; RUN: %test_debuginfo %s %t.out ; Radar 8412415 Modified: debuginfo-tests/trunk/dbg-declare.ll URL: http://llvm.org/viewvc/llvm-project/debuginfo-tests/trunk/dbg-declare.ll?rev=128421&r1=128420&r2=128421&view=diff ============================================================================== --- debuginfo-tests/trunk/dbg-declare.ll (original) +++ debuginfo-tests/trunk/dbg-declare.ll Mon Mar 28 15:00:34 2011 @@ -1,6 +1,6 @@ ; This test case checks handling of llvm.dbg.declare intrinsic during fast-isel. -; RUN: %clang -O0 -g %s -c -o %t.o -; RUN: %clang %t.o -o %t.out +; RUN: %clang -arch x86_64 -O0 -g %s -c -o %t.o +; RUN: %clang -arch x86_64 %t.o -o %t.out ; RUN: %test_debuginfo %s %t.out target triple = "x86_64-apple-darwin" Modified: debuginfo-tests/trunk/dbg-declare2.ll URL: http://llvm.org/viewvc/llvm-project/debuginfo-tests/trunk/dbg-declare2.ll?rev=128421&r1=128420&r2=128421&view=diff ============================================================================== --- debuginfo-tests/trunk/dbg-declare2.ll (original) +++ debuginfo-tests/trunk/dbg-declare2.ll Mon Mar 28 15:00:34 2011 @@ -1,6 +1,6 @@ ; This test case checks handling of llvm.dbg.declare intrinsic during isel. -; RUN: %clang -mllvm -fast-isel=false -mllvm -regalloc=default -g %s -c -o %t.o -; RUN: %clang %t.o -o %t.out +; RUN: %clang -arch x86_64 -mllvm -fast-isel=false -mllvm -regalloc=default -g %s -c -o %t.o +; RUN: %clang -arch x86_64 %t.o -o %t.out ; RUN: %test_debuginfo %s %t.out target triple = "x86_64-apple-darwin" Modified: debuginfo-tests/trunk/local-var.ll URL: http://llvm.org/viewvc/llvm-project/debuginfo-tests/trunk/local-var.ll?rev=128421&r1=128420&r2=128421&view=diff ============================================================================== --- debuginfo-tests/trunk/local-var.ll (original) +++ debuginfo-tests/trunk/local-var.ll Mon Mar 28 15:00:34 2011 @@ -1,6 +1,6 @@ ; This test case checks handling of llvm.dbg.declare intrinsic during fast-isel. -; RUN: %clang -O0 -g %s -c -o %t.o -; RUN: %clang %t.o -o %t.out +; RUN: %clang -arch x86_64 -O0 -g %s -c -o %t.o +; RUN: %clang -arch x86_64 %t.o -o %t.out ; RUN: %test_debuginfo %s %t.out target triple = "x86_64-apple-darwin10.0.0" Modified: debuginfo-tests/trunk/local-var2.ll URL: http://llvm.org/viewvc/llvm-project/debuginfo-tests/trunk/local-var2.ll?rev=128421&r1=128420&r2=128421&view=diff ============================================================================== --- debuginfo-tests/trunk/local-var2.ll (original) +++ debuginfo-tests/trunk/local-var2.ll Mon Mar 28 15:00:34 2011 @@ -1,6 +1,6 @@ ; This test case checks handling of llvm.dbg.declare intrinsic during isel. -; RUN: %clang -O0 -mllvm -fast-isel=false -g %s -c -o %t.o -; RUN: %clang %t.o -o %t.out +; RUN: %clang -arch x86_64 -O0 -mllvm -fast-isel=false -g %s -c -o %t.o +; RUN: %clang -arch x86_64 %t.o -o %t.out ; RUN: %test_debuginfo %s %t.out target triple = "x86_64-apple-darwin10.0.0" From dpatel at apple.com Mon Mar 28 15:25:47 2011 From: dpatel at apple.com (Devang Patel) Date: Mon, 28 Mar 2011 20:25:47 -0000 Subject: [llvm-commits] [test-suite] r128423 - in /test-suite/trunk: CollectDebugInfoUsingLLDB.py CompareDebugInfo.py Makefile.programs TEST.dbg.Makefile Message-ID: <20110328202547.B10462A6C12C@llvm.org> Author: dpatel Date: Mon Mar 28 15:25:47 2011 New Revision: 128423 URL: http://llvm.org/viewvc/llvm-project?rev=128423&view=rev Log: Tidy up TEST=dbg reports. Added: test-suite/trunk/CollectDebugInfoUsingLLDB.py (with props) test-suite/trunk/CompareDebugInfo.py (with props) Modified: test-suite/trunk/Makefile.programs test-suite/trunk/TEST.dbg.Makefile Added: test-suite/trunk/CollectDebugInfoUsingLLDB.py URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/CollectDebugInfoUsingLLDB.py?rev=128423&view=auto ============================================================================== --- test-suite/trunk/CollectDebugInfoUsingLLDB.py (added) +++ test-suite/trunk/CollectDebugInfoUsingLLDB.py Mon Mar 28 15:25:47 2011 @@ -0,0 +1,237 @@ +#!/usr/bin/python + +#---------------------------------------------------------------------- +# +# Be sure to add the python path that points to the LLDB shared library. +# On MacOSX csh, tcsh: +# setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python +# On MacOSX sh, bash: +# export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python +# +# This script collect debugging information using LLDB. This script is +# used by TEST=dbg in llvm testsuite to measure quality of debug info in +# optimized builds. +# +# Usage: +# export PYTHONPATH=... +# ./CollectDebugInfUsingLLDB.py program bp_file out_file +# program - Executable program with debug info. +# bp_file - Simple text file listing breakpoints. +# +# out_file - Output file where the debug info will be emitted. +#---------------------------------------------------------------------- + +import lldb +import os +import sys +import time + +# AlreadyPrintedValues - A place to keep track of recursive values. +AlreadyPrintedValues = {} + +# ISAlreadyPrinted - Return true if value is already printed. +def IsAlreadyPrinted(value_name): + if AlreadyPrintedValues.get(value_name) is None: + AlreadyPrintedValues[value_name] = 1 + return False + return True + + +# print_var_value - Print a variable's value. +def print_var_value (v, file, frame): + if v.IsValid() == False: + return + if IsAlreadyPrinted(v.GetName()): + return + total_children = v.GetNumChildren() + if total_children > 0: + c = 0 + while (c < total_children) : + child = v.GetChildAtIndex(c) + if child is None: + file.write("None") + else: + if (child.GetName()) is None: + file.write("None") + else: + file.write(child.GetName()) + file.write('=') + print_var_value(child, file, frame) + file.write(',') + c = c + 1 + else: + if v.GetValue(frame) is None: + file.write("None") + else: + file.write(v.GetValue(frame)) + +def disable_bp(thread): + # disable this thread. + count = thread.GetStopReasonDataCount() + bid = 0 + tid = 0 + for i in range(count): + id = thread.GetStopReasonDataAtIndex(i) + bp = target.FindBreakpointByID(id) + if bp.IsValid(): + if bp.IsEnabled() == True: + bid = bp.GetID() + tid = bp.GetThreadID() + bp.SetEnabled(False) + # print " disabled [", str(bp.GetThreadID()), ":", str(bp.GetID()), "]" + else: + bp_loc = bp.FindLocationByID(thread.GetStopReasonDataAtIndex(i+1)) + if bp_loc.IsValid(): + bid = bp_loc.GetBreakPoint().GetID() + tid = bp_loc.ThreadGetID() + bp_loc.SetEnabled(False); + # print " disabled [", str(bp.GetThreadID()), ":", str(bp.GetID()), "]" + +# print_vars - Print variable values in output file. +def print_vars (tag, vars, fname, line, file, frame, target, thread): + + bid = 0 + tid = 0 + count = thread.GetStopReasonDataCount() + # print "count = ",count + for i in range(count): + # print "i =", i + id = thread.GetStopReasonDataAtIndex(i) + bp = target.FindBreakpointByID(id) + if bp.IsValid(): + bid = bp.GetID() + tid = bp.GetThreadID() + # print "bp is valid", bid, tid + for j in range(vars.GetSize()): + v = vars.GetValueAtIndex(j) + if v.GetName() is not None: + file.write(tag) + file.write(fname) + file.write(':') + file.write(str(line)) + file.write(' ') + file.write(str(tid)) + file.write(':') + file.write(str(bid)) + file.write(' ') + file.write(v.GetName()) + file.write(' ') + AlreadyPrintedValues.clear() + print_var_value (v, file, frame) + file.write('\n') + +# set_breakpoints_old - set breakpoints as listed in input file. +def set_breakpoints_old (target, breakpoint_filename, file): + f = open(breakpoint_filename, "r") + lines = f.readlines() + for l in range(len(lines)): + c = lines[l].split() + # print "setting break point - ", c + bp = target.BreakpointCreateByLocation (str(c[0]), int(c[1])) + file.write("#Breakpoint ") + file.write(str(c[0])) + file.write(':') + file.write(str(c[1])) + file.write(' ') + file.write(str(bp.GetThreadID())) + file.write(':') + file.write(str(bp.GetID())) + file.write('\n') + f.close() + +# stopeed_at_breakpoint - Return True if process is stopeed at a +# set_breakpoints - set breakpoints as listed in input file. +def set_breakpoints (target, breakpoint_filename, file): + f = open(breakpoint_filename, "r") + lines = f.readlines() + for l in range(len(lines)): + l2 = len(lines[l]) + l3 = l2 - 1 + # print "setting break point - ", lines[l][0:l3] + bp = target.BreakpointCreateByName (str(lines[l][0:l3])) + # print "setting break point - ", lines[l][0:l3], + # print " [", str(bp.GetThreadID()), ":", str(bp.GetID()), "]" + file.write("#Breakpoint ") + file.write(str(1)) + file.write(':') + file.write(str(2)) + file.write(' ') + file.write(str(bp.GetThreadID())) + file.write(':') + file.write(str(bp.GetID())) + file.write(' ') + file.write(str(lines[l][0:l3])) + file.write('\n') + f.close() + +# stopeed_at_breakpoint - Return True if process is stopeed at a +# breakpoint. +def stopped_at_breakpoint (process): + # print "stopped" + if process.IsValid(): + # print "stopped process" + state = process.GetState() + # print "stopped process", state + if state == lldb.eStateStopped: + # print "stopped process state is stopped" + thread = process.GetThreadAtIndex(0) + if thread.IsValid(): + # print "thread is valid" + if thread.GetStopReason() == lldb.eStopReasonBreakpoint: + # print "thread stopped at breakpoint" + return True + return False + +# Create a new debugger instance +debugger = lldb.SBDebugger.Create() + +# When we step or continue, don't return from the function until the process +# stops. We do this by setting the async mode to false. +debugger.SetAsync (False) + +# Create a target from a file and arch +# print "Creating a target for '%s'" % sys.argv[1] + +target = debugger.CreateTargetWithFileAndArch (sys.argv[1], lldb.LLDB_ARCH_DEFAULT) + +if target.IsValid(): + # print "target is valid" + file=open(str(sys.argv[3]), 'w') + set_breakpoints (target, sys.argv[2], file) + + # Launch the process. Since we specified synchronous mode, we won't return + # from this function until we hit the breakpoint at main + sberror = lldb.SBError() + process = target.Launch (None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, sberror) + # Make sure the launch went ok + while stopped_at_breakpoint(process): + # print "stopped at a bp" + thread = process.GetThreadAtIndex (0) + # print "num of frames ", thread.GetNumFrames() + frame = thread.GetFrameAtIndex (0) + if not frame.IsValid(): + for fi in range(thread.GetNumFrames()): + # print "checking frame no : ", fi + frame = thread.GetFrameAtIndex(fi) + if frame.IsValid(): + fi = thread.GetNumFrames() + if frame.IsValid(): + # #Print some simple frame info + ##print frame + # print "frame is valid" + function = frame.GetFunction() + if function.IsValid(): + fname = function.GetMangledName() + if fname is None: + fname = function.GetName() + # print "function : ",fname + line = frame.GetLineEntry().GetLine() + vars = frame.GetVariables(1,0,0,0) + print_vars ("#Argument ", vars, fname, line, file, frame, target, thread) + # vars = frame.GetVariables(0,1,0,0) + # print_vars ("#Variables ", vars, fname, line, file, frame, target, thread) + disable_bp(thread) + process.Continue() + file.close() + +lldb.SBDebugger.Terminate() Propchange: test-suite/trunk/CollectDebugInfoUsingLLDB.py ------------------------------------------------------------------------------ svn:executable = * Added: test-suite/trunk/CompareDebugInfo.py URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/CompareDebugInfo.py?rev=128423&view=auto ============================================================================== --- test-suite/trunk/CompareDebugInfo.py (added) +++ test-suite/trunk/CompareDebugInfo.py Mon Mar 28 15:25:47 2011 @@ -0,0 +1,193 @@ +#!/usr/bin/python + +import os +import sys + +DBG_OUTPUT_FILE="Output/" + sys.argv[1] + ".dbg.out" +OPT_DBG_OUTPUT_FILE="Output/" + sys.argv[1] + ".dbg.opt.out" +LOG_FILE="Output/" + sys.argv[1] + ".log" +NATIVE_DBG_OUTPUT_FILE="Output/" + sys.argv[1] + ".native.dbg.out" +NATIVE_OPT_DBG_OUTPUT_FILE="Output/" + sys.argv[1] + ".native.dbg.opt.out" +NATIVE_LOG_FILE="Output/" + sys.argv[1] + ".native.log" +REPORT_FILE="Output/" + sys.argv[1] + ".dbg.report.txt" + +class BreakPoint: + def __init__(self, bp_name): + self.name = bp_name + self.values = {} + self.missing_args = [] + self.matching_args = [] + self.notmatching_args = [] + self.missing_bp = False + + def setMissing(self): + self.missing_bp = True + + def getArgCount(self): + return len(self.values) + + def getMissingArgCount(self): + if self.missing_bp == True: + return len(self.values) + return len(self.missing_args) + + def getMatchingArgCount(self): + if self.missing_bp == True: + return 0 + return len(self.matching_args) + + def getNotMatchingArgCount(self): + if self.missing_bp == True: + return 0 + return len(self.notmatching_args) + + def recordArgument(self, arg_name, value): + self.values[arg_name] = value + + def __repr__(self): + print self.name + items = self.values.items() + for i in range(len(items)): + print items[i][0]," = ",items[i][1] + return '' + + def compare_args(self, other, file): + myitems = self.values.items() + otheritems = other.values.items() + match = False + for i in range(len(myitems)): + if i >= len(otheritems): + match = True + self.missing_args.append(myitems[i][0]) + elif cmp(myitems[i][1], otheritems[i][1]): + match = True + self.notmatching_args.append(myitems[i][0]) + else: + self.matching_args.append(myitems[i][0]) + + self.print_list(self.matching_args, " Matching arguments ", file) + self.print_list(self.notmatching_args, " Not Matching arguments ", file) + self.print_list(self.missing_args, " Missing arguments ", file) + return match + + def print_list(self, items, txt, pfile): + if len(items) == 0: + return + pfile.write(self.name) + pfile.write(txt) + for e in items: + pfile.write(e) + pfile.write(' ') + pfile.write('\n') + +def read_input(filename, dict): + f = open(filename, "r") + lines = f.readlines() + for l in range(len(lines)): + c = lines[l].split() + if c[0] == "#Breakpoint": + bp = dict.get(c[2]) + if bp is None: + bp = BreakPoint(c[1]) + dict[c[2]] = bp + if c[0] == "#Argument": + bp = dict.get(c[2]) + if bp is None: + bp = BreakPoint(c[1]) + dict[c[2]] = bp + bp.recordArgument(c[3], c[4]) + return + +f1_breakpoints = {} +read_input(DBG_OUTPUT_FILE, f1_breakpoints) +f1_items = f1_breakpoints.items() + +f2_breakpoints = {} +read_input(OPT_DBG_OUTPUT_FILE, f2_breakpoints) +f2_items = f2_breakpoints.items() + +f = open(LOG_FILE, "w") +f.write("Log output\n") +for f2bp in range(len(f2_items)): + id = f2_items[f2bp][0] + bp = f2_items[f2bp][1] + bp1 = f1_breakpoints.get(id) + if bp1 is None: + bp.setMissing() + else: + bp1.compare_args(bp,f) +f.close() + +nf1_breakpoints = {} +read_input(NATIVE_DBG_OUTPUT_FILE, nf1_breakpoints) +nf1_items = nf1_breakpoints.items() + +nf2_breakpoints = {} +read_input(NATIVE_OPT_DBG_OUTPUT_FILE, nf2_breakpoints) +nf2_items = nf2_breakpoints.items() + +nfl = open(NATIVE_LOG_FILE, "w") +for nf2bp in range(len(nf2_items)): + id = nf2_items[nf2bp][0] + bp = nf2_items[nf2bp][1] + bp1 = nf1_breakpoints.get(id) + if bp1 is None: + bp.setMissing() + else: + bp1.compare_args(bp,nfl) +nfl.close() + +f1_arg_count = 0 +f1_matching_arg_count = 0 +f1_notmatching_arg_count = 0 +f1_missing_arg_count = 0 +for idx in range(len(f1_items)): + bp = f1_items[idx][1] + f1_arg_count = f1_arg_count + bp.getArgCount() + f1_matching_arg_count = f1_matching_arg_count + bp.getMatchingArgCount() + f1_notmatching_arg_count = f1_notmatching_arg_count + bp.getNotMatchingArgCount() + f1_missing_arg_count = f1_missing_arg_count + bp.getMissingArgCount() + +nf1_arg_count = 0 +nf1_matching_arg_count = 0 +nf1_notmatching_arg_count = 0 +nf1_missing_arg_count = 0 +for idx in range(len(nf1_items)): + bp = nf1_items[idx][1] + nf1_arg_count = nf1_arg_count + bp.getArgCount() + nf1_matching_arg_count = nf1_matching_arg_count + bp.getMatchingArgCount() + nf1_notmatching_arg_count = nf1_notmatching_arg_count + bp.getNotMatchingArgCount() + nf1_missing_arg_count = nf1_missing_arg_count + bp.getMissingArgCount() + +rf = open(REPORT_FILE, "w") +rf.write("---------------------------------------------------------------\n"); +rf.write(">>> ========= '") +rf.write(sys.argv[1]) +rf.write("'") +rf.write(" Program\n") +rf.write("---------------------------------------------------------------\n\n"); +rf.write("GCC Total Arguments: ") +rf.write(str(nf1_arg_count)) +rf.write("\n") +rf.write("GCC Matching Arguments: ") +rf.write(str(nf1_matching_arg_count)) +rf.write("\n") +rf.write("GCC Not Matching Arguments: ") +rf.write(str(nf1_notmatching_arg_count)) +rf.write("\n") +rf.write("GCC Missing Arguments: ") +rf.write(str(nf1_missing_arg_count)) +rf.write("\n") +rf.write("LLVM Total Arguments: ") +rf.write(str(f1_arg_count)) +rf.write("\n") +rf.write("LLVM Matching Arguments: ") +rf.write(str(f1_matching_arg_count)) +rf.write("\n") +rf.write("LLVM Not Matching Arguments: ") +rf.write(str(f1_notmatching_arg_count)) +rf.write("\n") +rf.write("LLVM Missing Arguments: ") +rf.write(str(f1_missing_arg_count)) +rf.write("\n") +rf.close() Propchange: test-suite/trunk/CompareDebugInfo.py ------------------------------------------------------------------------------ svn:executable = * Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=128423&r1=128422&r2=128423&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Mon Mar 28 15:25:47 2011 @@ -995,30 +995,6 @@ report.dbgopt: report.dbgopt.header report.$(TEST).txtonly -report.dbg.html: $(REPORT_DEPENDENCIES) $(TestMakefile) - $(MAKE) $(FORCE_SERIAL_ARG) TEST=$(TEST) - @echo "

    Quality of debug info in optimized builds at -O3

    " > $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - @echo "" >> $@ - find . -name \*.$(TEST).report.html -exec cat {} \; >> $@ - @echo "
    |GCC|LLVM
    Name|Total
    Arguments
    Valid
    Arguments
    Missing
    Arguments
    Invalid
    Arguments
    |Total
    Arguments
    Valid
    Arguments
    Missing
    Arguments
    Invalid
    Arguments
    " >> $@ - endif clean:: Modified: test-suite/trunk/TEST.dbg.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.dbg.Makefile?rev=128423&r1=128422&r2=128423&view=diff ============================================================================== --- test-suite/trunk/TEST.dbg.Makefile (original) +++ test-suite/trunk/TEST.dbg.Makefile Mon Mar 28 15:25:47 2011 @@ -15,6 +15,7 @@ CURDIR := $(shell cd .; pwd) PROGDIR := $(PROJ_SRC_ROOT) RELDIR := $(subst $(PROGDIR),,$(CURDIR)) +COLLECTOR := $(PROJ_SRC_ROOT)/CollectDebugInfoUsingLLDB.py REPORTS_TO_GEN := dbg REPORTS_SUFFIX := $(addsuffix .report.txt, $(REPORTS_TO_GEN)) @@ -56,11 +57,20 @@ if test "$*" == "exptree"; then \ is_skip=1; \ fi; \ + if test "$*" == "ray"; then \ + is_skip=1; \ + fi; \ + if test "$*" == "oscar"; then \ + is_skip=1; \ + fi; \ + if test "$*" == "spirit"; then \ + is_skip=1; \ + fi; \ if test $$is_skip == 0; then \ - $(LLVM_SRC_ROOT)/utils/CollectDebugInfoUsingLLDB.py Output/$*.dbg Output/$*.bp Output/$*.dbg.out; \ - $(LLVM_SRC_ROOT)/utils/CollectDebugInfoUsingLLDB.py Output/$*.dbg.opt Output/$*.bp Output/$*.dbg.opt.out; \ - $(LLVM_SRC_ROOT)/utils/CollectDebugInfoUsingLLDB.py Output/$*.native.dbg Output/$*.bp Output/$*.native.dbg.out; \ - $(LLVM_SRC_ROOT)/utils/CollectDebugInfoUsingLLDB.py Output/$*.native.dbg.opt Output/$*.bp Output/$*.native.dbg.opt.out; \ - $(LLVM_SRC_ROOT)/utils/CompareDebugInfo.py $*; \ + $(COLLECTOR) Output/$*.dbg Output/$*.bp Output/$*.dbg.out; \ + $(COLLECTOR) Output/$*.dbg.opt Output/$*.bp Output/$*.dbg.opt.out; \ + $(COLLECTOR) Output/$*.native.dbg Output/$*.bp Output/$*.native.dbg.out; \ + $(COLLECTOR) Output/$*.native.dbg.opt Output/$*.bp Output/$*.native.dbg.opt.out; \ + $(PROJ_SRC_ROOT)/CompareDebugInfo.py $*; \ fi From dpatel at apple.com Mon Mar 28 15:26:54 2011 From: dpatel at apple.com (Devang Patel) Date: Mon, 28 Mar 2011 20:26:54 -0000 Subject: [llvm-commits] [test-suite] r128424 - /test-suite/trunk/TEST.dbg.report Message-ID: <20110328202654.32E512A6C12C@llvm.org> Author: dpatel Date: Mon Mar 28 15:26:54 2011 New Revision: 128424 URL: http://llvm.org/viewvc/llvm-project?rev=128424&view=rev Log: Add report format for TEST=dbg Added: test-suite/trunk/TEST.dbg.report Added: test-suite/trunk/TEST.dbg.report URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.dbg.report?rev=128424&view=auto ============================================================================== --- test-suite/trunk/TEST.dbg.report (added) +++ test-suite/trunk/TEST.dbg.report Mon Mar 28 15:26:54 2011 @@ -0,0 +1,25 @@ +##=== TEST.dbg.report - Report description for dbg -------------*- perl -*-===## +# +# This file defines a report to be generated for TEST=dbg tests. +# +##===----------------------------------------------------------------------===## + + +# 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 +# separators, and closures may be put in for custom processing. +( +# Name + ["Program" , '\'([^\']+)\' Program'], + [], +# Times + ["GCC Total" , 'GCC Total Arguments: *([0-9]+)'], + ["GCC Valid" , 'GCC Matching Arguments: *([0-9]+)'], + ["GCC Invalid" , 'GCC Not Matching Arguments: *([0-9]+)'], + ["GCC Missing" , 'GCC Missing Arguments: *([0-9]+)'], + [], + ["LLVM Total" , 'LLVM Total Arguments: *([0-9]+)'], + ["LLVM Valid" , 'LLVM Matching Arguments: *([0-9]+)'], + ["LLVM Invalid" , 'LLVM Not Matching Arguments: *([0-9]+)'], + ["LLVM Missing" , 'LLVM Missing Arguments: *([0-9]+)'], +); From dpatel at apple.com Mon Mar 28 15:28:30 2011 From: dpatel at apple.com (Devang Patel) Date: Mon, 28 Mar 2011 20:28:30 -0000 Subject: [llvm-commits] [llvm] r128425 - in /llvm/trunk/utils: CollectDebugInfoUsingLLDB.py CompareDebugInfo.py Message-ID: <20110328202830.9CE482A6C12C@llvm.org> Author: dpatel Date: Mon Mar 28 15:28:30 2011 New Revision: 128425 URL: http://llvm.org/viewvc/llvm-project?rev=128425&view=rev Log: Remove scripts used by TEST=dbg from here. They now live inside llvm test suite. Removed: llvm/trunk/utils/CollectDebugInfoUsingLLDB.py llvm/trunk/utils/CompareDebugInfo.py Removed: llvm/trunk/utils/CollectDebugInfoUsingLLDB.py URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/CollectDebugInfoUsingLLDB.py?rev=128424&view=auto ============================================================================== --- llvm/trunk/utils/CollectDebugInfoUsingLLDB.py (original) +++ llvm/trunk/utils/CollectDebugInfoUsingLLDB.py (removed) @@ -1,182 +0,0 @@ -#!/usr/bin/python - -#---------------------------------------------------------------------- -# -# Be sure to add the python path that points to the LLDB shared library. -# On MacOSX csh, tcsh: -# setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python -# On MacOSX sh, bash: -# export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python -# -# This script collect debugging information using LLDB. This script is -# used by TEST=dbg in llvm testsuite to measure quality of debug info in -# optimized builds. -# -# Usage: -# export PYTHONPATH=... -# ./CollectDebugInfUsingLLDB.py program bp_file out_file -# program - Executable program with debug info. -# bp_file - Simple text file listing breakpoints. -# -# out_file - Output file where the debug info will be emitted. -#---------------------------------------------------------------------- - -import lldb -import os -import sys -import time - -# AlreadyPrintedValues - A place to keep track of recursive values. -AlreadyPrintedValues = {} - -# ISAlreadyPrinted - Return true if value is already printed. -def IsAlreadyPrinted(value_name): - if AlreadyPrintedValues.get(value_name) is None: - AlreadyPrintedValues[value_name] = 1 - return False - return True - - -# print_var_value - Print a variable's value. -def print_var_value (v, file, frame): - if v.IsValid() == False: - return - if IsAlreadyPrinted(v.GetName()): - return - total_children = v.GetNumChildren() - if total_children > 0: - c = 0 - while (c < total_children) : - child = v.GetChildAtIndex(c) - if child is None: - file.write("None") - else: - if (child.GetName()) is None: - file.write("None") - else: - file.write(child.GetName()) - file.write('=') - print_var_value(child, file, frame) - file.write(',') - c = c + 1 - else: - if v.GetValue(frame) is None: - file.write("None") - else: - file.write(v.GetValue(frame)) - -# print_vars - Print variable values in output file. -def print_vars (tag, vars, fname, line, file, frame, target, thread): - # disable this thread. - count = thread.GetStopReasonDataCount() - bid = 0 - tid = 0 - for i in range(count): - id = thread.GetStopReasonDataAtIndex(i) - bp = target.FindBreakpointByID(id) - if bp.IsValid(): - if bp.IsEnabled() == True: - bid = bp.GetID() - tid = bp.GetThreadID() - bp.SetEnabled(False) - else: - bp_loc = bp.FindLocationByID(thread.GetStopReasonDataAtIndex(i+1)) - if bp_loc.IsValid(): - bid = bp_loc.GetBreakPoint().GetID() - tid = bp_loc.ThreadGetID() - bp_loc.SetEnabled(False); - - for i in range(vars.GetSize()): - v = vars.GetValueAtIndex(i) - if v.GetName() is not None: - file.write(tag) - file.write(fname) - file.write(':') - file.write(str(line)) - file.write(' ') - file.write(str(tid)) - file.write(':') - file.write(str(bid)) - file.write(' ') - file.write(v.GetName()) - file.write(' ') - AlreadyPrintedValues.clear() - print_var_value (v, file, frame) - file.write('\n') - -# set_breakpoints - set breakpoints as listed in input file. -def set_breakpoints (target, breakpoint_filename, file): - f = open(breakpoint_filename, "r") - lines = f.readlines() - for l in range(len(lines)): - c = lines[l].split() - # print "setting break point - ", c - bp = target.BreakpointCreateByLocation (str(c[0]), int(c[1])) - file.write("#Breakpoint ") - file.write(str(c[0])) - file.write(':') - file.write(str(c[1])) - file.write(' ') - file.write(str(bp.GetThreadID())) - file.write(':') - file.write(str(bp.GetID())) - file.write('\n') - f.close() - -# stopeed_at_breakpoint - Return True if process is stopeed at a -# breakpoint. -def stopped_at_breakpoint (process): - if process.IsValid(): - state = process.GetState() - if state == lldb.eStateStopped: - thread = process.GetThreadAtIndex(0) - if thread.IsValid(): - if thread.GetStopReason() == lldb.eStopReasonBreakpoint: - return True - return False - -# Create a new debugger instance -debugger = lldb.SBDebugger.Create() - -# When we step or continue, don't return from the function until the process -# stops. We do this by setting the async mode to false. -debugger.SetAsync (False) - -# Create a target from a file and arch -##print "Creating a target for '%s'" % sys.argv[1] - -target = debugger.CreateTargetWithFileAndArch (sys.argv[1], lldb.LLDB_ARCH_DEFAULT) - -if target.IsValid(): - #print "target is valid" - file=open(str(sys.argv[3]), 'w') - set_breakpoints (target, sys.argv[2], file) - - # Launch the process. Since we specified synchronous mode, we won't return - # from this function until we hit the breakpoint at main - sberror = lldb.SBError() - process = target.Launch (None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, sberror) - # Make sure the launch went ok - while stopped_at_breakpoint(process): - thread = process.GetThreadAtIndex (0) - frame = thread.GetFrameAtIndex (0) - if frame.IsValid(): - # #Print some simple frame info - ##print frame - #print "frame is valid" - function = frame.GetFunction() - if function.IsValid(): - fname = function.GetMangledName() - if fname is None: - fname = function.GetName() - #print "function : ",fname - line = frame.GetLineEntry().GetLine() - vars = frame.GetVariables(1,0,0,0) - print_vars ("#Argument ", vars, fname, line, file, frame, target, thread) - # vars = frame.GetVariables(0,1,0,0) - # print_vars ("#Variables ", vars, fname, line, file, frame, target, thread) - - process.Continue() - file.close() - -lldb.SBDebugger.Terminate() Removed: llvm/trunk/utils/CompareDebugInfo.py URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/CompareDebugInfo.py?rev=128424&view=auto ============================================================================== --- llvm/trunk/utils/CompareDebugInfo.py (original) +++ llvm/trunk/utils/CompareDebugInfo.py (removed) @@ -1,182 +0,0 @@ -#!/usr/bin/python - -import os -import sys - -DBG_OUTPUT_FILE="Output/" + sys.argv[1] + ".dbg.out" -OPT_DBG_OUTPUT_FILE="Output/" + sys.argv[1] + ".dbg.opt.out" -LOG_FILE="Output/" + sys.argv[1] + ".log" -NATIVE_DBG_OUTPUT_FILE="Output/" + sys.argv[1] + ".native.dbg.out" -NATIVE_OPT_DBG_OUTPUT_FILE="Output/" + sys.argv[1] + ".native.dbg.opt.out" -NATIVE_LOG_FILE="Output/" + sys.argv[1] + ".native.log" -REPORT_FILE="Output/" + sys.argv[1] + ".dbg.report.html" - -class BreakPoint: - def __init__(self, bp_name): - self.name = bp_name - self.values = {} - self.missing_args = [] - self.matching_args = [] - self.notmatching_args = [] - self.missing_bp = False - - def setMissing(self): - self.missing_bp = True - - def getArgCount(self): - return len(self.values) - - def getMissingArgCount(self): - if self.missing_bp == True: - return len(self.values) - return len(self.missing_args) - - def getMatchingArgCount(self): - if self.missing_bp == True: - return 0 - return len(self.matching_args) - - def getNotMatchingArgCount(self): - if self.missing_bp == True: - return 0 - return len(self.notmatching_args) - - def recordArgument(self, arg_name, value): - self.values[arg_name] = value - - def __repr__(self): - print self.name - items = self.values.items() - for i in range(len(items)): - print items[i][0]," = ",items[i][1] - return '' - - def compare_args(self, other, file): - myitems = self.values.items() - otheritems = other.values.items() - match = False - for i in range(len(myitems)): - if i >= len(otheritems): - match = True - self.missing_args.append(myitems[i][0]) - elif cmp(myitems[i][1], otheritems[i][1]): - match = True - self.notmatching_args.append(myitems[i][0]) - else: - self.matching_args.append(myitems[i][0]) - - self.print_list(self.matching_args, " Matching arguments ", file) - self.print_list(self.notmatching_args, " Not Matching arguments ", file) - self.print_list(self.missing_args, " Missing arguments ", file) - return match - - def print_list(self, items, txt, pfile): - if len(items) == 0: - return - pfile.write(self.name) - pfile.write(txt) - for e in items: - pfile.write(e) - pfile.write(' ') - pfile.write('\n') - -def read_input(filename, dict): - f = open(filename, "r") - lines = f.readlines() - for l in range(len(lines)): - c = lines[l].split() - if c[0] == "#Breakpoint": - bp = dict.get(c[2]) - if bp is None: - bp = BreakPoint(c[1]) - dict[c[2]] = bp - if c[0] == "#Argument": - bp = dict.get(c[2]) - if bp is None: - bp = BreakPoint(c[1]) - dict[c[2]] = bp - bp.recordArgument(c[3], c[4]) - return - -f1_breakpoints = {} -read_input(DBG_OUTPUT_FILE, f1_breakpoints) -f1_items = f1_breakpoints.items() - -f2_breakpoints = {} -read_input(OPT_DBG_OUTPUT_FILE, f2_breakpoints) -f2_items = f2_breakpoints.items() - -f = open(LOG_FILE, "w") -f.write("Log output\n") -for f2bp in range(len(f2_items)): - id = f2_items[f2bp][0] - bp = f2_items[f2bp][1] - bp1 = f1_breakpoints.get(id) - if bp1 is None: - bp.setMissing() - else: - bp1.compare_args(bp,f) -f.close() - -nf1_breakpoints = {} -read_input(NATIVE_DBG_OUTPUT_FILE, nf1_breakpoints) -nf1_items = nf1_breakpoints.items() - -nf2_breakpoints = {} -read_input(NATIVE_OPT_DBG_OUTPUT_FILE, nf2_breakpoints) -nf2_items = nf2_breakpoints.items() - -nfl = open(NATIVE_LOG_FILE, "w") -for nf2bp in range(len(nf2_items)): - id = nf2_items[nf2bp][0] - bp = nf2_items[nf2bp][1] - bp1 = nf1_breakpoints.get(id) - if bp1 is None: - bp.setMissing() - else: - bp1.compare_args(bp,nfl) -nfl.close() - -f1_arg_count = 0 -f1_matching_arg_count = 0 -f1_notmatching_arg_count = 0 -f1_missing_arg_count = 0 -for idx in range(len(f1_items)): - bp = f1_items[idx][1] - f1_arg_count = f1_arg_count + bp.getArgCount() - f1_matching_arg_count = f1_matching_arg_count + bp.getMatchingArgCount() - f1_notmatching_arg_count = f1_notmatching_arg_count + bp.getNotMatchingArgCount() - f1_missing_arg_count = f1_missing_arg_count + bp.getMissingArgCount() - -nf1_arg_count = 0 -nf1_matching_arg_count = 0 -nf1_notmatching_arg_count = 0 -nf1_missing_arg_count = 0 -for idx in range(len(nf1_items)): - bp = nf1_items[idx][1] - nf1_arg_count = nf1_arg_count + bp.getArgCount() - nf1_matching_arg_count = nf1_matching_arg_count + bp.getMatchingArgCount() - nf1_notmatching_arg_count = nf1_notmatching_arg_count + bp.getNotMatchingArgCount() - nf1_missing_arg_count = nf1_missing_arg_count + bp.getMissingArgCount() - -rf = open(REPORT_FILE, "w") -rf.write("") -rf.write(str(sys.argv[1])) -rf.write("|") -rf.write(str(nf1_arg_count)) -rf.write("") -rf.write(str(nf1_matching_arg_count)) -rf.write("") -rf.write(str(nf1_notmatching_arg_count)) -rf.write("") -rf.write(str(nf1_missing_arg_count)) -rf.write("|") -rf.write(str(f1_arg_count)) -rf.write("") -rf.write(str(f1_matching_arg_count)) -rf.write("") -rf.write(str(f1_notmatching_arg_count)) -rf.write("") -rf.write(str(f1_missing_arg_count)) -rf.write("\n") -rf.close() From kremenek at apple.com Mon Mar 28 15:43:53 2011 From: kremenek at apple.com (Ted Kremenek) Date: Mon, 28 Mar 2011 20:43:53 -0000 Subject: [llvm-commits] [llvm] r128426 - /llvm/trunk/lib/MC/MCDisassembler/CMakeLists.txt Message-ID: <20110328204353.AE70F2A6C12C@llvm.org> Author: kremenek Date: Mon Mar 28 15:43:53 2011 New Revision: 128426 URL: http://llvm.org/viewvc/llvm-project?rev=128426&view=rev Log: Unbreak CMake build. Modified: llvm/trunk/lib/MC/MCDisassembler/CMakeLists.txt Modified: llvm/trunk/lib/MC/MCDisassembler/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/CMakeLists.txt?rev=128426&r1=128425&r2=128426&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDisassembler/CMakeLists.txt (original) +++ llvm/trunk/lib/MC/MCDisassembler/CMakeLists.txt Mon Mar 28 15:43:53 2011 @@ -1,7 +1,8 @@ add_llvm_library(LLVMMCDisassembler + Disassembler.cpp EDDisassembler.cpp - EDOperand.cpp EDInst.cpp + EDOperand.cpp EDToken.cpp ) From daniel at zuster.org Mon Mar 28 17:49:15 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 28 Mar 2011 22:49:15 -0000 Subject: [llvm-commits] [llvm] r128430 - in /llvm/trunk: include/llvm/MC/MCContext.h lib/MC/MCContext.cpp test/MC/MachO/temp-labels.s tools/llvm-mc/llvm-mc.cpp Message-ID: <20110328224916.081BF2A6C12C@llvm.org> Author: ddunbar Date: Mon Mar 28 17:49:15 2011 New Revision: 128430 URL: http://llvm.org/viewvc/llvm-project?rev=128430&view=rev Log: MC: Add support for disabling "temporary label" behavior. Useful for debugging on Darwin. Added: llvm/trunk/test/MC/MachO/temp-labels.s Modified: llvm/trunk/include/llvm/MC/MCContext.h llvm/trunk/lib/MC/MCContext.cpp llvm/trunk/tools/llvm-mc/llvm-mc.cpp Modified: llvm/trunk/include/llvm/MC/MCContext.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=128430&r1=128429&r2=128430&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCContext.h (original) +++ llvm/trunk/include/llvm/MC/MCContext.h Mon Mar 28 17:49:15 2011 @@ -84,6 +84,11 @@ MCDwarfLoc CurrentDwarfLoc; bool DwarfLocSeen; + /// Honor temporary labels, this is useful for debugging semantic + /// differences between temporary and non-temporary labels (primarily on + /// Darwin). + bool AllowTemporaryLabels; + /// The dwarf line information from the .loc directives for the sections /// with assembled machine instructions have after seeing .loc directives. DenseMap MCLineSections; @@ -109,6 +114,8 @@ const TargetAsmInfo &getTargetAsmInfo() const { return *TAI; } + void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; } + /// @name Symbol Management /// @{ Modified: llvm/trunk/lib/MC/MCContext.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=128430&r1=128429&r2=128430&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCContext.cpp (original) +++ llvm/trunk/lib/MC/MCContext.cpp Mon Mar 28 17:49:15 2011 @@ -28,7 +28,8 @@ MCContext::MCContext(const MCAsmInfo &mai, const TargetAsmInfo *tai) : MAI(mai), TAI(tai), NextUniqueID(0), - CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0) { + CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0), + AllowTemporaryLabels(true) { MachOUniquingMap = 0; ELFUniquingMap = 0; COFFUniquingMap = 0; @@ -76,8 +77,10 @@ } MCSymbol *MCContext::CreateSymbol(StringRef Name) { - // Determine whether this is an assembler temporary or normal label. - bool isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix()); + // Determine whether this is an assembler temporary or normal label, if used. + bool isTemporary = false; + if (AllowTemporaryLabels) + isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix()); StringMapEntry *NameEntry = &UsedNames.GetOrCreateValue(Name); if (NameEntry->getValue()) { Added: llvm/trunk/test/MC/MachO/temp-labels.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/temp-labels.s?rev=128430&view=auto ============================================================================== --- llvm/trunk/test/MC/MachO/temp-labels.s (added) +++ llvm/trunk/test/MC/MachO/temp-labels.s Mon Mar 28 17:49:15 2011 @@ -0,0 +1,33 @@ +// RUN: llvm-mc -triple x86_64-apple-darwin10 %s -filetype=obj -L -o - | macho-dump --dump-section-data | FileCheck %s + +// CHECK: # Load Command 1 +// CHECK: (('command', 2) +// CHECK: ('size', 24) +// CHECK: ('symoff', 296) +// CHECK: ('nsyms', 2) +// CHECK: ('stroff', 328) +// CHECK: ('strsize', 8) +// CHECK: ('_string_data', '\x00_f0\x00L0\x00') +// CHECK: ('_symbols', [ +// CHECK: # Symbol 0 +// CHECK: (('n_strx', 1) +// CHECK: ('n_type', 0xe) +// CHECK: ('n_sect', 1) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 0) +// CHECK: ('_string', '_f0') +// CHECK: ), +// CHECK: # Symbol 1 +// CHECK: (('n_strx', 5) +// CHECK: ('n_type', 0xe) +// CHECK: ('n_sect', 1) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 4) +// CHECK: ('_string', 'L0') +// CHECK: ), +// CHECK: ]) +// CHECK: ), +_f0: + .long 0 +L0: + .long 0 Modified: llvm/trunk/tools/llvm-mc/llvm-mc.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/llvm-mc.cpp?rev=128430&r1=128429&r2=128430&view=diff ============================================================================== --- llvm/trunk/tools/llvm-mc/llvm-mc.cpp (original) +++ llvm/trunk/tools/llvm-mc/llvm-mc.cpp Mon Mar 28 17:49:15 2011 @@ -113,6 +113,10 @@ NoInitialTextSection("n", cl::desc( "Don't assume assembly file starts in the text section")); +static cl::opt +SaveTempLabels("L", cl::desc( + "Don't discard temporary labels")); + enum ActionType { AC_AsLex, AC_Assemble, @@ -327,6 +331,8 @@ const TargetAsmInfo *tai = new TargetAsmInfo(*TM); MCContext Ctx(*MAI, tai); + if (SaveTempLabels) + Ctx.setAllowTemporaryLabels(false); OwningPtr Out(GetOutputStream()); if (!Out) From daniel at zuster.org Mon Mar 28 17:49:19 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 28 Mar 2011 22:49:19 -0000 Subject: [llvm-commits] [llvm] r128431 - in /llvm/trunk: include/llvm/Target/TargetMachine.h lib/CodeGen/LLVMTargetMachine.cpp lib/Target/TargetMachine.cpp Message-ID: <20110328224919.A12D32A6C12D@llvm.org> Author: ddunbar Date: Mon Mar 28 17:49:19 2011 New Revision: 128431 URL: http://llvm.org/viewvc/llvm-project?rev=128431&view=rev Log: Integrated-As: Add support for setting the AllowTemporaryLabels flag via integrated-as. Modified: llvm/trunk/include/llvm/Target/TargetMachine.h llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp llvm/trunk/lib/Target/TargetMachine.cpp Modified: llvm/trunk/include/llvm/Target/TargetMachine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetMachine.h?rev=128431&r1=128430&r2=128431&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetMachine.h (original) +++ llvm/trunk/include/llvm/Target/TargetMachine.h Mon Mar 28 17:49:19 2011 @@ -106,6 +106,7 @@ unsigned MCRelaxAll : 1; unsigned MCNoExecStack : 1; + unsigned MCSaveTempLabels : 1; unsigned MCUseLoc : 1; public: @@ -172,6 +173,14 @@ /// relaxed. void setMCRelaxAll(bool Value) { MCRelaxAll = Value; } + /// hasMCSaveTempLabels - Check whether temporary labels will be preserved + /// (i.e., not treated as temporary). + bool hasMCSaveTempLabels() const { return MCSaveTempLabels; } + + /// setMCSaveTempLabels - Set whether temporary labels will be preserved + /// (i.e., not treated as temporary). + void setMCSaveTempLabels(bool Value) { MCSaveTempLabels = Value; } + /// hasMCNoExecStack - Check whether an executable stack is not needed. bool hasMCNoExecStack() const { return MCNoExecStack; } Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=128431&r1=128430&r2=128431&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Mon Mar 28 17:49:19 2011 @@ -126,6 +126,9 @@ return true; assert(Context != 0 && "Failed to get MCContext"); + if (hasMCSaveTempLabels()) + Context->setAllowTemporaryLabels(false); + const MCAsmInfo &MAI = *getMCAsmInfo(); OwningPtr AsmStreamer; @@ -231,6 +234,9 @@ if (addCommonCodeGenPasses(PM, OptLevel, DisableVerify, Ctx)) return true; + if (hasMCSaveTempLabels()) + Ctx->setAllowTemporaryLabels(false); + // Create the code emitter for the target if it exists. If not, .o file // emission fails. MCCodeEmitter *MCE = getTarget().createCodeEmitter(*this, *Ctx); Modified: llvm/trunk/lib/Target/TargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetMachine.cpp?rev=128431&r1=128430&r2=128431&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetMachine.cpp (original) +++ llvm/trunk/lib/Target/TargetMachine.cpp Mon Mar 28 17:49:19 2011 @@ -221,6 +221,7 @@ : TheTarget(T), AsmInfo(0), MCRelaxAll(false), MCNoExecStack(false), + MCSaveTempLabels(false), MCUseLoc(true) { // Typically it will be subtargets that will adjust FloatABIType from Default // to Soft or Hard. From isanbard at gmail.com Mon Mar 28 18:02:18 2011 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 28 Mar 2011 23:02:18 -0000 Subject: [llvm-commits] [llvm] r128434 - in /llvm/trunk: lib/CodeGen/StackProtector.cpp test/CodeGen/X86/crash.ll Message-ID: <20110328230218.6CF852A6C12C@llvm.org> Author: void Date: Mon Mar 28 18:02:18 2011 New Revision: 128434 URL: http://llvm.org/viewvc/llvm-project?rev=128434&view=rev Log: In some cases, the "fail BB dominator" may be null after the BB was split (and becomes reachable when before it wasn't). Check to make sure that it's not null before trying to use it. Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp llvm/trunk/test/CodeGen/X86/crash.ll Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=128434&r1=128433&r2=128434&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackProtector.cpp (original) +++ llvm/trunk/lib/CodeGen/StackProtector.cpp Mon Mar 28 18:02:18 2011 @@ -221,7 +221,8 @@ BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return"); if (DT && DT->isReachableFromEntry(BB)) { DT->addNewBlock(NewBB, BB); - FailBBDom = DT->findNearestCommonDominator(FailBBDom, BB); + if (FailBBDom) + FailBBDom = DT->findNearestCommonDominator(FailBBDom, BB); } // Remove default branch instruction to the new BB. Modified: llvm/trunk/test/CodeGen/X86/crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/crash.ll?rev=128434&r1=128433&r2=128434&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/crash.ll (original) +++ llvm/trunk/test/CodeGen/X86/crash.ll Mon Mar 28 18:02:18 2011 @@ -189,7 +189,7 @@ } ; PR9028 -define void @f(i64 %A) nounwind { +define void @func_60(i64 %A) nounwind { entry: %0 = zext i64 %A to i160 %1 = shl i160 %0, 64 @@ -199,3 +199,19 @@ store i576 %4, i576* undef, align 8 ret void } + +; +define fastcc void @func_61() nounwind sspreq { +entry: + %t1 = tail call i64 @llvm.objectsize.i64(i8* undef, i1 false) + %t2 = icmp eq i64 %t1, -1 + br i1 %t2, label %bb2, label %bb1 + +bb1: + ret void + +bb2: + ret void +} + +declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone From fjahanian at apple.com Mon Mar 28 18:48:25 2011 From: fjahanian at apple.com (Fariborz Jahanian) Date: Mon, 28 Mar 2011 23:48:25 -0000 Subject: [llvm-commits] [test-suite] r128436 - in /test-suite/trunk/SingleSource/UnitTests/ObjC++: Makefile property-reference-object.mm property-reference-object.reference_output Message-ID: <20110328234825.49B1F2A6C12C@llvm.org> Author: fjahanian Date: Mon Mar 28 18:48:25 2011 New Revision: 128436 URL: http://llvm.org/viewvc/llvm-project?rev=128436&view=rev Log: This is test for clang's // rdar://9070460. I have modified the Makefile so test is skipped for llvm-gcc (which does not fully support this feature). Added: test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output Modified: test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile Modified: test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/Makefile?rev=128436&r1=128435&r2=128436&view=diff ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile (original) +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile Mon Mar 28 18:48:25 2011 @@ -6,4 +6,10 @@ LDFLAGS += -lstdc++ -lobjc -framework Foundation PROGRAM_REQUIRED_TO_EXIT_OK := 1 + +# This is a known gcc / llvm-gcc miscompilation fixed in clang. +ifdef CC_UNDER_TEST_IS_LLVM_GCC +EXEC_XFAILS = property-reference-object +endif + include $(LEVEL)/SingleSource/Makefile.singlesrc Added: test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/property-reference-object.mm?rev=128436&view=auto ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm (added) +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm Mon Mar 28 18:48:25 2011 @@ -0,0 +1,105 @@ +#import + +static int count; +class Foo +{ + static int sNextId; + int mId; + int mRefId; +public: + Foo(const Foo& rhs){ + mId = sNextId++; + mRefId = rhs.mId; + printf("Foo(%d,%d)\n", mId, mRefId); + }; + + Foo() { + mId = sNextId++; + mRefId = mId; + printf("Foo(%d,%d)\n", mId,mRefId); + } + ~Foo(){ + printf("~Foo(%d, %d)\n", mId, mRefId); + }; + + Foo& operator=(const Foo& rhs){ + mRefId = rhs.mRefId; + return *this; + }; + + int Data() { return fData; }; + +private: + int fData; +}; + +int Foo::sNextId = 0; + + +#pragma mark - + + + at interface TNSObject : NSObject +{ + at private + Foo _cppObjectNonAtomic; + Foo _cppObjectAtomic; + Foo _cppObjectDynamic; +} + + at property (assign, readwrite, nonatomic) const Foo& cppObjectNonAtomic; + at property (assign, readwrite) const Foo& cppObjectAtomic; + at property (assign, readwrite, nonatomic) const Foo& cppObjectDynamic; + at end + + +#pragma mark - + + + at implementation TNSObject + + at synthesize cppObjectNonAtomic = _cppObjectNonAtomic; + at synthesize cppObjectAtomic = _cppObjectAtomic; + at dynamic cppObjectDynamic; + +- (id)init +{ + self = [super init]; + if (self) { + + // Add your subclass-specific initialization here. + // If an error occurs here, send a [self release] message and return nil. + + Foo cppObject; + self.cppObjectNonAtomic = cppObject; + self.cppObjectAtomic = cppObject; + self.cppObjectDynamic = cppObject; + } + return self; +} + +- (const Foo&) cppObjectDynamic +{ + return _cppObjectDynamic; +} + +- (void) setCppObjectDynamic: (const Foo&)cppObject +{ + _cppObjectDynamic = cppObject; +} + at end + + +#pragma mark - + + +int main (int argc, const char * argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + [[[TNSObject alloc] init] autorelease]; + + [pool drain]; + return 0; +} + Added: test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/property-reference-object.reference_output?rev=128436&view=auto ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output (added) +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output Mon Mar 28 18:48:25 2011 @@ -0,0 +1,14 @@ +Foo(0,0) +Foo(1,1) +Foo(2,2) +Foo(3,3) +Foo(4,3) +~Foo(4, 3) +Foo(5,3) +~Foo(5, 3) +Foo(6,3) +~Foo(6, 3) +~Foo(3, 3) +~Foo(2, 3) +~Foo(1, 3) +~Foo(0, 3) From fjahanian at apple.com Mon Mar 28 18:55:48 2011 From: fjahanian at apple.com (Fariborz Jahanian) Date: Mon, 28 Mar 2011 23:55:48 -0000 Subject: [llvm-commits] [test-suite] r128438 - /test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output Message-ID: <20110328235548.4BEA52A6C12C@llvm.org> Author: fjahanian Date: Mon Mar 28 18:55:48 2011 New Revision: 128438 URL: http://llvm.org/viewvc/llvm-project?rev=128438&view=rev Log: updated reference output file to match the convention. // rdar://9070460 Modified: test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output Modified: test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/property-reference-object.reference_output?rev=128438&r1=128437&r2=128438&view=diff ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output (original) +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output Mon Mar 28 18:55:48 2011 @@ -12,3 +12,4 @@ ~Foo(2, 3) ~Foo(1, 3) ~Foo(0, 3) +exit 0 From aggarwa4 at illinois.edu Mon Mar 28 18:59:38 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 28 Mar 2011 23:59:38 -0000 Subject: [llvm-commits] [poolalloc] r128439 - in /poolalloc/trunk/test/dsa/var_arg: print.c print.ll Message-ID: <20110328235938.2B87D2A6C12C@llvm.org> Author: aggarwa4 Date: Mon Mar 28 18:59:37 2011 New Revision: 128439 URL: http://llvm.org/viewvc/llvm-project?rev=128439&view=rev Log: A usage of va_start. Derived from mpg123. Added: poolalloc/trunk/test/dsa/var_arg/print.c poolalloc/trunk/test/dsa/var_arg/print.ll Added: poolalloc/trunk/test/dsa/var_arg/print.c URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/var_arg/print.c?rev=128439&view=auto ============================================================================== --- poolalloc/trunk/test/dsa/var_arg/print.c (added) +++ poolalloc/trunk/test/dsa/var_arg/print.c Mon Mar 28 18:59:37 2011 @@ -0,0 +1,28 @@ +#include +#include + +//--build the code into a .bc +//RUN: llvm-gcc -O0 %s -S --emit-llvm -o - | llvm-as > %t.bc +//--check if ds-aa breaks, breaks opts, or results in miscompiled code +//RUN: lli %t.bc > %t.refout +//RUN: dsaopt %t.bc -ds-aa -O3 -o - | lli > %t.out +//RUN: diff %t.refout %t.out +//--check properties of this particular test +//N/A + +void generic_sendmsg (const char *fmt, ...) +{ + va_list ap; + printf( "@"); + va_start(ap, fmt); + vprintf( fmt, ap); + va_end(ap); + printf("\n"); +} + +void main() { + int *x = malloc(sizeof(int)); + generic_sendmsg("F %li %li %3.2f %3.2f", 1234, 1234,123.22, 123.45); + generic_sendmsg("%s ID3:%s%s", "TEST", "AAA" , "Unknown"); + generic_sendmsg("%s ID3:%s%s %p", "TEST", "AAA" , "Unknown", x); +} Added: poolalloc/trunk/test/dsa/var_arg/print.ll URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/var_arg/print.ll?rev=128439&view=auto ============================================================================== --- poolalloc/trunk/test/dsa/var_arg/print.ll (added) +++ poolalloc/trunk/test/dsa/var_arg/print.ll Mon Mar 28 18:59:37 2011 @@ -0,0 +1,66 @@ +; ModuleID = 'tt.o' +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-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" +;RUN: dsaopt %s -dsa-local -disable-output +;RUN: dsaopt %s -dsa-bu -disable-output +;RUN: dsaopt %s -dsa-td -disable-output +;RUN: dsaopt %s -dsa-eq -disable-output + +%struct.__va_list_tag = type { i32, i32, i8*, i8* } + + at .str = private constant [22 x i8] c"F %li %li %3.2f %3.2f\00", align 1 ; <[22 x i8]*> [#uses=1] + at .str1 = private constant [12 x i8] c"%s ID3:%s%s\00", align 1 ; <[12 x i8]*> [#uses=1] + at .str2 = private constant [5 x i8] c"TEST\00", align 1 ; <[5 x i8]*> [#uses=1] + at .str3 = private constant [4 x i8] c"AAA\00", align 1 ; <[4 x i8]*> [#uses=1] + at .str4 = private constant [8 x i8] c"Unknown\00", align 1 ; <[8 x i8]*> [#uses=1] + at .str5 = private constant [15 x i8] c"%s ID3:%s%s %p\00", align 1 ; <[15 x i8]*> [#uses=1] + +define internal void @generic_sendmsg(i8* %fmt, ...) nounwind { +entry: + %fmt_addr = alloca i8* ; [#uses=2] + %ap = alloca [1 x %struct.__va_list_tag] ; <[1 x %struct.__va_list_tag]*> [#uses=3] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i8* %fmt, i8** %fmt_addr + %0 = call i32 @putchar(i32 64) nounwind ; [#uses=0] + %ap1 = bitcast [1 x %struct.__va_list_tag]* %ap to %struct.__va_list_tag* ; <%struct.__va_list_tag*> [#uses=1] + %ap12 = bitcast %struct.__va_list_tag* %ap1 to i8* ; [#uses=1] + call void @llvm.va_start(i8* %ap12) + %1 = load i8** %fmt_addr, align 8 ; [#uses=1] + %ap3 = bitcast [1 x %struct.__va_list_tag]* %ap to %struct.__va_list_tag* ; <%struct.__va_list_tag*> [#uses=1] + %2 = call i32 @vprintf(i8* noalias %1, %struct.__va_list_tag* %ap3) nounwind ; [#uses=0] + %ap4 = bitcast [1 x %struct.__va_list_tag]* %ap to %struct.__va_list_tag* ; <%struct.__va_list_tag*> [#uses=1] + %ap45 = bitcast %struct.__va_list_tag* %ap4 to i8* ; [#uses=1] + call void @llvm.va_end(i8* %ap45) + %3 = call i32 @putchar(i32 10) nounwind ; [#uses=0] + br label %return + +return: ; preds = %entry + ret void +} + +declare i32 @putchar(i32) + +declare void @llvm.va_start(i8*) nounwind + +declare i32 @vprintf(i8* noalias, %struct.__va_list_tag*) nounwind + +declare void @llvm.va_end(i8*) nounwind + +define void @main() nounwind { +entry: + %x = alloca i32* ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + %0 = call noalias i8* @malloc(i64 4) nounwind ; [#uses=1] + %1 = bitcast i8* %0 to i32* ; [#uses=1] + store i32* %1, i32** %x, align 8 + call void (i8*, ...)* @generic_sendmsg(i8* getelementptr inbounds ([22 x i8]* @.str, i64 0, i64 0), i32 1234, i32 1234, double 1.232200e+02, double 1.234500e+02) nounwind + call void (i8*, ...)* @generic_sendmsg(i8* getelementptr inbounds ([12 x i8]* @.str1, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8]* @.str2, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8]* @.str3, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8]* @.str4, i64 0, i64 0)) nounwind + %2 = load i32** %x, align 8 ; [#uses=1] + call void (i8*, ...)* @generic_sendmsg(i8* getelementptr inbounds ([15 x i8]* @.str5, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8]* @.str2, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8]* @.str3, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8]* @.str4, i64 0, i64 0), i32* %2) nounwind + br label %return + +return: ; preds = %entry + ret void +} + +declare noalias i8* @malloc(i64) nounwind From dpatel at apple.com Mon Mar 28 19:01:39 2011 From: dpatel at apple.com (Devang Patel) Date: Tue, 29 Mar 2011 00:01:39 -0000 Subject: [llvm-commits] [llvm] r128440 - in /llvm/trunk/tools/lto: Makefile lto.exports Message-ID: <20110329000139.73D4B2A6C12C@llvm.org> Author: dpatel Date: Mon Mar 28 19:01:39 2011 New Revision: 128440 URL: http://llvm.org/viewvc/llvm-project?rev=128440&view=rev Log: Expoert c interface for disassembler. Modified: llvm/trunk/tools/lto/Makefile llvm/trunk/tools/lto/lto.exports Modified: llvm/trunk/tools/lto/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/Makefile?rev=128440&r1=128439&r2=128440&view=diff ============================================================================== --- llvm/trunk/tools/lto/Makefile (original) +++ llvm/trunk/tools/lto/Makefile Mon Mar 28 19:01:39 2011 @@ -20,7 +20,8 @@ LINK_LIBS_IN_SHARED = 1 SHARED_LIBRARY = 1 -LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader bitwriter +LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader \ + bitwriter mcdisassembler include $(LEVEL)/Makefile.common Modified: llvm/trunk/tools/lto/lto.exports URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.exports?rev=128440&r1=128439&r2=128440&view=diff ============================================================================== --- llvm/trunk/tools/lto/lto.exports (original) +++ llvm/trunk/tools/lto/lto.exports Mon Mar 28 19:01:39 2011 @@ -27,3 +27,6 @@ lto_codegen_set_assembler_path lto_codegen_set_cpu lto_codegen_compile_to_file +LLVMCreateDisasm +LLVMDisasmDispose +LLVMDisasmInstruction From pichet2000 at gmail.com Mon Mar 28 19:30:01 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Tue, 29 Mar 2011 00:30:01 -0000 Subject: [llvm-commits] [llvm] r128441 - /llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp Message-ID: <20110329003001.C21062A6C12C@llvm.org> Author: fpichet Date: Mon Mar 28 19:30:01 2011 New Revision: 128441 URL: http://llvm.org/viewvc/llvm-project?rev=128441&view=rev Log: Fix the MSVC build. Modified: llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp Modified: llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp?rev=128441&r1=128440&r2=128441&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp (original) +++ llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp Mon Mar 28 19:30:01 2011 @@ -160,7 +160,11 @@ std::string p; p = OS.str(); +#ifdef LLVM_ON_WIN32 + sprintf(OutString, "%s", p.c_str()); +#else snprintf(OutString, OutStringSize, "%s", p.c_str()); +#endif return Size; } From evan.cheng at apple.com Mon Mar 28 20:56:09 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 29 Mar 2011 01:56:09 -0000 Subject: [llvm-commits] [llvm] r128444 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/vmul.ll Message-ID: <20110329015610.0B0F12A6C12C@llvm.org> Author: evancheng Date: Mon Mar 28 20:56:09 2011 New Revision: 128444 URL: http://llvm.org/viewvc/llvm-project?rev=128444&view=rev Log: Optimizing (zext A + zext B) * C, to (VMULL A, C) + (VMULL B, C) during isel lowering to fold the zero-extend's and take advantage of no-stall back to back vmul + vmla: vmull q0, d4, d6 vmlal q0, d5, d6 is faster than vaddl q0, d4, d5 vmovl q1, d6 vmul q0, q0, q1 This allows us to vmull + vmlal for: f = vmull_u8( vget_high_u8(s), c); f = vmlal_u8(f, vget_low_u8(s), c); rdar://9197392 Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/test/CodeGen/ARM/vmul.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=128444&r1=128443&r2=128444&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Mar 28 20:56:09 2011 @@ -4370,6 +4370,28 @@ MVT::getVectorVT(TruncVT, NumElts), Ops.data(), NumElts); } +static bool isAddSubSExt(SDNode *N, SelectionDAG &DAG) { + unsigned Opcode = N->getOpcode(); + if (Opcode == ISD::ADD || Opcode == ISD::SUB) { + SDNode *N0 = N->getOperand(0).getNode(); + SDNode *N1 = N->getOperand(1).getNode(); + return N0->hasOneUse() && N1->hasOneUse() && + isSignExtended(N0, DAG) && isSignExtended(N1, DAG); + } + return false; +} + +static bool isAddSubZExt(SDNode *N, SelectionDAG &DAG) { + unsigned Opcode = N->getOpcode(); + if (Opcode == ISD::ADD || Opcode == ISD::SUB) { + SDNode *N0 = N->getOperand(0).getNode(); + SDNode *N1 = N->getOperand(1).getNode(); + return N0->hasOneUse() && N1->hasOneUse() && + isZeroExtended(N0, DAG) && isZeroExtended(N1, DAG); + } + return false; +} + static SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) { // Multiplications are only custom-lowered for 128-bit vectors so that // VMULL can be detected. Otherwise v2i64 multiplications are not legal. @@ -4378,26 +4400,70 @@ SDNode *N0 = Op.getOperand(0).getNode(); SDNode *N1 = Op.getOperand(1).getNode(); unsigned NewOpc = 0; - if (isSignExtended(N0, DAG) && isSignExtended(N1, DAG)) + bool isMLA = false; + bool isN0SExt = isSignExtended(N0, DAG); + bool isN1SExt = isSignExtended(N1, DAG); + if (isN0SExt && isN1SExt) NewOpc = ARMISD::VMULLs; - else if (isZeroExtended(N0, DAG) && isZeroExtended(N1, DAG)) - NewOpc = ARMISD::VMULLu; - else if (VT == MVT::v2i64) - // Fall through to expand this. It is not legal. - return SDValue(); - else - // Other vector multiplications are legal. - return Op; + else { + bool isN0ZExt = isZeroExtended(N0, DAG); + bool isN1ZExt = isZeroExtended(N1, DAG); + if (isN0ZExt && isN1ZExt) + NewOpc = ARMISD::VMULLu; + else if (isN1SExt || isN1ZExt) { + // Look for (s/zext A + s/zext B) * (s/zext C). We want to turn these + // into (s/zext A * s/zext C) + (s/zext B * s/zext C) + if (isN1SExt && isAddSubSExt(N0, DAG)) { + NewOpc = ARMISD::VMULLs; + isMLA = true; + } else if (isN1ZExt && isAddSubZExt(N0, DAG)) { + NewOpc = ARMISD::VMULLu; + isMLA = true; + } else if (isN0ZExt && isAddSubZExt(N1, DAG)) { + std::swap(N0, N1); + NewOpc = ARMISD::VMULLu; + isMLA = true; + } + } + + if (!NewOpc) { + if (VT == MVT::v2i64) + // Fall through to expand this. It is not legal. + return SDValue(); + else + // Other vector multiplications are legal. + return Op; + } + } // Legalize to a VMULL instruction. DebugLoc DL = Op.getDebugLoc(); - SDValue Op0 = SkipExtension(N0, DAG); + SDValue Op0; SDValue Op1 = SkipExtension(N1, DAG); - - assert(Op0.getValueType().is64BitVector() && - Op1.getValueType().is64BitVector() && - "unexpected types for extended operands to VMULL"); - return DAG.getNode(NewOpc, DL, VT, Op0, Op1); + if (!isMLA) { + Op0 = SkipExtension(N0, DAG); + assert(Op0.getValueType().is64BitVector() && + Op1.getValueType().is64BitVector() && + "unexpected types for extended operands to VMULL"); + return DAG.getNode(NewOpc, DL, VT, Op0, Op1); + } + + // Optimizing (zext A + zext B) * C, to (VMULL A, C) + (VMULL B, C) during + // isel lowering to take advantage of no-stall back to back vmul + vmla. + // vmull q0, d4, d6 + // vmlal q0, d5, d6 + // is faster than + // vaddl q0, d4, d5 + // vmovl q1, d6 + // vmul q0, q0, q1 + SDValue N00 = SkipExtension(N0->getOperand(0).getNode(), DAG); + SDValue N01 = SkipExtension(N0->getOperand(1).getNode(), DAG); + EVT Op1VT = Op1.getValueType(); + return DAG.getNode(N0->getOpcode(), DL, VT, + DAG.getNode(NewOpc, DL, VT, + DAG.getNode(ISD::BITCAST, DL, Op1VT, N00), Op1), + DAG.getNode(NewOpc, DL, VT, + DAG.getNode(ISD::BITCAST, DL, Op1VT, N01), Op1)); } static SDValue Modified: llvm/trunk/test/CodeGen/ARM/vmul.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vmul.ll?rev=128444&r1=128443&r2=128444&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vmul.ll (original) +++ llvm/trunk/test/CodeGen/ARM/vmul.ll Mon Mar 28 20:56:09 2011 @@ -339,3 +339,32 @@ %tmp4 = mul <2 x i64> %tmp3, ret <2 x i64> %tmp4 } + +; rdar://9197392 +define void @distribue(i16* %dst, i8* %src, i32 %mul) nounwind { +entry: +; CHECK: distribue: +; CHECK: vmull.u8 [[REG1:(q[0-9]+)]], d{{.*}}, [[REG2:(d[0-9]+)]] +; CHECK: vmlal.u8 [[REG1]], d{{.*}}, [[REG2]] + %0 = trunc i32 %mul to i8 + %1 = insertelement <8 x i8> undef, i8 %0, i32 0 + %2 = shufflevector <8 x i8> %1, <8 x i8> undef, <8 x i32> zeroinitializer + %3 = tail call <16 x i8> @llvm.arm.neon.vld1.v16i8(i8* %src, i32 1) + %4 = bitcast <16 x i8> %3 to <2 x double> + %5 = extractelement <2 x double> %4, i32 1 + %6 = bitcast double %5 to <8 x i8> + %7 = zext <8 x i8> %6 to <8 x i16> + %8 = zext <8 x i8> %2 to <8 x i16> + %9 = extractelement <2 x double> %4, i32 0 + %10 = bitcast double %9 to <8 x i8> + %11 = zext <8 x i8> %10 to <8 x i16> + %12 = add <8 x i16> %7, %11 + %13 = mul <8 x i16> %12, %8 + %14 = bitcast i16* %dst to i8* + tail call void @llvm.arm.neon.vst1.v8i16(i8* %14, <8 x i16> %13, i32 2) + ret void +} + +declare <16 x i8> @llvm.arm.neon.vld1.v16i8(i8*, i32) nounwind readonly + +declare void @llvm.arm.neon.vst1.v8i16(i8*, <8 x i16>, i32) nounwind From rafael.espindola at gmail.com Mon Mar 28 21:18:55 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Tue, 29 Mar 2011 02:18:55 -0000 Subject: [llvm-commits] [llvm] r128445 - /llvm/trunk/test/CodeGen/X86/dbg-file-name.ll Message-ID: <20110329021855.1BD592A6C12C@llvm.org> Author: rafael Date: Mon Mar 28 21:18:54 2011 New Revision: 128445 URL: http://llvm.org/viewvc/llvm-project?rev=128445&view=rev Log: Reduce test case. Modified: llvm/trunk/test/CodeGen/X86/dbg-file-name.ll Modified: llvm/trunk/test/CodeGen/X86/dbg-file-name.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dbg-file-name.ll?rev=128445&r1=128444&r2=128445&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/dbg-file-name.ll (original) +++ llvm/trunk/test/CodeGen/X86/dbg-file-name.ll Mon Mar 28 21:18:54 2011 @@ -1,69 +1,19 @@ -; RUN: llc -O0 < %s | FileCheck %s -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-n8:16:32:64" -target triple = "x86_64-apple-darwin10.0.0" +; RUN: llc -mtriple x86_64-apple-darwin10.0.0 < %s | FileCheck %s ; Radar 8884898 ; CHECK: file 1 "/Users/manav/one/two/simple.c" - at .str = private unnamed_addr constant [8 x i8] c"i = %d\0A\00", align 4 - at .str1 = private unnamed_addr constant [12 x i8] c"i + 1 = %d\0A\00", align 4 - -define void @foo(i32 %i) nounwind { -entry: - %i_addr = alloca i32, align 4 - %"alloca point" = bitcast i32 0 to i32 - call void @llvm.dbg.declare(metadata !{i32* %i_addr}, metadata !9), !dbg !10 - store i32 %i, i32* %i_addr - %0 = load i32* %i_addr, align 4, !dbg !11 - %1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]* @.str, i32 0, i32 0), i32 %0) nounwind, !dbg !11 - %2 = load i32* %i_addr, align 4, !dbg !13 - %3 = add nsw i32 %2, 1, !dbg !13 - %4 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str1, i32 0, i32 0), i32 %3) nounwind, !dbg !13 - br label %return, !dbg !14 - -return: ; preds = %entry - ret void, !dbg !14 -} - -declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone - declare i32 @printf(i8*, ...) nounwind define i32 @main() nounwind { -entry: - %retval = alloca i32 - %0 = alloca i32 - %"alloca point" = bitcast i32 0 to i32 - call void @foo(i32 2) nounwind, !dbg !15 - call void @foo(i32 4) nounwind, !dbg !17 - store i32 0, i32* %0, align 4, !dbg !18 - %1 = load i32* %0, align 4, !dbg !18 - store i32 %1, i32* %retval, align 4, !dbg !18 - br label %return, !dbg !18 - -return: ; preds = %entry - %retval1 = load i32* %retval, !dbg !18 - ret i32 %retval1, !dbg !18 + ret i32 0 } -!llvm.dbg.sp = !{!0, !6} +!llvm.dbg.sp = !{ !6} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"foo", metadata !1, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i32)* @foo} ; [ DW_TAG_subprogram ] !1 = metadata !{i32 589865, metadata !"simple.c", metadata !"/Users/manav/one/two", metadata !2} ; [ DW_TAG_file_type ] !2 = metadata !{i32 589841, i32 0, i32 1, metadata !"simple.c", metadata !"/Users/manav/one/two", metadata !"LLVM build 00", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{null, metadata !5} !5 = metadata !{i32 589860, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] !6 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 9, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] !7 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, null} ; [ DW_TAG_subroutine_type ] !8 = metadata !{metadata !5} -!9 = metadata !{i32 590081, metadata !0, metadata !"i", metadata !1, i32 4, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!10 = metadata !{i32 4, i32 0, metadata !0, null} -!11 = metadata !{i32 5, i32 0, metadata !12, null} -!12 = metadata !{i32 589835, metadata !0, i32 4, i32 0, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!13 = metadata !{i32 6, i32 0, metadata !12, null} -!14 = metadata !{i32 7, i32 0, metadata !12, null} -!15 = metadata !{i32 10, i32 0, metadata !16, null} -!16 = metadata !{i32 589835, metadata !6, i32 9, i32 0, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] -!17 = metadata !{i32 11, i32 0, metadata !16, null} -!18 = metadata !{i32 12, i32 0, metadata !16, null} From daniel at zuster.org Mon Mar 28 21:30:34 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 29 Mar 2011 02:30:34 -0000 Subject: [llvm-commits] [llvm] r128446 - /llvm/trunk/include/llvm-c/Disassembler.h Message-ID: <20110329023034.6CC322A6C12C@llvm.org> Author: ddunbar Date: Mon Mar 28 21:30:34 2011 New Revision: 128446 URL: http://llvm.org/viewvc/llvm-project?rev=128446&view=rev Log: C-API: Include DataTypes.h instead of stdint.h. Modified: llvm/trunk/include/llvm-c/Disassembler.h Modified: llvm/trunk/include/llvm-c/Disassembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Disassembler.h?rev=128446&r1=128445&r2=128446&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/Disassembler.h (original) +++ llvm/trunk/include/llvm-c/Disassembler.h Mon Mar 28 21:30:34 2011 @@ -15,8 +15,8 @@ #ifndef LLVM_C_DISASSEMBLER_H #define LLVM_C_DISASSEMBLER_H 1 -#include #include +#include "llvm/Support/DataTypes.h" /** * An opaque reference to a disassembler context. From daniel at zuster.org Mon Mar 28 21:59:26 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 29 Mar 2011 02:59:26 -0000 Subject: [llvm-commits] [zorg] r128447 - /zorg/trunk/llvmlab/llvmlab/ui/app.py Message-ID: <20110329025926.23F922A6C12C@llvm.org> Author: ddunbar Date: Mon Mar 28 21:59:25 2011 New Revision: 128447 URL: http://llvm.org/viewvc/llvm-project?rev=128447&view=rev Log: llvmlab: Work around an annoying property of the werkzeug reloader where the app instance is created twice. This means we end up with two monitor threads when running a debug server, which is not what we want. Modified: zorg/trunk/llvmlab/llvmlab/ui/app.py Modified: zorg/trunk/llvmlab/llvmlab/ui/app.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/llvmlab/llvmlab/ui/app.py?rev=128447&r1=128446&r2=128447&view=diff ============================================================================== --- zorg/trunk/llvmlab/llvmlab/ui/app.py (original) +++ zorg/trunk/llvmlab/llvmlab/ui/app.py Mon Mar 28 21:59:25 2011 @@ -64,9 +64,6 @@ module = __import__(plugins_module, fromlist=['__name__']) module.register(app) - # Spawn the status monitor thread. - app.monitor = app.config.status.start_monitor(app) - return app @staticmethod @@ -181,3 +178,14 @@ # Return the appropriate user object. return self.config.data.users[id] + + def __call__(self, environ, start_response): + # This works around an annoying property of the werkzeug reloader where + # we can't tell if we are in the actual web app instance. + # + # FIXME: Find a nicer solution. + if not self.monitor: + # Spawn the status monitor thread. + self.monitor = self.config.status.start_monitor(self) + + return flask.Flask.__call__(self, environ, start_response) From daniel at zuster.org Mon Mar 28 21:59:28 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 29 Mar 2011 02:59:28 -0000 Subject: [llvm-commits] [zorg] r128448 - /zorg/trunk/llvmlab/llvmlab/ui/app.py Message-ID: <20110329025928.F1E732A6C12D@llvm.org> Author: ddunbar Date: Mon Mar 28 21:59:28 2011 New Revision: 128448 URL: http://llvm.org/viewvc/llvm-project?rev=128448&view=rev Log: llvmlab.app: Improve save_status to be a bit more reliable and make sure we don't leave the status file in an indeterminant state. Modified: zorg/trunk/llvmlab/llvmlab/ui/app.py Modified: zorg/trunk/llvmlab/llvmlab/ui/app.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/llvmlab/llvmlab/ui/app.py?rev=128448&r1=128447&r2=128448&view=diff ============================================================================== --- zorg/trunk/llvmlab/llvmlab/ui/app.py (original) +++ zorg/trunk/llvmlab/llvmlab/ui/app.py Mon Mar 28 21:59:28 2011 @@ -2,6 +2,7 @@ import logging import logging.handlers import os +import shutil import flask @@ -158,12 +159,22 @@ def save_status(self): install_path = self.config["INSTALL_PATH"] - data_path = os.path.join(install_path, "lab-status.json") + data_path = os.path.join(install_path, "lab-status.json.new") file = open(data_path, 'w') flask.json.dump(self.config.status.todata(), file, indent=2) print >>file file.close() + # Backup the current status. + backup_path = os.path.join(install_path, "lab-status.json.bak") + status_path = os.path.join(install_path, "lab-status.json") + try: + os.remove(backup_path) + except: + pass + shutil.move(status_path, backup_path) + shutil.move(data_path, status_path) + def authenticate_login(self, username, password): passhash = hashlib.sha256( password + self.config["SECRET_KEY"]).hexdigest() From stoklund at 2pi.dk Mon Mar 28 22:12:02 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 29 Mar 2011 03:12:02 -0000 Subject: [llvm-commits] [llvm] r128449 - in /llvm/trunk/lib/CodeGen: InlineSpiller.cpp LiveRangeEdit.cpp LiveRangeEdit.h Message-ID: <20110329031202.B21B92A6C12C@llvm.org> Author: stoklund Date: Mon Mar 28 22:12:02 2011 New Revision: 128449 URL: http://llvm.org/viewvc/llvm-project?rev=128449&view=rev Log: Properly enable rematerialization when spilling after live range splitting. The instruction to be rematerialized may not be the one defining the register that is being spilled. The traceSiblingValue() function sees through sibling copies to find the remat candidate. Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp llvm/trunk/lib/CodeGen/LiveRangeEdit.h Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InlineSpiller.cpp?rev=128449&r1=128448&r2=128449&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/InlineSpiller.cpp (original) +++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp Mon Mar 28 22:12:02 2011 @@ -120,13 +120,14 @@ } bool isSibling(unsigned Reg); - void traceSiblingValue(unsigned, VNInfo*, VNInfo*); + MachineInstr *traceSiblingValue(unsigned, VNInfo*, VNInfo*); void analyzeSiblingValues(); bool hoistSpill(LiveInterval &SpillLI, MachineInstr *CopyMI); void eliminateRedundantSpills(LiveInterval &LI, VNInfo *VNI); - bool reMaterializeFor(MachineBasicBlock::iterator MI); + void markValueUsed(LiveInterval*, VNInfo*); + bool reMaterializeFor(LiveInterval&, MachineBasicBlock::iterator MI); void reMaterializeAll(); bool coalesceStackAccess(MachineInstr *MI, unsigned Reg); @@ -277,10 +278,10 @@ /// Determine if the value is defined by all reloads, so spilling isn't /// necessary - the value is already in the stack slot. /// -/// Find a defining instruction that may be a candidate for rematerialization. +/// Return a defining instruction that may be a candidate for rematerialization. /// -void InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI, - VNInfo *OrigVNI) { +MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI, + VNInfo *OrigVNI) { DEBUG(dbgs() << "Tracing value " << PrintReg(UseReg) << ':' << UseVNI->id << '@' << UseVNI->def << '\n'); SmallPtrSet Visited; @@ -365,7 +366,7 @@ // We have an 'original' def. Don't record trivial cases. if (VNI == UseVNI) { DEBUG(dbgs() << "Not a sibling copy.\n"); - return; + return MI; } // Potential remat candidate. @@ -385,10 +386,13 @@ << SVI.SpillVNI->id << '@' << SVI.SpillVNI->def << '\n'; }); SibValues.insert(std::make_pair(UseVNI, SVI)); + return SVI.DefMI; } /// analyzeSiblingValues - Trace values defined by sibling copies back to /// something that isn't a sibling copy. +/// +/// Keep track of values that may be rematerializable. void InlineSpiller::analyzeSiblingValues() { SibValues.clear(); @@ -403,11 +407,19 @@ for (LiveInterval::const_vni_iterator VI = LI.vni_begin(), VE = LI.vni_end(); VI != VE; ++VI) { VNInfo *VNI = *VI; - if (VNI->isUnused() || !(VNI->isPHIDef() || VNI->getCopy())) + if (VNI->isUnused()) continue; - VNInfo *OrigVNI = OrigLI.getVNInfoAt(VNI->def); - if (OrigVNI->def != VNI->def) - traceSiblingValue(Reg, VNI, OrigVNI); + MachineInstr *DefMI = 0; + // Check possible sibling copies. + if (VNI->isPHIDef() || VNI->getCopy()) { + VNInfo *OrigVNI = OrigLI.getVNInfoAt(VNI->def); + if (OrigVNI->def != VNI->def) + DefMI = traceSiblingValue(Reg, VNI, OrigVNI); + } + if (!DefMI && !VNI->isPHIDef()) + DefMI = LIS.getInstructionFromIndex(VNI->def); + if (DefMI) + Edit->checkRematerializable(VNI, DefMI, TII, AA); } } } @@ -520,12 +532,51 @@ } while (!WorkList.empty()); } + +//===----------------------------------------------------------------------===// +// Rematerialization +//===----------------------------------------------------------------------===// + +/// markValueUsed - Remember that VNI failed to rematerialize, so its defining +/// instruction cannot be eliminated. See through snippet copies +void InlineSpiller::markValueUsed(LiveInterval *LI, VNInfo *VNI) { + SmallVector, 8> WorkList; + WorkList.push_back(std::make_pair(LI, VNI)); + do { + tie(LI, VNI) = WorkList.pop_back_val(); + if (!UsedValues.insert(VNI)) + continue; + + if (VNI->isPHIDef()) { + MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def); + for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), + PE = MBB->pred_end(); PI != PE; ++PI) { + VNInfo *PVNI = LI->getVNInfoAt(LIS.getMBBEndIdx(*PI).getPrevSlot()); + if (PVNI) + WorkList.push_back(std::make_pair(LI, PVNI)); + } + continue; + } + + // Follow snippet copies. + MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def); + if (!SnippetCopies.count(MI)) + continue; + LiveInterval &SnipLI = LIS.getInterval(MI->getOperand(1).getReg()); + assert(isRegToSpill(SnipLI.reg) && "Unexpected register in copy"); + VNInfo *SnipVNI = SnipLI.getVNInfoAt(VNI->def.getUseIndex()); + assert(SnipVNI && "Snippet undefined before copy"); + WorkList.push_back(std::make_pair(&SnipLI, SnipVNI)); + } while (!WorkList.empty()); +} + /// reMaterializeFor - Attempt to rematerialize before MI instead of reloading. -bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) { +bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg, + MachineBasicBlock::iterator MI) { SlotIndex UseIdx = LIS.getInstructionIndex(MI).getUseIndex(); - VNInfo *OrigVNI = Edit->getParent().getVNInfoAt(UseIdx); + VNInfo *ParentVNI = VirtReg.getVNInfoAt(UseIdx); - if (!OrigVNI) { + if (!ParentVNI) { DEBUG(dbgs() << "\tadding flags: "); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); @@ -536,15 +587,16 @@ return true; } - // FIXME: Properly remat for snippets as well. - if (SnippetCopies.count(MI)) { - UsedValues.insert(OrigVNI); + if (SnippetCopies.count(MI)) return false; - } - LiveRangeEdit::Remat RM(OrigVNI); + // Use an OrigVNI from traceSiblingValue when ParentVNI is a sibling copy. + LiveRangeEdit::Remat RM(ParentVNI); + SibValueMap::const_iterator SibI = SibValues.find(ParentVNI); + if (SibI != SibValues.end()) + RM.OrigMI = SibI->second.DefMI; if (!Edit->canRematerializeAt(RM, UseIdx, false, LIS)) { - UsedValues.insert(OrigVNI); + markValueUsed(&VirtReg, ParentVNI); DEBUG(dbgs() << "\tcannot remat for " << UseIdx << '\t' << *MI); return false; } @@ -558,7 +610,7 @@ for (unsigned i = 0, e = Ops.size(); i != e; ++i) { MachineOperand &MO = MI->getOperand(Ops[i]); if (MO.isUse() ? MI->isRegTiedToDefOperand(Ops[i]) : MO.getSubReg()) { - UsedValues.insert(OrigVNI); + markValueUsed(&VirtReg, ParentVNI); DEBUG(dbgs() << "\tcannot remat tied reg: " << UseIdx << '\t' << *MI); return false; } @@ -606,58 +658,48 @@ /// reMaterializeAll - Try to rematerialize as many uses as possible, /// and trim the live ranges after. void InlineSpiller::reMaterializeAll() { - // Do a quick scan of the interval values to find if any are remattable. + // analyzeSiblingValues has already tested all relevant defining instructions. if (!Edit->anyRematerializable(LIS, TII, AA)) return; UsedValues.clear(); - // Try to remat before all uses of Edit->getReg(). + // Try to remat before all uses of snippets. bool anyRemat = false; - for (MachineRegisterInfo::use_nodbg_iterator - RI = MRI.use_nodbg_begin(Edit->getReg()); - MachineInstr *MI = RI.skipInstruction();) - anyRemat |= reMaterializeFor(MI); - + for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) { + unsigned Reg = RegsToSpill[i]; + LiveInterval &LI = LIS.getInterval(Reg); + for (MachineRegisterInfo::use_nodbg_iterator + RI = MRI.use_nodbg_begin(Reg); + MachineInstr *MI = RI.skipInstruction();) + anyRemat |= reMaterializeFor(LI, MI); + } if (!anyRemat) return; // Remove any values that were completely rematted. - bool anyRemoved = false; - for (LiveInterval::vni_iterator I = Edit->getParent().vni_begin(), - E = Edit->getParent().vni_end(); I != E; ++I) { - VNInfo *VNI = *I; - if (VNI->hasPHIKill() || !Edit->didRematerialize(VNI) || - UsedValues.count(VNI)) - continue; - MachineInstr *DefMI = LIS.getInstructionFromIndex(VNI->def); - DEBUG(dbgs() << "\tremoving dead def: " << VNI->def << '\t' << *DefMI); - LIS.RemoveMachineInstrFromMaps(DefMI); - VRM.RemoveMachineInstrFromMaps(DefMI); - DefMI->eraseFromParent(); - VNI->def = SlotIndex(); - anyRemoved = true; - } - - if (!anyRemoved) - return; - - // Removing values may cause debug uses where parent is not live. - for (MachineRegisterInfo::use_iterator RI = MRI.use_begin(Edit->getReg()); - MachineInstr *MI = RI.skipInstruction();) { - if (!MI->isDebugValue()) - continue; - // Try to preserve the debug value if parent is live immediately after it. - MachineBasicBlock::iterator NextMI = MI; - ++NextMI; - if (NextMI != MI->getParent()->end() && !LIS.isNotInMIMap(NextMI)) { - SlotIndex Idx = LIS.getInstructionIndex(NextMI); - VNInfo *VNI = Edit->getParent().getVNInfoAt(Idx); - if (VNI && (VNI->hasPHIKill() || UsedValues.count(VNI))) + for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) { + unsigned Reg = RegsToSpill[i]; + LiveInterval &LI = LIS.getInterval(Reg); + for (LiveInterval::vni_iterator I = LI.vni_begin(), E = LI.vni_end(); + I != E; ++I) { + VNInfo *VNI = *I; + if (VNI->isUnused() || VNI->isPHIDef() || VNI->hasPHIKill() || + UsedValues.count(VNI)) continue; + MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def); + MI->addRegisterDead(Reg, &TRI); + if (!MI->allDefsAreDead()) + continue; + DEBUG(dbgs() << "All defs dead: " << *MI); + DeadDefs.push_back(MI); + // Remove all Reg references so we don't insert spill code around MI. + for (MachineInstr::mop_iterator MOI = MI->operands_begin(), + MOE = MI->operands_end(); MOI != MOE ; ++MOI) + if (MOI->isReg() && MOI->getReg() == Reg) + MOI->setReg(0); + VNI->setIsUnused(true); } - DEBUG(dbgs() << "Removing debug info due to remat:" << "\t" << *MI); - MI->eraseFromParent(); } } Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp?rev=128449&r1=128448&r2=128449&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp Mon Mar 28 22:12:02 2011 @@ -34,6 +34,16 @@ return LI; } +void LiveRangeEdit::checkRematerializable(VNInfo *VNI, + const MachineInstr *DefMI, + const TargetInstrInfo &tii, + AliasAnalysis *aa) { + assert(DefMI && "Missing instruction"); + if (tii.isTriviallyReMaterializable(DefMI, aa)) + remattable_.insert(VNI); + scannedRemattable_ = true; +} + void LiveRangeEdit::scanRemattable(LiveIntervals &lis, const TargetInstrInfo &tii, AliasAnalysis *aa) { @@ -45,10 +55,8 @@ MachineInstr *DefMI = lis.getInstructionFromIndex(VNI->def); if (!DefMI) continue; - if (tii.isTriviallyReMaterializable(DefMI, aa)) - remattable_.insert(VNI); + checkRematerializable(VNI, DefMI, tii, aa); } - scannedRemattable_ = true; } bool LiveRangeEdit::anyRematerializable(LiveIntervals &lis, @@ -69,14 +77,11 @@ UseIdx = UseIdx.getUseIndex(); for (unsigned i = 0, e = OrigMI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = OrigMI->getOperand(i); - if (!MO.isReg() || !MO.getReg() || MO.getReg() == getReg()) + if (!MO.isReg() || !MO.getReg() || MO.isDef()) continue; // Reserved registers are OK. if (MO.isUndef() || !lis.hasInterval(MO.getReg())) continue; - // We don't want to move any defs. - if (MO.isDef()) - return false; // We cannot depend on virtual registers in uselessRegs_. if (uselessRegs_) for (unsigned ui = 0, ue = uselessRegs_->size(); ui != ue; ++ui) @@ -103,16 +108,22 @@ if (!remattable_.count(RM.ParentVNI)) return false; - // No defining instruction. - RM.OrigMI = lis.getInstructionFromIndex(RM.ParentVNI->def); - assert(RM.OrigMI && "Defining instruction for remattable value disappeared"); + // No defining instruction provided. + SlotIndex DefIdx; + if (RM.OrigMI) + DefIdx = lis.getInstructionIndex(RM.OrigMI); + else { + DefIdx = RM.ParentVNI->def; + RM.OrigMI = lis.getInstructionFromIndex(DefIdx); + assert(RM.OrigMI && "No defining instruction for remattable value"); + } // If only cheap remats were requested, bail out early. if (cheapAsAMove && !RM.OrigMI->getDesc().isAsCheapAsAMove()) return false; // Verify that all used registers are available with the same values. - if (!allUsesAvailableAt(RM.OrigMI, RM.ParentVNI->def, UseIdx, lis)) + if (!allUsesAvailableAt(RM.OrigMI, DefIdx, UseIdx, lis)) return false; return true; Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.h?rev=128449&r1=128448&r2=128449&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.h (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.h Mon Mar 28 22:12:02 2011 @@ -125,6 +125,11 @@ bool anyRematerializable(LiveIntervals&, const TargetInstrInfo&, AliasAnalysis*); + /// checkRematerializable - Manually add VNI to the list of rematerializable + /// values if DefMI may be rematerializable. + void checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI, + const TargetInstrInfo&, AliasAnalysis*); + /// Remat - Information needed to rematerialize at a specific location. struct Remat { VNInfo *ParentVNI; // parent_'s value at the remat location. From stoklund at 2pi.dk Mon Mar 28 22:12:04 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 29 Mar 2011 03:12:04 -0000 Subject: [llvm-commits] [llvm] r128450 - /llvm/trunk/lib/CodeGen/SplitKit.cpp Message-ID: <20110329031204.E6A4F2A6C12D@llvm.org> Author: stoklund Date: Mon Mar 28 22:12:04 2011 New Revision: 128450 URL: http://llvm.org/viewvc/llvm-project?rev=128450&view=rev Log: Handle the special case when all uses follow the last split point. Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=128450&r1=128449&r2=128450&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.cpp (original) +++ llvm/trunk/lib/CodeGen/SplitKit.cpp Mon Mar 28 22:12:04 2011 @@ -928,7 +928,8 @@ continue; openIntv(); - SlotIndex SegStart = enterIntvBefore(BI.FirstUse); + SlotIndex SegStart = enterIntvBefore(std::min(BI.FirstUse, + BI.LastSplitPoint)); if (!BI.LiveOut || BI.LastUse < BI.LastSplitPoint) { useIntv(SegStart, leaveIntvAfter(BI.LastUse)); } else { From isanbard at gmail.com Mon Mar 28 23:28:26 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 29 Mar 2011 04:28:26 -0000 Subject: [llvm-commits] [llvm] r128451 - /llvm/trunk/lib/VMCore/Dominators.cpp Message-ID: <20110329042826.C32AF2A6C12C@llvm.org> Author: void Date: Mon Mar 28 23:28:26 2011 New Revision: 128451 URL: http://llvm.org/viewvc/llvm-project?rev=128451&view=rev Log: Spruce up the error output. Modified: llvm/trunk/lib/VMCore/Dominators.cpp Modified: llvm/trunk/lib/VMCore/Dominators.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Dominators.cpp?rev=128451&r1=128450&r2=128451&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Dominators.cpp (original) +++ llvm/trunk/lib/VMCore/Dominators.cpp Mon Mar 28 23:28:26 2011 @@ -68,9 +68,8 @@ DominatorTree OtherDT; OtherDT.getBase().recalculate(F); if (compare(OtherDT)) { - errs() << "DominatorTree is not up to date! Computed:\n"; + errs() << "DominatorTree is not up to date!\nComputed:\n"; print(errs()); - errs() << "\nActual:\n"; OtherDT.print(errs()); abort(); From isanbard at gmail.com Tue Mar 29 00:15:49 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 29 Mar 2011 05:15:49 -0000 Subject: [llvm-commits] [llvm] r128452 - /llvm/trunk/lib/CodeGen/StackProtector.cpp Message-ID: <20110329051549.1A4B72A6C12C@llvm.org> Author: void Date: Tue Mar 29 00:15:48 2011 New Revision: 128452 URL: http://llvm.org/viewvc/llvm-project?rev=128452&view=rev Log: Don't try to add stack protector logic to a dead basic block. It messes up dominator information. Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=128452&r1=128451&r2=128452&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackProtector.cpp (original) +++ llvm/trunk/lib/CodeGen/StackProtector.cpp Tue Mar 29 00:15:48 2011 @@ -150,9 +150,11 @@ BasicBlock *FailBBDom = 0; // FailBB's dominator. AllocaInst *AI = 0; // Place on stack that stores the stack guard. Value *StackGuardVar = 0; // The stack guard variable. + BasicBlock &Entry = F->getEntryBlock(); for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { BasicBlock *BB = I++; + if (BB->getNumUses() == 0 && BB != &Entry) continue; ReturnInst *RI = dyn_cast(BB->getTerminator()); if (!RI) continue; @@ -178,7 +180,6 @@ StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); } - BasicBlock &Entry = F->getEntryBlock(); Instruction *InsPt = &Entry.front(); AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt); From zwarich at apple.com Tue Mar 29 00:19:52 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 29 Mar 2011 05:19:52 -0000 Subject: [llvm-commits] [llvm] r128453 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/inline-vector.ll test/Transforms/ScalarRepl/vector_promote.ll Message-ID: <20110329051952.CD38E2A6C12C@llvm.org> Author: zwarich Date: Tue Mar 29 00:19:52 2011 New Revision: 128453 URL: http://llvm.org/viewvc/llvm-project?rev=128453&view=rev Log: Do some simple copy propagation through integer loads and stores when promoting vector types. This helps a lot with inlined functions when using the ARM soft float ABI. Fixes . Added: llvm/trunk/test/Transforms/ScalarRepl/inline-vector.ll Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp llvm/trunk/test/Transforms/ScalarRepl/vector_promote.ll Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=128453&r1=128452&r2=128453&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Tue Mar 29 00:19:52 2011 @@ -252,7 +252,7 @@ private: bool CanConvertToScalar(Value *V, uint64_t Offset); - void MergeInType(const Type *In, uint64_t Offset); + void MergeInType(const Type *In, uint64_t Offset, bool IsLoadOrStore); bool MergeInVectorType(const VectorType *VInTy, uint64_t Offset); void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset); @@ -315,7 +315,8 @@ /// large) integer type with extract and insert operations where the loads /// and stores would mutate the memory. We mark this by setting VectorTy /// to VoidTy. -void ConvertToScalarInfo::MergeInType(const Type *In, uint64_t Offset) { +void ConvertToScalarInfo::MergeInType(const Type *In, uint64_t Offset, + bool IsLoadOrStore) { // If we already decided to turn this into a blob of integer memory, there is // nothing to be done. if (VectorTy && VectorTy->isVoidTy()) @@ -331,10 +332,14 @@ } else if (In->isFloatTy() || In->isDoubleTy() || (In->isIntegerTy() && In->getPrimitiveSizeInBits() >= 8 && isPowerOf2_32(In->getPrimitiveSizeInBits()))) { + // Full width accesses can be ignored, because they can always be turned + // into bitcasts. + unsigned EltSize = In->getPrimitiveSizeInBits()/8; + if (IsLoadOrStore && EltSize == AllocaSize) + return; // If we're accessing something that could be an element of a vector, see // if the implied vector agrees with what we already have and if Offset is // compatible with it. - unsigned EltSize = In->getPrimitiveSizeInBits()/8; if (Offset % EltSize == 0 && AllocaSize % EltSize == 0 && (VectorTy == 0 || cast(VectorTy)->getElementType() @@ -442,7 +447,7 @@ if (LI->getType()->isX86_MMXTy()) return false; HadNonMemTransferAccess = true; - MergeInType(LI->getType(), Offset); + MergeInType(LI->getType(), Offset, true); continue; } @@ -453,7 +458,7 @@ if (SI->getOperand(0)->getType()->isX86_MMXTy()) return false; HadNonMemTransferAccess = true; - MergeInType(SI->getOperand(0)->getType(), Offset); + MergeInType(SI->getOperand(0)->getType(), Offset, true); continue; } @@ -691,11 +696,11 @@ // If the result alloca is a vector type, this is either an element // access or a bitcast to another vector type of the same size. if (const VectorType *VTy = dyn_cast(FromVal->getType())) { - if (ToType->isVectorTy()) { - unsigned ToTypeSize = TD.getTypeAllocSize(ToType); - if (ToTypeSize == AllocaSize) - return Builder.CreateBitCast(FromVal, ToType, "tmp"); + unsigned ToTypeSize = TD.getTypeAllocSize(ToType); + if (ToTypeSize == AllocaSize) + return Builder.CreateBitCast(FromVal, ToType, "tmp"); + if (ToType->isVectorTy()) { assert(isPowerOf2_64(AllocaSize / ToTypeSize) && "Partial vector access of an alloca must have a power-of-2 size " "ratio."); Added: llvm/trunk/test/Transforms/ScalarRepl/inline-vector.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/inline-vector.ll?rev=128453&view=auto ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/inline-vector.ll (added) +++ llvm/trunk/test/Transforms/ScalarRepl/inline-vector.ll Tue Mar 29 00:19:52 2011 @@ -0,0 +1,53 @@ +; RUN: opt < %s -scalarrepl -S | FileCheck %s +; RUN: opt < %s -scalarrepl-ssa -S | FileCheck %s +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32" +target triple = "thumbv7-apple-darwin10.0.0" + +%struct.Vector4 = type { float, float, float, float } + at f.vector = internal constant %struct.Vector4 { float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00 }, align 16 + +; CHECK: define void @f +; CHECK-NOT: alloca +; CHECK: phi <4 x float> + +define void @f() nounwind ssp { +entry: + %i = alloca i32, align 4 + %vector = alloca %struct.Vector4, align 16 + %agg.tmp = alloca %struct.Vector4, align 16 + %tmp = bitcast %struct.Vector4* %vector to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %tmp, i8* bitcast (%struct.Vector4* @f.vector to i8*), i32 16, i32 16, i1 false) + br label %for.cond + +for.cond: ; preds = %for.body, %entry + %storemerge = phi i32 [ 0, %entry ], [ %inc, %for.body ] + store i32 %storemerge, i32* %i, align 4 + %cmp = icmp slt i32 %storemerge, 1000000 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %tmp2 = bitcast %struct.Vector4* %agg.tmp to i8* + %tmp3 = bitcast %struct.Vector4* %vector to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %tmp2, i8* %tmp3, i32 16, i32 16, i1 false) + %0 = bitcast %struct.Vector4* %agg.tmp to [2 x i64]* + %1 = load [2 x i64]* %0, align 16 + %tmp2.i = extractvalue [2 x i64] %1, 0 + %tmp3.i = zext i64 %tmp2.i to i128 + %tmp10.i = bitcast i128 %tmp3.i to <4 x float> + %sub.i.i = fsub <4 x float> , %tmp10.i + %2 = bitcast %struct.Vector4* %vector to <4 x float>* + store <4 x float> %sub.i.i, <4 x float>* %2, align 16 + %tmp4 = load i32* %i, align 4 + %inc = add nsw i32 %tmp4, 1 + br label %for.cond + +for.end: ; preds = %for.cond + %x = getelementptr inbounds %struct.Vector4* %vector, i32 0, i32 0 + %tmp5 = load float* %x, align 16 + %conv = fpext float %tmp5 to double + %call = call i32 (...)* @printf(double %conv) nounwind + ret void +} + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind +declare i32 @printf(...) Modified: llvm/trunk/test/Transforms/ScalarRepl/vector_promote.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/vector_promote.ll?rev=128453&r1=128452&r2=128453&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/vector_promote.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/vector_promote.ll Tue Mar 29 00:19:52 2011 @@ -94,7 +94,7 @@ %tmp = load i64* %P ret i64 %tmp ; CHECK: @test6 -; CHECK: bitcast <2 x float> %X to <1 x i64> +; CHECK: bitcast <2 x float> %X to i64 ; CHECK: ret i64 } From eli.friedman at gmail.com Tue Mar 29 00:35:21 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 28 Mar 2011 22:35:21 -0700 Subject: [llvm-commits] [llvm] r128452 - /llvm/trunk/lib/CodeGen/StackProtector.cpp In-Reply-To: <20110329051549.1A4B72A6C12C@llvm.org> References: <20110329051549.1A4B72A6C12C@llvm.org> Message-ID: On Mon, Mar 28, 2011 at 10:15 PM, Bill Wendling wrote: > Author: void > Date: Tue Mar 29 00:15:48 2011 > New Revision: 128452 > > URL: http://llvm.org/viewvc/llvm-project?rev=128452&view=rev > Log: > Don't try to add stack protector logic to a dead basic block. It messes up > dominator information. > > Modified: > ? ?llvm/trunk/lib/CodeGen/StackProtector.cpp > > Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=128452&r1=128451&r2=128452&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/StackProtector.cpp (original) > +++ llvm/trunk/lib/CodeGen/StackProtector.cpp Tue Mar 29 00:15:48 2011 > @@ -150,9 +150,11 @@ > ? BasicBlock *FailBBDom = 0; ? ?// FailBB's dominator. > ? AllocaInst *AI = 0; ? ? ? ? ? // Place on stack that stores the stack guard. > ? Value *StackGuardVar = 0; ?// The stack guard variable. > + ?BasicBlock &Entry = F->getEntryBlock(); > > ? for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { > ? ? BasicBlock *BB = I++; > + ? ?if (BB->getNumUses() == 0 && BB != &Entry) continue; That isn't a safe way to query whether a block is usable... if you have domtree, why not just use "DT->isReachableFromEntry(BB)"? -Eli From geek4civic at gmail.com Tue Mar 29 00:42:25 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Tue, 29 Mar 2011 14:42:25 +0900 Subject: [llvm-commits] [llvm] r128033 - in /llvm/trunk: CMakeLists.txt cmake/modules/AddLLVM.cmake In-Reply-To: <20110321225352.0E0BF2A6C12C@llvm.org> References: <20110321225352.0E0BF2A6C12C@llvm.org> Message-ID: On Tue, Mar 22, 2011 at 7:53 AM, Oscar Fuentes wrote: > Author: ofv > Date: Mon Mar 21 17:53:51 2011 > New Revision: 128033 > > URL: http://llvm.org/viewvc/llvm-project?rev=128033&view=rev > Log: > Removed workaround for unspecified build problem on MinGW. > > Tested that MinGW/MSYS builds fine without that. It makes linking ClangUnitTests unable on mingw, lack of system libs. Investigating. ...Takumi From baldrick at free.fr Tue Mar 29 01:26:30 2011 From: baldrick at free.fr (Duncan Sands) Date: Tue, 29 Mar 2011 06:26:30 -0000 Subject: [llvm-commits] [dragonegg] r128454 - in /dragonegg/trunk: Internals.h Types.cpp Message-ID: <20110329062630.3BC972A6C12C@llvm.org> Author: baldrick Date: Tue Mar 29 01:26:30 2011 New Revision: 128454 URL: http://llvm.org/viewvc/llvm-project?rev=128454&view=rev Log: Add a utility function for getting an array of units (aka bytes). Modified: dragonegg/trunk/Internals.h dragonegg/trunk/Types.cpp Modified: dragonegg/trunk/Internals.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Internals.h?rev=128454&r1=128453&r2=128454&view=diff ============================================================================== --- dragonegg/trunk/Internals.h (original) +++ dragonegg/trunk/Internals.h Tue Mar 29 01:26:30 2011 @@ -1,4 +1,4 @@ -//=---- Internals.h - Interface between the backend components --*- C++ -*---=// +//=---- Internals.h - Interface between the backend components ----*- C++ -*-=// // // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Chris Lattner, // Duncan Sands et al. @@ -227,6 +227,12 @@ Constant::getNullValue(Ty) : UndefValue::get(Ty); } +/// GetUnitType - Returns an integer one address unit wide if 'NumUnits' is 1; +/// otherwise returns an array of such integers with 'NumUnits' elements. For +/// example, on a machine which has 16 bit bytes returns an i16 or an array of +/// i16. +extern const Type *GetUnitType(LLVMContext &C, unsigned NumUnits = 1); + /// GetUnitPointerType - Returns an LLVM pointer type which points to memory one /// address unit wide. For example, on a machine which has 16 bit bytes returns /// an i16*. Modified: dragonegg/trunk/Types.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Types.cpp?rev=128454&r1=128453&r2=128454&view=diff ============================================================================== --- dragonegg/trunk/Types.cpp (original) +++ dragonegg/trunk/Types.cpp Tue Mar 29 01:26:30 2011 @@ -230,12 +230,23 @@ return Result; } +/// GetUnitType - Returns an integer one address unit wide if 'NumUnits' is 1; +/// otherwise returns an array of such integers with 'NumUnits' elements. For +/// example, on a machine which has 16 bit bytes returns an i16 or an array of +/// i16. +const Type *GetUnitType(LLVMContext &C, unsigned NumUnits) { + assert(!(BITS_PER_UNIT & 7) && "Unit size not a multiple of 8 bits!"); + const Type *UnitTy = IntegerType::get(C, BITS_PER_UNIT); + if (NumUnits == 1) + return UnitTy; + return ArrayType::get(UnitTy, NumUnits); +} + /// GetUnitPointerType - Returns an LLVM pointer type which points to memory one /// address unit wide. For example, on a machine which has 16 bit bytes returns /// an i16*. const Type *GetUnitPointerType(LLVMContext &C, unsigned AddrSpace) { - assert(!(BITS_PER_UNIT & 7) && "Unit size not a multiple of 8 bits!"); - return IntegerType::get(C, BITS_PER_UNIT)->getPointerTo(AddrSpace); + return GetUnitType(C)->getPointerTo(AddrSpace); } // isPassedByInvisibleReference - Return true if an argument of the specified From isanbard at gmail.com Tue Mar 29 02:06:40 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 29 Mar 2011 00:06:40 -0700 Subject: [llvm-commits] [llvm] r128452 - /llvm/trunk/lib/CodeGen/StackProtector.cpp In-Reply-To: References: <20110329051549.1A4B72A6C12C@llvm.org> Message-ID: On Mar 28, 2011, at 10:35 PM, Eli Friedman wrote: > On Mon, Mar 28, 2011 at 10:15 PM, Bill Wendling wrote: >> Author: void >> Date: Tue Mar 29 00:15:48 2011 >> New Revision: 128452 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=128452&view=rev >> Log: >> Don't try to add stack protector logic to a dead basic block. It messes up >> dominator information. >> >> Modified: >> llvm/trunk/lib/CodeGen/StackProtector.cpp >> >> Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=128452&r1=128451&r2=128452&view=diff >> ============================================================================== >> --- llvm/trunk/lib/CodeGen/StackProtector.cpp (original) >> +++ llvm/trunk/lib/CodeGen/StackProtector.cpp Tue Mar 29 00:15:48 2011 >> @@ -150,9 +150,11 @@ >> BasicBlock *FailBBDom = 0; // FailBB's dominator. >> AllocaInst *AI = 0; // Place on stack that stores the stack guard. >> Value *StackGuardVar = 0; // The stack guard variable. >> + BasicBlock &Entry = F->getEntryBlock(); >> >> for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { >> BasicBlock *BB = I++; >> + if (BB->getNumUses() == 0 && BB != &Entry) continue; > > That isn't a safe way to query whether a block is usable... if you > have domtree, why not just use "DT->isReachableFromEntry(BB)"? > It's probably rather slow. Why isn't this safe? -bw From zwarich at apple.com Tue Mar 29 02:24:28 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 29 Mar 2011 00:24:28 -0700 Subject: [llvm-commits] [llvm] r128452 - /llvm/trunk/lib/CodeGen/StackProtector.cpp In-Reply-To: References: <20110329051549.1A4B72A6C12C@llvm.org> Message-ID: <48678CD9-FAEB-45E5-A9BE-5C02B064E485@apple.com> On 2011-03-29, at 12:06 AM, Bill Wendling wrote: > On Mar 28, 2011, at 10:35 PM, Eli Friedman wrote: > >> On Mon, Mar 28, 2011 at 10:15 PM, Bill Wendling wrote: >> >> That isn't a safe way to query whether a block is usable... if you >> have domtree, why not just use "DT->isReachableFromEntry(BB)"? >> > It's probably rather slow. Why isn't this safe? You can have an unreachable loop. Using isReachableFromEntry() was fast the last time I checked. It just checks whether the BB has a DomTreeNode. Cameron -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110329/1c8c71d1/attachment.html From isanbard at gmail.com Tue Mar 29 02:28:52 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 29 Mar 2011 07:28:52 -0000 Subject: [llvm-commits] [llvm] r128455 - /llvm/trunk/lib/CodeGen/StackProtector.cpp Message-ID: <20110329072852.A25EA2A6C12C@llvm.org> Author: void Date: Tue Mar 29 02:28:52 2011 New Revision: 128455 URL: http://llvm.org/viewvc/llvm-project?rev=128455&view=rev Log: Rework the logic (and removing the bad check for an unreachable block) so that the FailBB dominator is correctly calculated. Believe it or not, there isn't a functionality change here. Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=128455&r1=128454&r2=128455&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackProtector.cpp (original) +++ llvm/trunk/lib/CodeGen/StackProtector.cpp Tue Mar 29 02:28:52 2011 @@ -150,12 +150,9 @@ BasicBlock *FailBBDom = 0; // FailBB's dominator. AllocaInst *AI = 0; // Place on stack that stores the stack guard. Value *StackGuardVar = 0; // The stack guard variable. - BasicBlock &Entry = F->getEntryBlock(); for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { BasicBlock *BB = I++; - if (BB->getNumUses() == 0 && BB != &Entry) continue; - ReturnInst *RI = dyn_cast(BB->getTerminator()); if (!RI) continue; @@ -180,6 +177,7 @@ StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); } + BasicBlock &Entry = F->getEntryBlock(); Instruction *InsPt = &Entry.front(); AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt); @@ -192,8 +190,6 @@ // Create the basic block to jump to when the guard check fails. FailBB = CreateFailBB(); - if (DT) - FailBBDom = DT->isReachableFromEntry(BB) ? BB : 0; } // For each block with a return instruction, convert this: @@ -219,11 +215,12 @@ // unreachable // Split the basic block before the return instruction. + bool BBIsReachable = (DT && DT->isReachableFromEntry(BB)); BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return"); - if (DT && DT->isReachableFromEntry(BB)) { + + if (BBIsReachable) { DT->addNewBlock(NewBB, BB); - if (FailBBDom) - FailBBDom = DT->findNearestCommonDominator(FailBBDom, BB); + FailBBDom = FailBBDom ? DT->findNearestCommonDominator(FailBBDom, BB) :BB; } // Remove default branch instruction to the new BB. From isanbard at gmail.com Tue Mar 29 02:34:33 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 29 Mar 2011 00:34:33 -0700 Subject: [llvm-commits] [llvm] r128452 - /llvm/trunk/lib/CodeGen/StackProtector.cpp In-Reply-To: <48678CD9-FAEB-45E5-A9BE-5C02B064E485@apple.com> References: <20110329051549.1A4B72A6C12C@llvm.org> <48678CD9-FAEB-45E5-A9BE-5C02B064E485@apple.com> Message-ID: <9CAFE139-2799-4153-9593-CD57F9A755BE@gmail.com> On Mar 29, 2011, at 12:24 AM, Cameron Zwarich wrote: > On 2011-03-29, at 12:06 AM, Bill Wendling wrote: > >> On Mar 28, 2011, at 10:35 PM, Eli Friedman wrote: >> >>> On Mon, Mar 28, 2011 at 10:15 PM, Bill Wendling wrote: >>> >>> That isn't a safe way to query whether a block is usable... if you >>> have domtree, why not just use "DT->isReachableFromEntry(BB)"? >>> >> It's probably rather slow. Why isn't this safe? > > You can have an unreachable loop. Using isReachableFromEntry() was fast the last time I checked. It just checks whether the BB has a DomTreeNode. > Ah! Okay. (Though it seems like the isReachableFromEntry could call a slower routine, or maybe I misread it...) Well, the logic was gross and didn't work anyway. So I reworked it. It should now work and be less gross. -bw From zwarich at apple.com Tue Mar 29 02:37:31 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 29 Mar 2011 00:37:31 -0700 Subject: [llvm-commits] [llvm] r128452 - /llvm/trunk/lib/CodeGen/StackProtector.cpp In-Reply-To: <9CAFE139-2799-4153-9593-CD57F9A755BE@gmail.com> References: <20110329051549.1A4B72A6C12C@llvm.org> <48678CD9-FAEB-45E5-A9BE-5C02B064E485@apple.com> <9CAFE139-2799-4153-9593-CD57F9A755BE@gmail.com> Message-ID: On 2011-03-29, at 12:34 AM, Bill Wendling wrote: > On Mar 29, 2011, at 12:24 AM, Cameron Zwarich wrote: > >> On 2011-03-29, at 12:06 AM, Bill Wendling wrote: >> >>> On Mar 28, 2011, at 10:35 PM, Eli Friedman wrote: >>> >>>> On Mon, Mar 28, 2011 at 10:15 PM, Bill Wendling wrote: >>>> >>>> That isn't a safe way to query whether a block is usable... if you >>>> have domtree, why not just use "DT->isReachableFromEntry(BB)"? >>>> >>> It's probably rather slow. Why isn't this safe? >> >> You can have an unreachable loop. Using isReachableFromEntry() was fast the last time I checked. It just checks whether the BB has a DomTreeNode. >> > Ah! Okay. (Though it seems like the isReachableFromEntry could call a slower routine, or maybe I misread it...) Well, the logic was gross and didn't work anyway. So I reworked it. It should now work and be less gross. Yeah, it does a dominance check even though it doesn't have to. Why not move the dominator check below here so that it is executed less often? ReturnInst *RI = dyn_cast(BB->getTerminator()); if (!RI) continue; Also, if you're going to just skip unreachable blocks, then you should probably remove the reachability checks later on in the function. Cameron From jay.foad at gmail.com Tue Mar 29 03:25:07 2011 From: jay.foad at gmail.com (Jay Foad) Date: Tue, 29 Mar 2011 09:25:07 +0100 Subject: [llvm-commits] [PATCH] remove PHINode::reserveOperandSpace() Message-ID: I noticed that: - All calls to PHINode::reserveOperandSpace() are on newly created PHINodes. - Most places that create a PHINode immediately call reserveOperandSpace(), to reserve space for the (known or expected) number of operands. - Those that don't, probably should. These patches enforce and simplify this by making the number of operands an argument to PHINode::Create(), and removing the reserveOperandSpace() method altogether. The patches are: 1. (Almost) always call reserveOperandSpace() on newly created PHINodes. 2. Add parameter to PHINode::Create() and remove PHINode::reserveOperandSpace(). Tested with "make check", LLVM and Clang. OK to apply? My motivation for working on this is that it removes one caller of PHINode::resizeOperands(), which in turn should allow some simplification of that function. Thanks, Jay. -------------- next part -------------- A non-text attachment was scrubbed... Name: call-reserveoperandspace.diff Type: text/x-patch Size: 25068 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110329/14298c20/attachment-0002.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: remove-reserveoperandspace.diff Type: text/x-patch Size: 50862 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110329/14298c20/attachment-0003.bin From baldrick at free.fr Tue Mar 29 05:46:17 2011 From: baldrick at free.fr (Duncan Sands) Date: Tue, 29 Mar 2011 10:46:17 -0000 Subject: [llvm-commits] [dragonegg] r128458 - in /dragonegg/trunk: Debug.h Trees.h Message-ID: <20110329104618.013892A6C12C@llvm.org> Author: baldrick Date: Tue Mar 29 05:46:17 2011 New Revision: 128458 URL: http://llvm.org/viewvc/llvm-project?rev=128458&view=rev Log: Comment formatting fix. Modified: dragonegg/trunk/Debug.h dragonegg/trunk/Trees.h Modified: dragonegg/trunk/Debug.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Debug.h?rev=128458&r1=128457&r2=128458&view=diff ============================================================================== --- dragonegg/trunk/Debug.h (original) +++ dragonegg/trunk/Debug.h Tue Mar 29 05:46:17 2011 @@ -1,4 +1,4 @@ -//===------ Debug.h - Interface for generating debug info ----*- C++ -*----===// +//===------ Debug.h - Interface for generating debug info -------*- C++ -*-===// // // Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Jim Laskey, Duncan Sands // et al. Modified: dragonegg/trunk/Trees.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Trees.h?rev=128458&r1=128457&r2=128458&view=diff ============================================================================== --- dragonegg/trunk/Trees.h (original) +++ dragonegg/trunk/Trees.h Tue Mar 29 05:46:17 2011 @@ -1,4 +1,4 @@ -//=---- Trees.h - Utility functions for working with GCC trees --*- C++ -*---=// +//=---- Trees.h - Utility functions for working with GCC trees ----*- C++ -*-=// // // Copyright (C) 2010, 2011 Duncan Sands. // From bob.wilson at apple.com Tue Mar 29 10:48:56 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 29 Mar 2011 08:48:56 -0700 Subject: [llvm-commits] [test-suite] r128436 - in /test-suite/trunk/SingleSource/UnitTests/ObjC++: Makefile property-reference-object.mm property-reference-object.reference_output In-Reply-To: <20110328234825.49B1F2A6C12C@llvm.org> References: <20110328234825.49B1F2A6C12C@llvm.org> Message-ID: <96505E08-9F1B-4DD2-93E5-927A4DFB6C2D@apple.com> You changed the makefile to expect the executable to fail, but it's failing to compile with llvm-gcc (http://llvm.org/perf/db_default/simple/nts/149/): /nightly/src/test-suite/SingleSource/UnitTests/ObjC++/property-reference-object.mm: In function ?~@~Xobjc_object* -[TNSObject init](TNSObject*, objc_selector*)?~@~Y: /nightly/src/test-suite/SingleSource/UnitTests/ObjC++/property-reference-object.mm:74: error: setting a C++ non-POD object value is not implemented - assign the value to a temporary and use the temporary. /nightly/src/test-suite/SingleSource/UnitTests/ObjC++/property-reference-object.mm:75: error: setting a C++ non-POD object value is not implemented - assign the value to a temporary and use the temporary. /nightly/src/test-suite/SingleSource/UnitTests/ObjC++/property-reference-object.mm:76: error: setting a C++ non-POD object value is not implemented - assign the value to a temporary and use the temporary. Can you change it to skip this test altogether for llvm-gcc? On Mar 28, 2011, at 4:48 PM, Fariborz Jahanian wrote: > Author: fjahanian > Date: Mon Mar 28 18:48:25 2011 > New Revision: 128436 > > URL: http://llvm.org/viewvc/llvm-project?rev=128436&view=rev > Log: > This is test for clang's // rdar://9070460. > I have modified the Makefile so test is skipped > for llvm-gcc (which does not fully support this feature). > > > Added: > test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm > test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output > Modified: > test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile > > Modified: test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/Makefile?rev=128436&r1=128435&r2=128436&view=diff > ============================================================================== > --- test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile (original) > +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile Mon Mar 28 18:48:25 2011 > @@ -6,4 +6,10 @@ > > LDFLAGS += -lstdc++ -lobjc -framework Foundation > PROGRAM_REQUIRED_TO_EXIT_OK := 1 > + > +# This is a known gcc / llvm-gcc miscompilation fixed in clang. > +ifdef CC_UNDER_TEST_IS_LLVM_GCC > +EXEC_XFAILS = property-reference-object > +endif > + > include $(LEVEL)/SingleSource/Makefile.singlesrc > > Added: test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/property-reference-object.mm?rev=128436&view=auto > ============================================================================== > --- test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm (added) > +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm Mon Mar 28 18:48:25 2011 > @@ -0,0 +1,105 @@ > +#import > + > +static int count; > +class Foo > +{ > + static int sNextId; > + int mId; > + int mRefId; > +public: > + Foo(const Foo& rhs){ > + mId = sNextId++; > + mRefId = rhs.mId; > + printf("Foo(%d,%d)\n", mId, mRefId); > + }; > + > + Foo() { > + mId = sNextId++; > + mRefId = mId; > + printf("Foo(%d,%d)\n", mId,mRefId); > + } > + ~Foo(){ > + printf("~Foo(%d, %d)\n", mId, mRefId); > + }; > + > + Foo& operator=(const Foo& rhs){ > + mRefId = rhs.mRefId; > + return *this; > + }; > + > + int Data() { return fData; }; > + > +private: > + int fData; > +}; > + > +int Foo::sNextId = 0; > + > + > +#pragma mark - > + > + > + at interface TNSObject : NSObject > +{ > + at private > + Foo _cppObjectNonAtomic; > + Foo _cppObjectAtomic; > + Foo _cppObjectDynamic; > +} > + > + at property (assign, readwrite, nonatomic) const Foo& cppObjectNonAtomic; > + at property (assign, readwrite) const Foo& cppObjectAtomic; > + at property (assign, readwrite, nonatomic) const Foo& cppObjectDynamic; > + at end > + > + > +#pragma mark - > + > + > + at implementation TNSObject > + > + at synthesize cppObjectNonAtomic = _cppObjectNonAtomic; > + at synthesize cppObjectAtomic = _cppObjectAtomic; > + at dynamic cppObjectDynamic; > + > +- (id)init > +{ > + self = [super init]; > + if (self) { > + > + // Add your subclass-specific initialization here. > + // If an error occurs here, send a [self release] message and return nil. > + > + Foo cppObject; > + self.cppObjectNonAtomic = cppObject; > + self.cppObjectAtomic = cppObject; > + self.cppObjectDynamic = cppObject; > + } > + return self; > +} > + > +- (const Foo&) cppObjectDynamic > +{ > + return _cppObjectDynamic; > +} > + > +- (void) setCppObjectDynamic: (const Foo&)cppObject > +{ > + _cppObjectDynamic = cppObject; > +} > + at end > + > + > +#pragma mark - > + > + > +int main (int argc, const char * argv[]) > +{ > + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; > + > + [[[TNSObject alloc] init] autorelease]; > + > + [pool drain]; > + return 0; > +} > + > > Added: test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/property-reference-object.reference_output?rev=128436&view=auto > ============================================================================== > --- test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output (added) > +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output Mon Mar 28 18:48:25 2011 > @@ -0,0 +1,14 @@ > +Foo(0,0) > +Foo(1,1) > +Foo(2,2) > +Foo(3,3) > +Foo(4,3) > +~Foo(4, 3) > +Foo(5,3) > +~Foo(5, 3) > +Foo(6,3) > +~Foo(6, 3) > +~Foo(3, 3) > +~Foo(2, 3) > +~Foo(1, 3) > +~Foo(0, 3) > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110329/753735de/attachment.html From fjahanian at apple.com Tue Mar 29 10:52:00 2011 From: fjahanian at apple.com (jahanian) Date: Tue, 29 Mar 2011 08:52:00 -0700 Subject: [llvm-commits] [test-suite] r128436 - in /test-suite/trunk/SingleSource/UnitTests/ObjC++: Makefile property-reference-object.mm property-reference-object.reference_output In-Reply-To: <96505E08-9F1B-4DD2-93E5-927A4DFB6C2D@apple.com> References: <20110328234825.49B1F2A6C12C@llvm.org> <96505E08-9F1B-4DD2-93E5-927A4DFB6C2D@apple.com> Message-ID: On Mar 29, 2011, at 8:48 AM, Bob Wilson wrote: > You changed the makefile to expect the executable to fail, but it's failing to compile with llvm-gcc (http://llvm.org/perf/db_default/simple/nts/149/): > > /nightly/src/test-suite/SingleSource/UnitTests/ObjC++/property-reference-object.mm: In function ?~@~Xobjc_object* -[TNSObject init](TNSObject*, objc_selector*)?~@~Y: > /nightly/src/test-suite/SingleSource/UnitTests/ObjC++/property-reference-object.mm:74: error: setting a C++ non-POD object value is not implemented - assign the value to a temporary and use the temporary. > /nightly/src/test-suite/SingleSource/UnitTests/ObjC++/property-reference-object.mm:75: error: setting a C++ non-POD object value is not implemented - assign the value to a temporary and use the temporary. > /nightly/src/test-suite/SingleSource/UnitTests/ObjC++/property-reference-object.mm:76: error: setting a C++ non-POD object value is not implemented - assign the value to a temporary and use the temporary. > > Can you change it to skip this test altogether for llvm-gcc? I though the change in Makefile does this. But how? Test has output. How do I make this clang specific when having an expected property-reference-object.reference_output (Do I need to add fake printf's for llvm-gcc) ? - fj > > On Mar 28, 2011, at 4:48 PM, Fariborz Jahanian wrote: > >> Author: fjahanian >> Date: Mon Mar 28 18:48:25 2011 >> New Revision: 128436 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=128436&view=rev >> Log: >> This is test for clang's // rdar://9070460. >> I have modified the Makefile so test is skipped >> for llvm-gcc (which does not fully support this feature). >> >> >> Added: >> test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm >> test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output >> Modified: >> test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile >> >> Modified: test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile >> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/Makefile?rev=128436&r1=128435&r2=128436&view=diff >> ============================================================================== >> --- test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile (original) >> +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile Mon Mar 28 18:48:25 2011 >> @@ -6,4 +6,10 @@ >> >> LDFLAGS += -lstdc++ -lobjc -framework Foundation >> PROGRAM_REQUIRED_TO_EXIT_OK := 1 >> + >> +# This is a known gcc / llvm-gcc miscompilation fixed in clang. >> +ifdef CC_UNDER_TEST_IS_LLVM_GCC >> +EXEC_XFAILS = property-reference-object >> +endif >> + >> include $(LEVEL)/SingleSource/Makefile.singlesrc >> >> Added: test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm >> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/property-reference-object.mm?rev=128436&view=auto >> ============================================================================== >> --- test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm (added) >> +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm Mon Mar 28 18:48:25 2011 >> @@ -0,0 +1,105 @@ >> +#import >> + >> +static int count; >> +class Foo >> +{ >> + static int sNextId; >> + int mId; >> + int mRefId; >> +public: >> + Foo(const Foo& rhs){ >> + mId = sNextId++; >> + mRefId = rhs.mId; >> + printf("Foo(%d,%d)\n", mId, mRefId); >> + }; >> + >> + Foo() { >> + mId = sNextId++; >> + mRefId = mId; >> + printf("Foo(%d,%d)\n", mId,mRefId); >> + } >> + ~Foo(){ >> + printf("~Foo(%d, %d)\n", mId, mRefId); >> + }; >> + >> + Foo& operator=(const Foo& rhs){ >> + mRefId = rhs.mRefId; >> + return *this; >> + }; >> + >> + int Data() { return fData; }; >> + >> +private: >> + int fData; >> +}; >> + >> +int Foo::sNextId = 0; >> + >> + >> +#pragma mark - >> + >> + >> + at interface TNSObject : NSObject >> +{ >> + at private >> + Foo _cppObjectNonAtomic; >> + Foo _cppObjectAtomic; >> + Foo _cppObjectDynamic; >> +} >> + >> + at property (assign, readwrite, nonatomic) const Foo& cppObjectNonAtomic; >> + at property (assign, readwrite) const Foo& cppObjectAtomic; >> + at property (assign, readwrite, nonatomic) const Foo& cppObjectDynamic; >> + at end >> + >> + >> +#pragma mark - >> + >> + >> + at implementation TNSObject >> + >> + at synthesize cppObjectNonAtomic = _cppObjectNonAtomic; >> + at synthesize cppObjectAtomic = _cppObjectAtomic; >> + at dynamic cppObjectDynamic; >> + >> +- (id)init >> +{ >> + self = [super init]; >> + if (self) { >> + >> + // Add your subclass-specific initialization here. >> + // If an error occurs here, send a [self release] message and return nil. >> + >> + Foo cppObject; >> + self.cppObjectNonAtomic = cppObject; >> + self.cppObjectAtomic = cppObject; >> + self.cppObjectDynamic = cppObject; >> + } >> + return self; >> +} >> + >> +- (const Foo&) cppObjectDynamic >> +{ >> + return _cppObjectDynamic; >> +} >> + >> +- (void) setCppObjectDynamic: (const Foo&)cppObject >> +{ >> + _cppObjectDynamic = cppObject; >> +} >> + at end >> + >> + >> +#pragma mark - >> + >> + >> +int main (int argc, const char * argv[]) >> +{ >> + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; >> + >> + [[[TNSObject alloc] init] autorelease]; >> + >> + [pool drain]; >> + return 0; >> +} >> + >> >> Added: test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output >> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/property-reference-object.reference_output?rev=128436&view=auto >> ============================================================================== >> --- test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output (added) >> +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output Mon Mar 28 18:48:25 2011 >> @@ -0,0 +1,14 @@ >> +Foo(0,0) >> +Foo(1,1) >> +Foo(2,2) >> +Foo(3,3) >> +Foo(4,3) >> +~Foo(4, 3) >> +Foo(5,3) >> +~Foo(5, 3) >> +Foo(6,3) >> +~Foo(6, 3) >> +~Foo(3, 3) >> +~Foo(2, 3) >> +~Foo(1, 3) >> +~Foo(0, 3) >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110329/1e7fbf1b/attachment.html From bob.wilson at apple.com Tue Mar 29 11:03:44 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 29 Mar 2011 16:03:44 -0000 Subject: [llvm-commits] [test-suite] r128460 - /test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile Message-ID: <20110329160344.413462A6C12C@llvm.org> Author: bwilson Date: Tue Mar 29 11:03:44 2011 New Revision: 128460 URL: http://llvm.org/viewvc/llvm-project?rev=128460&view=rev Log: Skip the property-reference-object test when using llvm-gcc. It won't even compile with llvm-gcc and only works with clang. Modified: test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile Modified: test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/Makefile?rev=128460&r1=128459&r2=128460&view=diff ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile (original) +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile Tue Mar 29 11:03:44 2011 @@ -9,7 +9,7 @@ # This is a known gcc / llvm-gcc miscompilation fixed in clang. ifdef CC_UNDER_TEST_IS_LLVM_GCC -EXEC_XFAILS = property-reference-object +PROGRAMS_TO_SKIP := property-reference-object endif include $(LEVEL)/SingleSource/Makefile.singlesrc From bob.wilson at apple.com Tue Mar 29 11:08:34 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 29 Mar 2011 09:08:34 -0700 Subject: [llvm-commits] [test-suite] r128436 - in /test-suite/trunk/SingleSource/UnitTests/ObjC++: Makefile property-reference-object.mm property-reference-object.reference_output In-Reply-To: References: <20110328234825.49B1F2A6C12C@llvm.org> <96505E08-9F1B-4DD2-93E5-927A4DFB6C2D@apple.com> Message-ID: <26FBB178-7BC4-4FB6-BBA2-F3542A0BE430@apple.com> I committed svn r128460 to try to fix it. It should just skip the test with llvm-gcc. On Mar 29, 2011, at 8:52 AM, jahanian wrote: > > On Mar 29, 2011, at 8:48 AM, Bob Wilson wrote: > >> You changed the makefile to expect the executable to fail, but it's failing to compile with llvm-gcc (http://llvm.org/perf/db_default/simple/nts/149/): >> >> /nightly/src/test-suite/SingleSource/UnitTests/ObjC++/property-reference-object.mm: In function ?~@~Xobjc_object* -[TNSObject init](TNSObject*, objc_selector*)?~@~Y: >> /nightly/src/test-suite/SingleSource/UnitTests/ObjC++/property-reference-object.mm:74: error: setting a C++ non-POD object value is not implemented - assign the value to a temporary and use the temporary. >> /nightly/src/test-suite/SingleSource/UnitTests/ObjC++/property-reference-object.mm:75: error: setting a C++ non-POD object value is not implemented - assign the value to a temporary and use the temporary. >> /nightly/src/test-suite/SingleSource/UnitTests/ObjC++/property-reference-object.mm:76: error: setting a C++ non-POD object value is not implemented - assign the value to a temporary and use the temporary. >> >> Can you change it to skip this test altogether for llvm-gcc? > > I though the change in Makefile does this. But how? Test has output. How do I make this clang specific when having an expected property-reference-object.reference_output > (Do I need to add fake printf's for llvm-gcc) ? > > - fj > >> >> On Mar 28, 2011, at 4:48 PM, Fariborz Jahanian wrote: >> >>> Author: fjahanian >>> Date: Mon Mar 28 18:48:25 2011 >>> New Revision: 128436 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=128436&view=rev >>> Log: >>> This is test for clang's // rdar://9070460. >>> I have modified the Makefile so test is skipped >>> for llvm-gcc (which does not fully support this feature). >>> >>> >>> Added: >>> test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm >>> test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output >>> Modified: >>> test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile >>> >>> Modified: test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile >>> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/Makefile?rev=128436&r1=128435&r2=128436&view=diff >>> ============================================================================== >>> --- test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile (original) >>> +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/Makefile Mon Mar 28 18:48:25 2011 >>> @@ -6,4 +6,10 @@ >>> >>> LDFLAGS += -lstdc++ -lobjc -framework Foundation >>> PROGRAM_REQUIRED_TO_EXIT_OK := 1 >>> + >>> +# This is a known gcc / llvm-gcc miscompilation fixed in clang. >>> +ifdef CC_UNDER_TEST_IS_LLVM_GCC >>> +EXEC_XFAILS = property-reference-object >>> +endif >>> + >>> include $(LEVEL)/SingleSource/Makefile.singlesrc >>> >>> Added: test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm >>> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/property-reference-object.mm?rev=128436&view=auto >>> ============================================================================== >>> --- test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm (added) >>> +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.mm Mon Mar 28 18:48:25 2011 >>> @@ -0,0 +1,105 @@ >>> +#import >>> + >>> +static int count; >>> +class Foo >>> +{ >>> + static int sNextId; >>> + int mId; >>> + int mRefId; >>> +public: >>> + Foo(const Foo& rhs){ >>> + mId = sNextId++; >>> + mRefId = rhs.mId; >>> + printf("Foo(%d,%d)\n", mId, mRefId); >>> + }; >>> + >>> + Foo() { >>> + mId = sNextId++; >>> + mRefId = mId; >>> + printf("Foo(%d,%d)\n", mId,mRefId); >>> + } >>> + ~Foo(){ >>> + printf("~Foo(%d, %d)\n", mId, mRefId); >>> + }; >>> + >>> + Foo& operator=(const Foo& rhs){ >>> + mRefId = rhs.mRefId; >>> + return *this; >>> + }; >>> + >>> + int Data() { return fData; }; >>> + >>> +private: >>> + int fData; >>> +}; >>> + >>> +int Foo::sNextId = 0; >>> + >>> + >>> +#pragma mark - >>> + >>> + >>> + at interface TNSObject : NSObject >>> +{ >>> + at private >>> + Foo _cppObjectNonAtomic; >>> + Foo _cppObjectAtomic; >>> + Foo _cppObjectDynamic; >>> +} >>> + >>> + at property (assign, readwrite, nonatomic) const Foo& cppObjectNonAtomic; >>> + at property (assign, readwrite) const Foo& cppObjectAtomic; >>> + at property (assign, readwrite, nonatomic) const Foo& cppObjectDynamic; >>> + at end >>> + >>> + >>> +#pragma mark - >>> + >>> + >>> + at implementation TNSObject >>> + >>> + at synthesize cppObjectNonAtomic = _cppObjectNonAtomic; >>> + at synthesize cppObjectAtomic = _cppObjectAtomic; >>> + at dynamic cppObjectDynamic; >>> + >>> +- (id)init >>> +{ >>> + self = [super init]; >>> + if (self) { >>> + >>> + // Add your subclass-specific initialization here. >>> + // If an error occurs here, send a [self release] message and return nil. >>> + >>> + Foo cppObject; >>> + self.cppObjectNonAtomic = cppObject; >>> + self.cppObjectAtomic = cppObject; >>> + self.cppObjectDynamic = cppObject; >>> + } >>> + return self; >>> +} >>> + >>> +- (const Foo&) cppObjectDynamic >>> +{ >>> + return _cppObjectDynamic; >>> +} >>> + >>> +- (void) setCppObjectDynamic: (const Foo&)cppObject >>> +{ >>> + _cppObjectDynamic = cppObject; >>> +} >>> + at end >>> + >>> + >>> +#pragma mark - >>> + >>> + >>> +int main (int argc, const char * argv[]) >>> +{ >>> + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; >>> + >>> + [[[TNSObject alloc] init] autorelease]; >>> + >>> + [pool drain]; >>> + return 0; >>> +} >>> + >>> >>> Added: test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output >>> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC%2B%2B/property-reference-object.reference_output?rev=128436&view=auto >>> ============================================================================== >>> --- test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output (added) >>> +++ test-suite/trunk/SingleSource/UnitTests/ObjC++/property-reference-object.reference_output Mon Mar 28 18:48:25 2011 >>> @@ -0,0 +1,14 @@ >>> +Foo(0,0) >>> +Foo(1,1) >>> +Foo(2,2) >>> +Foo(3,3) >>> +Foo(4,3) >>> +~Foo(4, 3) >>> +Foo(5,3) >>> +~Foo(5, 3) >>> +Foo(6,3) >>> +~Foo(6, 3) >>> +~Foo(3, 3) >>> +~Foo(2, 3) >>> +~Foo(1, 3) >>> +~Foo(0, 3) >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110329/53262c2b/attachment.html From fjahanian at apple.com Tue Mar 29 11:09:52 2011 From: fjahanian at apple.com (jahanian) Date: Tue, 29 Mar 2011 09:09:52 -0700 Subject: [llvm-commits] [test-suite] r128436 - in /test-suite/trunk/SingleSource/UnitTests/ObjC++: Makefile property-reference-object.mm property-reference-object.reference_output In-Reply-To: <26FBB178-7BC4-4FB6-BBA2-F3542A0BE430@apple.com> References: <20110328234825.49B1F2A6C12C@llvm.org> <96505E08-9F1B-4DD2-93E5-927A4DFB6C2D@apple.com> <26FBB178-7BC4-4FB6-BBA2-F3542A0BE430@apple.com> Message-ID: On Mar 29, 2011, at 9:08 AM, Bob Wilson wrote: > I committed svn r128460 to try to fix it. It should just skip the test with llvm-gcc. Great, Thanks. - Fariborz > > On Mar 29, 2011, at 8:52 AM, jahanian wrote: > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110329/55cbebab/attachment.html From resistor at mac.com Tue Mar 29 11:45:54 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 29 Mar 2011 16:45:54 -0000 Subject: [llvm-commits] [llvm] r128461 - in /llvm/trunk: lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMExpandPseudoInsts.cpp lib/Target/ARM/ARMInstrNEON.td lib/Target/ARM/ARMInstrVFP.td lib/Target/ARM/ARMLoadStoreOptimizer.cpp lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp test/MC/Disassembler/ARM/arm-tests.txt test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt Message-ID: <20110329164554.3DF472A6C12D@llvm.org> Author: resistor Date: Tue Mar 29 11:45:53 2011 New Revision: 128461 URL: http://llvm.org/viewvc/llvm-project?rev=128461&view=rev Log: Get rid of the non-writeback versions VLDMDB and VSTMDB, which don't actually exist. Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp llvm/trunk/lib/Target/ARM/ARMInstrNEON.td llvm/trunk/lib/Target/ARM/ARMInstrVFP.td llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=128461&r1=128460&r2=128461&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Tue Mar 29 11:45:53 2011 @@ -1789,9 +1789,7 @@ llvm_unreachable("Unexpected multi-uops instruction!"); break; case ARM::VLDMQIA: - case ARM::VLDMQDB: case ARM::VSTMQIA: - case ARM::VSTMQDB: return 2; // The number of uOps for load / store multiple are determined by the number @@ -1805,19 +1803,15 @@ // is not 64-bit aligned, then AGU would take an extra cycle. For VFP / NEON // load / store multiple, the formula is (#reg / 2) + (#reg % 2) + 1. case ARM::VLDMDIA: - case ARM::VLDMDDB: case ARM::VLDMDIA_UPD: case ARM::VLDMDDB_UPD: case ARM::VLDMSIA: - case ARM::VLDMSDB: case ARM::VLDMSIA_UPD: case ARM::VLDMSDB_UPD: case ARM::VSTMDIA: - case ARM::VSTMDDB: case ARM::VSTMDIA_UPD: case ARM::VSTMDDB_UPD: case ARM::VSTMSIA: - case ARM::VSTMSDB: case ARM::VSTMSIA_UPD: case ARM::VSTMSDB_UPD: { unsigned NumRegs = MI->getNumOperands() - Desc.getNumOperands(); @@ -1907,7 +1901,6 @@ switch (DefTID.getOpcode()) { default: break; case ARM::VLDMSIA: - case ARM::VLDMSDB: case ARM::VLDMSIA_UPD: case ARM::VLDMSDB_UPD: isSLoad = true; @@ -1983,7 +1976,6 @@ switch (UseTID.getOpcode()) { default: break; case ARM::VSTMSIA: - case ARM::VSTMSDB: case ARM::VSTMSIA_UPD: case ARM::VSTMSDB_UPD: isSStore = true; @@ -2054,11 +2046,9 @@ break; case ARM::VLDMDIA: - case ARM::VLDMDDB: case ARM::VLDMDIA_UPD: case ARM::VLDMDDB_UPD: case ARM::VLDMSIA: - case ARM::VLDMSDB: case ARM::VLDMSIA_UPD: case ARM::VLDMSDB_UPD: DefCycle = getVLDMDefCycle(ItinData, DefTID, DefClass, DefIdx, DefAlign); @@ -2097,11 +2087,9 @@ break; case ARM::VSTMDIA: - case ARM::VSTMDDB: case ARM::VSTMDIA_UPD: case ARM::VSTMDDB_UPD: case ARM::VSTMSIA: - case ARM::VSTMSDB: case ARM::VSTMSIA_UPD: case ARM::VSTMSDB_UPD: UseCycle = getVSTMUseCycle(ItinData, UseTID, UseClass, UseIdx, UseAlign); @@ -2312,9 +2300,7 @@ default: return ItinData->getStageLatency(get(Opcode).getSchedClass()); case ARM::VLDMQIA: - case ARM::VLDMQDB: case ARM::VSTMQIA: - case ARM::VSTMQDB: return 2; } } Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=128461&r1=128460&r2=128461&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Tue Mar 29 11:45:53 2011 @@ -967,9 +967,8 @@ return true; } - case ARM::VLDMQIA: - case ARM::VLDMQDB: { - unsigned NewOpc = (Opcode == ARM::VLDMQIA) ? ARM::VLDMDIA : ARM::VLDMDDB; + case ARM::VLDMQIA: { + unsigned NewOpc = ARM::VLDMDIA; MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc)); unsigned OpIdx = 0; @@ -998,9 +997,8 @@ return true; } - case ARM::VSTMQIA: - case ARM::VSTMQDB: { - unsigned NewOpc = (Opcode == ARM::VSTMQIA) ? ARM::VSTMDIA : ARM::VSTMDDB; + case ARM::VSTMQIA: { + unsigned NewOpc = ARM::VSTMDIA; MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc)); unsigned OpIdx = 0; Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=128461&r1=128460&r2=128461&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Tue Mar 29 11:45:53 2011 @@ -146,10 +146,6 @@ : PseudoVFPLdStM<(outs QPR:$dst), (ins GPR:$Rn), IIC_fpLoad_m, "", [(set QPR:$dst, (v2f64 (load GPR:$Rn)))]>; -def VLDMQDB - : PseudoVFPLdStM<(outs QPR:$dst), (ins GPR:$Rn), - IIC_fpLoad_m, "", - [(set QPR:$dst, (v2f64 (load GPR:$Rn)))]>; // Use VSTM to store a Q register as a D register pair. // This is a pseudo instruction that is expanded to VSTMD after reg alloc. @@ -157,10 +153,6 @@ : PseudoVFPLdStM<(outs), (ins QPR:$src, GPR:$Rn), IIC_fpStore_m, "", [(store (v2f64 QPR:$src), GPR:$Rn)]>; -def VSTMQDB - : PseudoVFPLdStM<(outs), (ins QPR:$src, GPR:$Rn), - IIC_fpStore_m, "", - [(store (v2f64 QPR:$src), GPR:$Rn)]>; // Classes for VLD* pseudo-instructions with multi-register operands. // These are expanded to real instructions after register allocation. Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=128461&r1=128460&r2=128461&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Tue Mar 29 11:45:53 2011 @@ -101,14 +101,6 @@ let Inst{21} = 1; // Writeback let Inst{20} = L_bit; } - def DDB : - AXDI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), - IndexModeNone, itin, - !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> { - let Inst{24-23} = 0b10; // Decrement Before - let Inst{21} = 0; // No writeback - let Inst{20} = L_bit; - } def DDB_UPD : AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), IndexModeUpd, itin_upd, @@ -143,18 +135,6 @@ // VFP pipelines. let D = VFPNeonDomain; } - def SDB : - AXSI4<(outs), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops), - IndexModeNone, itin, - !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> { - let Inst{24-23} = 0b10; // Decrement Before - let Inst{21} = 0; // No writeback - let Inst{20} = L_bit; - - // Some single precision VFP instructions may be executed on both NEON and - // VFP pipelines. - let D = VFPNeonDomain; - } def SDB_UPD : AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops), IndexModeUpd, itin_upd, Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=128461&r1=128460&r2=128461&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Tue Mar 29 11:45:53 2011 @@ -79,7 +79,7 @@ unsigned Position; MachineBasicBlock::iterator MBBI; bool Merged; - MemOpQueueEntry(int o, unsigned r, bool k, unsigned p, + MemOpQueueEntry(int o, unsigned r, bool k, unsigned p, MachineBasicBlock::iterator i) : Offset(o), Reg(r), isKill(k), Position(p), MBBI(i), Merged(false) {} }; @@ -174,7 +174,7 @@ switch (Mode) { default: llvm_unreachable("Unhandled submode!"); case ARM_AM::ia: return ARM::VLDMSIA; - case ARM_AM::db: return ARM::VLDMSDB; + case ARM_AM::db: return 0; // Only VLDMSDB_UPD exists. } break; case ARM::VSTRS: @@ -182,7 +182,7 @@ switch (Mode) { default: llvm_unreachable("Unhandled submode!"); case ARM_AM::ia: return ARM::VSTMSIA; - case ARM_AM::db: return ARM::VSTMSDB; + case ARM_AM::db: return 0; // Only VSTMSDB_UPD exists. } break; case ARM::VLDRD: @@ -190,7 +190,7 @@ switch (Mode) { default: llvm_unreachable("Unhandled submode!"); case ARM_AM::ia: return ARM::VLDMDIA; - case ARM_AM::db: return ARM::VLDMDDB; + case ARM_AM::db: return 0; // Only VLDMDDB_UPD exists. } break; case ARM::VSTRD: @@ -198,7 +198,7 @@ switch (Mode) { default: llvm_unreachable("Unhandled submode!"); case ARM_AM::ia: return ARM::VSTMDIA; - case ARM_AM::db: return ARM::VSTMDDB; + case ARM_AM::db: return 0; // Only VSTMDDB_UPD exists. } break; } @@ -246,13 +246,9 @@ case ARM::t2LDMDB_UPD: case ARM::t2STMDB: case ARM::t2STMDB_UPD: - case ARM::VLDMSDB: case ARM::VLDMSDB_UPD: - case ARM::VSTMSDB: case ARM::VSTMSDB_UPD: - case ARM::VLDMDDB: case ARM::VLDMDDB_UPD: - case ARM::VSTMDDB: case ARM::VSTMDDB_UPD: return ARM_AM::db; @@ -567,14 +563,10 @@ case ARM::t2STMIA: case ARM::t2STMDB: case ARM::VLDMSIA: - case ARM::VLDMSDB: case ARM::VSTMSIA: - case ARM::VSTMSDB: return (MI->getNumOperands() - MI->getDesc().getNumOperands() + 1) * 4; case ARM::VLDMDIA: - case ARM::VLDMDDB: case ARM::VSTMDIA: - case ARM::VSTMDDB: return (MI->getNumOperands() - MI->getDesc().getNumOperands() + 1) * 8; } } @@ -624,7 +616,6 @@ } break; case ARM::VLDMSIA: - case ARM::VLDMSDB: switch (Mode) { default: llvm_unreachable("Unhandled submode!"); case ARM_AM::ia: return ARM::VLDMSIA_UPD; @@ -632,7 +623,6 @@ } break; case ARM::VLDMDIA: - case ARM::VLDMDDB: switch (Mode) { default: llvm_unreachable("Unhandled submode!"); case ARM_AM::ia: return ARM::VLDMDIA_UPD; @@ -640,7 +630,6 @@ } break; case ARM::VSTMSIA: - case ARM::VSTMSDB: switch (Mode) { default: llvm_unreachable("Unhandled submode!"); case ARM_AM::ia: return ARM::VSTMSIA_UPD; @@ -648,7 +637,6 @@ } break; case ARM::VSTMDIA: - case ARM::VSTMDDB: switch (Mode) { default: llvm_unreachable("Unhandled submode!"); case ARM_AM::ia: return ARM::VSTMDIA_UPD; Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128461&r1=128460&r2=128461&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Tue Mar 29 11:45:53 2011 @@ -1123,7 +1123,7 @@ case ARM::LDRD: case ARM::LDRD_PRE: case ARM::LDRD_POST: case ARM::STRD: case ARM::STRD_PRE: case ARM::STRD_POST: return true; - } + } } static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn, @@ -1610,7 +1610,7 @@ // A8.6.295 vcvt (floating-point <-> integer) // Int to FP: VSITOD, VSITOS, VUITOD, VUITOS // FP to Int: VTOSI[Z|R]D, VTOSI[Z|R]S, VTOUI[Z|R]D, VTOUI[Z|R]S -// +// // A8.6.297 vcvt (floating-point and fixed-point) // Dd|Sd Dd|Sd(TIED_TO) #fbits(= 16|32 - UInt(imm4:i)) static bool DisassembleVFPConv1Frm(MCInst &MI, unsigned Opcode, uint32_t insn, @@ -1832,9 +1832,9 @@ OpIdx += 3; - bool isSPVFP = (Opcode == ARM::VLDMSIA || Opcode == ARM::VLDMSDB || + bool isSPVFP = (Opcode == ARM::VLDMSIA || Opcode == ARM::VLDMSIA_UPD || Opcode == ARM::VLDMSDB_UPD || - Opcode == ARM::VSTMSIA || Opcode == ARM::VSTMSDB || + Opcode == ARM::VSTMSIA || Opcode == ARM::VSTMSIA_UPD || Opcode == ARM::VSTMSDB_UPD); unsigned RegClassID = isSPVFP ? ARM::SPRRegClassID : ARM::DPRRegClassID; @@ -1848,7 +1848,7 @@ // Apply some sanity checks before proceeding. if (Regs == 0 || (RegD + Regs) > 32 || (!isSPVFP && Regs > 16)) return false; - + for (unsigned i = 0; i < Regs; ++i) { MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassID, RegD + i))); @@ -2286,15 +2286,15 @@ // n == 2 && type == 0b1001 -> DblSpaced = true if (Name.startswith("VST2") || Name.startswith("VLD2")) DblSpaced = slice(insn, 11, 8) == 9; - + // n == 3 && type == 0b0101 -> DblSpaced = true if (Name.startswith("VST3") || Name.startswith("VLD3")) DblSpaced = slice(insn, 11, 8) == 5; - + // n == 4 && type == 0b0001 -> DblSpaced = true if (Name.startswith("VST4") || Name.startswith("VLD4")) DblSpaced = slice(insn, 11, 8) == 1; - + } return DisassembleNLdSt0(MI, Opcode, insn, NumOps, NumOpsAdded, slice(insn, 21, 21) == 0, DblSpaced, B); @@ -2391,7 +2391,7 @@ // // Vector Move Long: // Qd Dm -// +// // Vector Move Narrow: // Dd Qm // @@ -2533,7 +2533,7 @@ assert(OpInfo[OpIdx].RegClass < 0 && "Imm operand expected"); // Add the imm operand. - + // VSHLL has maximum shift count as the imm, inferred from its size. unsigned Imm; switch (Opcode) { @@ -2646,7 +2646,7 @@ // N3RegFrm. if (Opcode == ARM::VMOVDneon || Opcode == ARM::VMOVQ) return true; - + // Dm = Inst{5:3-0} => NEON Rm // or // Dm is restricted to D0-D7 if size is 16, D0-D15 otherwise @@ -3183,7 +3183,7 @@ return false; } - + /// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process /// the possible Predicate and SBitModifier, to build the remaining MCOperand /// constituents. Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=128461&r1=128460&r2=128461&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Tue Mar 29 11:45:53 2011 @@ -173,9 +173,6 @@ # CHECK: vcmpe.f64 d8, #0 0xc0 0x8b 0xb5 0xee -# CHECK: vldmdb r2, {s7, s8, s9, s10, s11} -0x05 0x3a 0x52 0xed - # CHECK: strtvc r5, [r3], r0, lsr #20 0x30 0x5a 0xa3 0x76 Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt?rev=128461&r1=128460&r2=128461&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt Tue Mar 29 11:45:53 2011 @@ -1,4 +1,5 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} +# XFAIL: * # core registers out of range -0xa5 0xba 0x52 0xed +0xa5 0xba 0xd2 0xed From rjmccall at apple.com Tue Mar 29 12:11:07 2011 From: rjmccall at apple.com (John McCall) Date: Tue, 29 Mar 2011 10:11:07 -0700 Subject: [llvm-commits] [cfe-commits] [PATCH] remove PHINode::reserveOperandSpace() In-Reply-To: References: Message-ID: On Mar 29, 2011, at 1:25 AM, Jay Foad wrote: > I noticed that: > > - All calls to PHINode::reserveOperandSpace() are on newly created PHINodes. > - Most places that create a PHINode immediately call > reserveOperandSpace(), to reserve space for the (known or expected) > number of operands. > - Those that don't, probably should. Good idea! Thanks for doing this. The Clang parts look fine to me. John. From rjmccall at apple.com Tue Mar 29 12:12:34 2011 From: rjmccall at apple.com (John McCall) Date: Tue, 29 Mar 2011 10:12:34 -0700 Subject: [llvm-commits] [cfe-commits] [PATCH] remove PHINode::reserveOperandSpace() In-Reply-To: References: Message-ID: On Mar 29, 2011, at 1:25 AM, Jay Foad wrote: > I noticed that: > > - All calls to PHINode::reserveOperandSpace() are on newly created PHINodes. > - Most places that create a PHINode immediately call > reserveOperandSpace(), to reserve space for the (known or expected) > number of operands. > - Those that don't, probably should. Good idea! Thanks for doing this. The Clang parts look fine to me. John. From isanbard at gmail.com Tue Mar 29 12:12:55 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 29 Mar 2011 17:12:55 -0000 Subject: [llvm-commits] [llvm] r128465 - /llvm/trunk/lib/CodeGen/StackProtector.cpp Message-ID: <20110329171255.D2C272A6C12C@llvm.org> Author: void Date: Tue Mar 29 12:12:55 2011 New Revision: 128465 URL: http://llvm.org/viewvc/llvm-project?rev=128465&view=rev Log: Inline check that's used only once. Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=128465&r1=128464&r2=128465&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackProtector.cpp (original) +++ llvm/trunk/lib/CodeGen/StackProtector.cpp Tue Mar 29 12:12:55 2011 @@ -215,10 +215,9 @@ // unreachable // Split the basic block before the return instruction. - bool BBIsReachable = (DT && DT->isReachableFromEntry(BB)); BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return"); - if (BBIsReachable) { + if (DT && DT->isReachableFromEntry(BB)) { DT->addNewBlock(NewBB, BB); FailBBDom = FailBBDom ? DT->findNearestCommonDominator(FailBBDom, BB) :BB; } From ofv at wanadoo.es Tue Mar 29 12:19:21 2011 From: ofv at wanadoo.es (=?utf-8?Q?=C3=93scar_Fuentes?=) Date: Tue, 29 Mar 2011 19:19:21 +0200 Subject: [llvm-commits] [llvm] r128033 - in /llvm/trunk: CMakeLists.txt cmake/modules/AddLLVM.cmake In-Reply-To: (NAKAMURA Takumi's message of "Tue, 29 Mar 2011 14:42:25 +0900") References: <20110321225352.0E0BF2A6C12C@llvm.org> Message-ID: <87hbalx2sm.fsf@wanadoo.es> Hello Takumi. NAKAMURA Takumi writes: >> Author: ofv >> Date: Mon Mar 21 17:53:51 2011 >> New Revision: 128033 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=128033&view=rev >> Log: >> Removed workaround for unspecified build problem on MinGW. >> >> Tested that MinGW/MSYS builds fine without that. > > It makes linking ClangUnitTests unable on mingw, lack of system libs. > Investigating. I know where the problem is. A fix is on the pipe. From dpatel at apple.com Tue Mar 29 12:27:08 2011 From: dpatel at apple.com (Devang Patel) Date: Tue, 29 Mar 2011 17:27:08 -0000 Subject: [llvm-commits] [llvm] r128466 - /llvm/trunk/docs/SourceLevelDebugging.html Message-ID: <20110329172709.0111D2A6C12C@llvm.org> Author: dpatel Date: Tue Mar 29 12:27:08 2011 New Revision: 128466 URL: http://llvm.org/viewvc/llvm-project?rev=128466&view=rev Log: Document llvm.dbg.sp, llvm.dbg.gv and llvm.dbg.enum Modified: llvm/trunk/docs/SourceLevelDebugging.html Modified: llvm/trunk/docs/SourceLevelDebugging.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/SourceLevelDebugging.html?rev=128466&r1=128465&r2=128466&view=diff ============================================================================== --- llvm/trunk/docs/SourceLevelDebugging.html (original) +++ llvm/trunk/docs/SourceLevelDebugging.html Tue Mar 29 12:27:08 2011 @@ -407,7 +407,8 @@

    These descriptors provide debug information about globals variables. The -provide details such as name, type and where the variable is defined.

    +provide details such as name, type and where the variable is defined. All +global variables are collected by named metadata !llvm.dbg.gv.

    @@ -446,7 +447,10 @@

    These descriptors provide debug information about functions, methods and subprograms. They provide details such as name, return types and the source - location where the subprogram is defined.

    + location where the subprogram is defined. + All subprogram descriptors are collected by a named metadata + !llvm.dbg.sp. +

    @@ -646,7 +650,8 @@
    + the definition of enumeration value for the set. All enumeration type + descriptors are collected by named metadata !llvm.dbg.enum.

    The members of structure (tag = DW_TAG_structure_type) or union (tag = DW_TAG_union_type) types are any one of From evan.cheng at apple.com Tue Mar 29 12:42:58 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 29 Mar 2011 10:42:58 -0700 Subject: [llvm-commits] [llvm] r128461 - in /llvm/trunk: lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMExpandPseudoInsts.cpp lib/Target/ARM/ARMInstrNEON.td lib/Target/ARM/ARMInstrVFP.td lib/Target/ARM/ARMLoadStoreOptimizer.cpp lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp test/MC/Disassembler/ARM/arm-tests.txt test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt In-Reply-To: <20110329164554.3DF472A6C12D@llvm.org> References: <20110329164554.3DF472A6C12D@llvm.org> Message-ID: <6ABFDC60-ED76-4416-A5F3-0406D35C06E3@apple.com> Hi Owen, Does this patch work? Opcode = getLoadStoreMultipleOpcode(Opcode, Mode); MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(Opcode)) .addReg(Base, getKillRegState(BaseKill)) .addImm(Pred).addReg(PredReg); If Mode is ARM_AM::db, getLoadStoreMultipleOpcode() can return 0 and this would not work right? Evan On Mar 29, 2011, at 9:45 AM, Owen Anderson wrote: > Author: resistor > Date: Tue Mar 29 11:45:53 2011 > New Revision: 128461 > > URL: http://llvm.org/viewvc/llvm-project?rev=128461&view=rev > Log: > Get rid of the non-writeback versions VLDMDB and VSTMDB, which don't actually exist. > > Modified: > llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp > llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp > llvm/trunk/lib/Target/ARM/ARMInstrNEON.td > llvm/trunk/lib/Target/ARM/ARMInstrVFP.td > llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp > llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp > llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt > llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=128461&r1=128460&r2=128461&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Tue Mar 29 11:45:53 2011 > @@ -1789,9 +1789,7 @@ > llvm_unreachable("Unexpected multi-uops instruction!"); > break; > case ARM::VLDMQIA: > - case ARM::VLDMQDB: > case ARM::VSTMQIA: > - case ARM::VSTMQDB: > return 2; > > // The number of uOps for load / store multiple are determined by the number > @@ -1805,19 +1803,15 @@ > // is not 64-bit aligned, then AGU would take an extra cycle. For VFP / NEON > // load / store multiple, the formula is (#reg / 2) + (#reg % 2) + 1. > case ARM::VLDMDIA: > - case ARM::VLDMDDB: > case ARM::VLDMDIA_UPD: > case ARM::VLDMDDB_UPD: > case ARM::VLDMSIA: > - case ARM::VLDMSDB: > case ARM::VLDMSIA_UPD: > case ARM::VLDMSDB_UPD: > case ARM::VSTMDIA: > - case ARM::VSTMDDB: > case ARM::VSTMDIA_UPD: > case ARM::VSTMDDB_UPD: > case ARM::VSTMSIA: > - case ARM::VSTMSDB: > case ARM::VSTMSIA_UPD: > case ARM::VSTMSDB_UPD: { > unsigned NumRegs = MI->getNumOperands() - Desc.getNumOperands(); > @@ -1907,7 +1901,6 @@ > switch (DefTID.getOpcode()) { > default: break; > case ARM::VLDMSIA: > - case ARM::VLDMSDB: > case ARM::VLDMSIA_UPD: > case ARM::VLDMSDB_UPD: > isSLoad = true; > @@ -1983,7 +1976,6 @@ > switch (UseTID.getOpcode()) { > default: break; > case ARM::VSTMSIA: > - case ARM::VSTMSDB: > case ARM::VSTMSIA_UPD: > case ARM::VSTMSDB_UPD: > isSStore = true; > @@ -2054,11 +2046,9 @@ > break; > > case ARM::VLDMDIA: > - case ARM::VLDMDDB: > case ARM::VLDMDIA_UPD: > case ARM::VLDMDDB_UPD: > case ARM::VLDMSIA: > - case ARM::VLDMSDB: > case ARM::VLDMSIA_UPD: > case ARM::VLDMSDB_UPD: > DefCycle = getVLDMDefCycle(ItinData, DefTID, DefClass, DefIdx, DefAlign); > @@ -2097,11 +2087,9 @@ > break; > > case ARM::VSTMDIA: > - case ARM::VSTMDDB: > case ARM::VSTMDIA_UPD: > case ARM::VSTMDDB_UPD: > case ARM::VSTMSIA: > - case ARM::VSTMSDB: > case ARM::VSTMSIA_UPD: > case ARM::VSTMSDB_UPD: > UseCycle = getVSTMUseCycle(ItinData, UseTID, UseClass, UseIdx, UseAlign); > @@ -2312,9 +2300,7 @@ > default: > return ItinData->getStageLatency(get(Opcode).getSchedClass()); > case ARM::VLDMQIA: > - case ARM::VLDMQDB: > case ARM::VSTMQIA: > - case ARM::VSTMQDB: > return 2; > } > } > > Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=128461&r1=128460&r2=128461&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Tue Mar 29 11:45:53 2011 > @@ -967,9 +967,8 @@ > return true; > } > > - case ARM::VLDMQIA: > - case ARM::VLDMQDB: { > - unsigned NewOpc = (Opcode == ARM::VLDMQIA) ? ARM::VLDMDIA : ARM::VLDMDDB; > + case ARM::VLDMQIA: { > + unsigned NewOpc = ARM::VLDMDIA; > MachineInstrBuilder MIB = > BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc)); > unsigned OpIdx = 0; > @@ -998,9 +997,8 @@ > return true; > } > > - case ARM::VSTMQIA: > - case ARM::VSTMQDB: { > - unsigned NewOpc = (Opcode == ARM::VSTMQIA) ? ARM::VSTMDIA : ARM::VSTMDDB; > + case ARM::VSTMQIA: { > + unsigned NewOpc = ARM::VSTMDIA; > MachineInstrBuilder MIB = > BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc)); > unsigned OpIdx = 0; > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=128461&r1=128460&r2=128461&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Tue Mar 29 11:45:53 2011 > @@ -146,10 +146,6 @@ > : PseudoVFPLdStM<(outs QPR:$dst), (ins GPR:$Rn), > IIC_fpLoad_m, "", > [(set QPR:$dst, (v2f64 (load GPR:$Rn)))]>; > -def VLDMQDB > - : PseudoVFPLdStM<(outs QPR:$dst), (ins GPR:$Rn), > - IIC_fpLoad_m, "", > - [(set QPR:$dst, (v2f64 (load GPR:$Rn)))]>; > > // Use VSTM to store a Q register as a D register pair. > // This is a pseudo instruction that is expanded to VSTMD after reg alloc. > @@ -157,10 +153,6 @@ > : PseudoVFPLdStM<(outs), (ins QPR:$src, GPR:$Rn), > IIC_fpStore_m, "", > [(store (v2f64 QPR:$src), GPR:$Rn)]>; > -def VSTMQDB > - : PseudoVFPLdStM<(outs), (ins QPR:$src, GPR:$Rn), > - IIC_fpStore_m, "", > - [(store (v2f64 QPR:$src), GPR:$Rn)]>; > > // Classes for VLD* pseudo-instructions with multi-register operands. > // These are expanded to real instructions after register allocation. > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=128461&r1=128460&r2=128461&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Tue Mar 29 11:45:53 2011 > @@ -101,14 +101,6 @@ > let Inst{21} = 1; // Writeback > let Inst{20} = L_bit; > } > - def DDB : > - AXDI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), > - IndexModeNone, itin, > - !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> { > - let Inst{24-23} = 0b10; // Decrement Before > - let Inst{21} = 0; // No writeback > - let Inst{20} = L_bit; > - } > def DDB_UPD : > AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), > IndexModeUpd, itin_upd, > @@ -143,18 +135,6 @@ > // VFP pipelines. > let D = VFPNeonDomain; > } > - def SDB : > - AXSI4<(outs), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops), > - IndexModeNone, itin, > - !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> { > - let Inst{24-23} = 0b10; // Decrement Before > - let Inst{21} = 0; // No writeback > - let Inst{20} = L_bit; > - > - // Some single precision VFP instructions may be executed on both NEON and > - // VFP pipelines. > - let D = VFPNeonDomain; > - } > def SDB_UPD : > AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops), > IndexModeUpd, itin_upd, > > Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=128461&r1=128460&r2=128461&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Tue Mar 29 11:45:53 2011 > @@ -79,7 +79,7 @@ > unsigned Position; > MachineBasicBlock::iterator MBBI; > bool Merged; > - MemOpQueueEntry(int o, unsigned r, bool k, unsigned p, > + MemOpQueueEntry(int o, unsigned r, bool k, unsigned p, > MachineBasicBlock::iterator i) > : Offset(o), Reg(r), isKill(k), Position(p), MBBI(i), Merged(false) {} > }; > @@ -174,7 +174,7 @@ > switch (Mode) { > default: llvm_unreachable("Unhandled submode!"); > case ARM_AM::ia: return ARM::VLDMSIA; > - case ARM_AM::db: return ARM::VLDMSDB; > + case ARM_AM::db: return 0; // Only VLDMSDB_UPD exists. > } > break; > case ARM::VSTRS: > @@ -182,7 +182,7 @@ > switch (Mode) { > default: llvm_unreachable("Unhandled submode!"); > case ARM_AM::ia: return ARM::VSTMSIA; > - case ARM_AM::db: return ARM::VSTMSDB; > + case ARM_AM::db: return 0; // Only VSTMSDB_UPD exists. > } > break; > case ARM::VLDRD: > @@ -190,7 +190,7 @@ > switch (Mode) { > default: llvm_unreachable("Unhandled submode!"); > case ARM_AM::ia: return ARM::VLDMDIA; > - case ARM_AM::db: return ARM::VLDMDDB; > + case ARM_AM::db: return 0; // Only VLDMDDB_UPD exists. > } > break; > case ARM::VSTRD: > @@ -198,7 +198,7 @@ > switch (Mode) { > default: llvm_unreachable("Unhandled submode!"); > case ARM_AM::ia: return ARM::VSTMDIA; > - case ARM_AM::db: return ARM::VSTMDDB; > + case ARM_AM::db: return 0; // Only VSTMDDB_UPD exists. > } > break; > } > @@ -246,13 +246,9 @@ > case ARM::t2LDMDB_UPD: > case ARM::t2STMDB: > case ARM::t2STMDB_UPD: > - case ARM::VLDMSDB: > case ARM::VLDMSDB_UPD: > - case ARM::VSTMSDB: > case ARM::VSTMSDB_UPD: > - case ARM::VLDMDDB: > case ARM::VLDMDDB_UPD: > - case ARM::VSTMDDB: > case ARM::VSTMDDB_UPD: > return ARM_AM::db; > > @@ -567,14 +563,10 @@ > case ARM::t2STMIA: > case ARM::t2STMDB: > case ARM::VLDMSIA: > - case ARM::VLDMSDB: > case ARM::VSTMSIA: > - case ARM::VSTMSDB: > return (MI->getNumOperands() - MI->getDesc().getNumOperands() + 1) * 4; > case ARM::VLDMDIA: > - case ARM::VLDMDDB: > case ARM::VSTMDIA: > - case ARM::VSTMDDB: > return (MI->getNumOperands() - MI->getDesc().getNumOperands() + 1) * 8; > } > } > @@ -624,7 +616,6 @@ > } > break; > case ARM::VLDMSIA: > - case ARM::VLDMSDB: > switch (Mode) { > default: llvm_unreachable("Unhandled submode!"); > case ARM_AM::ia: return ARM::VLDMSIA_UPD; > @@ -632,7 +623,6 @@ > } > break; > case ARM::VLDMDIA: > - case ARM::VLDMDDB: > switch (Mode) { > default: llvm_unreachable("Unhandled submode!"); > case ARM_AM::ia: return ARM::VLDMDIA_UPD; > @@ -640,7 +630,6 @@ > } > break; > case ARM::VSTMSIA: > - case ARM::VSTMSDB: > switch (Mode) { > default: llvm_unreachable("Unhandled submode!"); > case ARM_AM::ia: return ARM::VSTMSIA_UPD; > @@ -648,7 +637,6 @@ > } > break; > case ARM::VSTMDIA: > - case ARM::VSTMDDB: > switch (Mode) { > default: llvm_unreachable("Unhandled submode!"); > case ARM_AM::ia: return ARM::VSTMDIA_UPD; > > Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128461&r1=128460&r2=128461&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) > +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Tue Mar 29 11:45:53 2011 > @@ -1123,7 +1123,7 @@ > case ARM::LDRD: case ARM::LDRD_PRE: case ARM::LDRD_POST: > case ARM::STRD: case ARM::STRD_PRE: case ARM::STRD_POST: > return true; > - } > + } > } > > static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn, > @@ -1610,7 +1610,7 @@ > // A8.6.295 vcvt (floating-point <-> integer) > // Int to FP: VSITOD, VSITOS, VUITOD, VUITOS > // FP to Int: VTOSI[Z|R]D, VTOSI[Z|R]S, VTOUI[Z|R]D, VTOUI[Z|R]S > -// > +// > // A8.6.297 vcvt (floating-point and fixed-point) > // Dd|Sd Dd|Sd(TIED_TO) #fbits(= 16|32 - UInt(imm4:i)) > static bool DisassembleVFPConv1Frm(MCInst &MI, unsigned Opcode, uint32_t insn, > @@ -1832,9 +1832,9 @@ > > OpIdx += 3; > > - bool isSPVFP = (Opcode == ARM::VLDMSIA || Opcode == ARM::VLDMSDB || > + bool isSPVFP = (Opcode == ARM::VLDMSIA || > Opcode == ARM::VLDMSIA_UPD || Opcode == ARM::VLDMSDB_UPD || > - Opcode == ARM::VSTMSIA || Opcode == ARM::VSTMSDB || > + Opcode == ARM::VSTMSIA || > Opcode == ARM::VSTMSIA_UPD || Opcode == ARM::VSTMSDB_UPD); > unsigned RegClassID = isSPVFP ? ARM::SPRRegClassID : ARM::DPRRegClassID; > > @@ -1848,7 +1848,7 @@ > // Apply some sanity checks before proceeding. > if (Regs == 0 || (RegD + Regs) > 32 || (!isSPVFP && Regs > 16)) > return false; > - > + > for (unsigned i = 0; i < Regs; ++i) { > MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassID, > RegD + i))); > @@ -2286,15 +2286,15 @@ > // n == 2 && type == 0b1001 -> DblSpaced = true > if (Name.startswith("VST2") || Name.startswith("VLD2")) > DblSpaced = slice(insn, 11, 8) == 9; > - > + > // n == 3 && type == 0b0101 -> DblSpaced = true > if (Name.startswith("VST3") || Name.startswith("VLD3")) > DblSpaced = slice(insn, 11, 8) == 5; > - > + > // n == 4 && type == 0b0001 -> DblSpaced = true > if (Name.startswith("VST4") || Name.startswith("VLD4")) > DblSpaced = slice(insn, 11, 8) == 1; > - > + > } > return DisassembleNLdSt0(MI, Opcode, insn, NumOps, NumOpsAdded, > slice(insn, 21, 21) == 0, DblSpaced, B); > @@ -2391,7 +2391,7 @@ > // > // Vector Move Long: > // Qd Dm > -// > +// > // Vector Move Narrow: > // Dd Qm > // > @@ -2533,7 +2533,7 @@ > assert(OpInfo[OpIdx].RegClass < 0 && "Imm operand expected"); > > // Add the imm operand. > - > + > // VSHLL has maximum shift count as the imm, inferred from its size. > unsigned Imm; > switch (Opcode) { > @@ -2646,7 +2646,7 @@ > // N3RegFrm. > if (Opcode == ARM::VMOVDneon || Opcode == ARM::VMOVQ) > return true; > - > + > // Dm = Inst{5:3-0} => NEON Rm > // or > // Dm is restricted to D0-D7 if size is 16, D0-D15 otherwise > @@ -3183,7 +3183,7 @@ > > return false; > } > - > + > /// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process > /// the possible Predicate and SBitModifier, to build the remaining MCOperand > /// constituents. > > Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=128461&r1=128460&r2=128461&view=diff > ============================================================================== > --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) > +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Tue Mar 29 11:45:53 2011 > @@ -173,9 +173,6 @@ > # CHECK: vcmpe.f64 d8, #0 > 0xc0 0x8b 0xb5 0xee > > -# CHECK: vldmdb r2, {s7, s8, s9, s10, s11} > -0x05 0x3a 0x52 0xed > - > # CHECK: strtvc r5, [r3], r0, lsr #20 > 0x30 0x5a 0xa3 0x76 > > > Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt?rev=128461&r1=128460&r2=128461&view=diff > ============================================================================== > --- llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt (original) > +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt Tue Mar 29 11:45:53 2011 > @@ -1,4 +1,5 @@ > # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} > +# XFAIL: * > > # core registers out of range > -0xa5 0xba 0x52 0xed > +0xa5 0xba 0xd2 0xed > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From resistor at mac.com Tue Mar 29 12:42:26 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 29 Mar 2011 17:42:26 -0000 Subject: [llvm-commits] [llvm] r128467 - /llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Message-ID: <20110329174226.2809C2A6C12C@llvm.org> Author: resistor Date: Tue Mar 29 12:42:25 2011 New Revision: 128467 URL: http://llvm.org/viewvc/llvm-project?rev=128467&view=rev Log: Add safety check that didn't show up in testing. Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=128467&r1=128466&r2=128467&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Tue Mar 29 12:42:25 2011 @@ -350,6 +350,7 @@ bool isDef = (isi32Load(Opcode) || Opcode == ARM::VLDRS || Opcode == ARM::VLDRD); Opcode = getLoadStoreMultipleOpcode(Opcode, Mode); + if (!Opcode) return false; MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(Opcode)) .addReg(Base, getKillRegState(BaseKill)) .addImm(Pred).addReg(PredReg); From stoklund at 2pi.dk Tue Mar 29 12:47:00 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 29 Mar 2011 17:47:00 -0000 Subject: [llvm-commits] [llvm] r128468 - /llvm/trunk/lib/CodeGen/InlineSpiller.cpp Message-ID: <20110329174700.3B7F72A6C12C@llvm.org> Author: stoklund Date: Tue Mar 29 12:47:00 2011 New Revision: 128468 URL: http://llvm.org/viewvc/llvm-project?rev=128468&view=rev Log: Run dead code elimination immediately after rematerialization. This may eliminate some uses of the spilled registers, and we don't want to insert reloads for that. Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InlineSpiller.cpp?rev=128468&r1=128467&r2=128468&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/InlineSpiller.cpp (original) +++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp Tue Mar 29 12:47:00 2011 @@ -684,8 +684,7 @@ for (LiveInterval::vni_iterator I = LI.vni_begin(), E = LI.vni_end(); I != E; ++I) { VNInfo *VNI = *I; - if (VNI->isUnused() || VNI->isPHIDef() || VNI->hasPHIKill() || - UsedValues.count(VNI)) + if (VNI->isUnused() || VNI->isPHIDef() || UsedValues.count(VNI)) continue; MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def); MI->addRegisterDead(Reg, &TRI); @@ -693,14 +692,30 @@ continue; DEBUG(dbgs() << "All defs dead: " << *MI); DeadDefs.push_back(MI); - // Remove all Reg references so we don't insert spill code around MI. - for (MachineInstr::mop_iterator MOI = MI->operands_begin(), - MOE = MI->operands_end(); MOI != MOE ; ++MOI) - if (MOI->isReg() && MOI->getReg() == Reg) - MOI->setReg(0); - VNI->setIsUnused(true); } } + + // Eliminate dead code after remat. Note that some snippet copies may be + // deleted here. + if (DeadDefs.empty()) + return; + DEBUG(dbgs() << "Remat created " << DeadDefs.size() << " dead defs.\n"); + Edit->eliminateDeadDefs(DeadDefs, LIS, VRM, TII); + + // Get rid of deleted and empty intervals. + for (unsigned i = RegsToSpill.size(); i != 0; --i) { + unsigned Reg = RegsToSpill[i-1]; + if (!LIS.hasInterval(Reg)) { + RegsToSpill.erase(RegsToSpill.begin() + (i - 1)); + continue; + } + LiveInterval &LI = LIS.getInterval(Reg); + if (!LI.empty()) + continue; + Edit->eraseVirtReg(Reg, LIS); + RegsToSpill.erase(RegsToSpill.begin() + (i - 1)); + } + DEBUG(dbgs() << RegsToSpill.size() << " registers to spill after remat.\n"); } /// If MI is a load or store of StackSlot, it can be removed. @@ -913,7 +928,7 @@ reMaterializeAll(); // Remat may handle everything. - if (Edit->getParent().empty()) + if (RegsToSpill.empty()) return; // Update LiveStacks now that we are committed to spilling. From stoklund at 2pi.dk Tue Mar 29 12:47:02 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 29 Mar 2011 17:47:02 -0000 Subject: [llvm-commits] [llvm] r128469 - in /llvm/trunk/lib/CodeGen: InlineSpiller.cpp LiveRangeEdit.cpp Message-ID: <20110329174702.AF05D2A6C12D@llvm.org> Author: stoklund Date: Tue Mar 29 12:47:02 2011 New Revision: 128469 URL: http://llvm.org/viewvc/llvm-project?rev=128469&view=rev Log: Remember to use the correct register when rematerializing for snippets. Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InlineSpiller.cpp?rev=128469&r1=128468&r2=128469&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/InlineSpiller.cpp (original) +++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp Tue Mar 29 12:47:02 2011 @@ -580,7 +580,7 @@ DEBUG(dbgs() << "\tadding flags: "); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); - if (MO.isReg() && MO.isUse() && MO.getReg() == Edit->getReg()) + if (MO.isReg() && MO.isUse() && MO.getReg() == VirtReg.reg) MO.setIsUndef(); } DEBUG(dbgs() << UseIdx << '\t' << *MI); @@ -601,11 +601,11 @@ return false; } - // If the instruction also writes Edit->getReg(), it had better not require - // the same register for uses and defs. + // If the instruction also writes VirtReg.reg, it had better not require the + // same register for uses and defs. bool Reads, Writes; SmallVector Ops; - tie(Reads, Writes) = MI->readsWritesVirtualRegister(Edit->getReg(), &Ops); + tie(Reads, Writes) = MI->readsWritesVirtualRegister(VirtReg.reg, &Ops); if (Writes) { for (unsigned i = 0, e = Ops.size(); i != e; ++i) { MachineOperand &MO = MI->getOperand(Ops[i]); @@ -626,7 +626,7 @@ } // Alocate a new register for the remat. - LiveInterval &NewLI = Edit->create(LIS, VRM); + LiveInterval &NewLI = Edit->createFrom(VirtReg.reg, LIS, VRM); NewLI.markNotSpillable(); // Rematting for a copy: Set allocation hint to be the destination register. @@ -642,7 +642,7 @@ // Replace operands for (unsigned i = 0, e = Ops.size(); i != e; ++i) { MachineOperand &MO = MI->getOperand(Ops[i]); - if (MO.isReg() && MO.isUse() && MO.getReg() == Edit->getReg()) { + if (MO.isReg() && MO.isUse() && MO.getReg() == VirtReg.reg) { MO.setReg(NewLI.reg); MO.setIsKill(); } Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp?rev=128469&r1=128468&r2=128469&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp Tue Mar 29 12:47:02 2011 @@ -11,6 +11,7 @@ // is spilled or split. //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "regalloc" #include "LiveRangeEdit.h" #include "VirtRegMap.h" #include "llvm/ADT/SetVector.h" From evan.cheng at apple.com Tue Mar 29 12:53:13 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 29 Mar 2011 10:53:13 -0700 Subject: [llvm-commits] [llvm] r128467 - /llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp In-Reply-To: <20110329174226.2809C2A6C12C@llvm.org> References: <20110329174226.2809C2A6C12C@llvm.org> Message-ID: <35CEEBBE-A13D-4D19-8506-FFF72758E59D@apple.com> Still not quite right. BuildMI(MBB, MBBI, dl, TII->get(BaseOpc), NewBase) .addReg(Base, getKillRegState(BaseKill)).addImm(Offset) .addImm(Pred).addReg(PredReg).addReg(0); Base = NewBase; BaseKill = true; // New base is always killed right its use. } bool isDef = (isi32Load(Opcode) || Opcode == ARM::VLDRS || Opcode == ARM::VLDRD); Opcode = getLoadStoreMultipleOpcode(Opcode, Mode); This could have introduced an instruction to calculate the new base register. Evan On Mar 29, 2011, at 10:42 AM, Owen Anderson wrote: > Author: resistor > Date: Tue Mar 29 12:42:25 2011 > New Revision: 128467 > > URL: http://llvm.org/viewvc/llvm-project?rev=128467&view=rev > Log: > Add safety check that didn't show up in testing. > > Modified: > llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp > > Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=128467&r1=128466&r2=128467&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Tue Mar 29 12:42:25 2011 > @@ -350,6 +350,7 @@ > bool isDef = (isi32Load(Opcode) || Opcode == ARM::VLDRS || > Opcode == ARM::VLDRD); > Opcode = getLoadStoreMultipleOpcode(Opcode, Mode); > + if (!Opcode) return false; > MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(Opcode)) > .addReg(Base, getKillRegState(BaseKill)) > .addImm(Pred).addReg(PredReg); > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Tue Mar 29 13:44:32 2011 From: baldrick at free.fr (Duncan Sands) Date: Tue, 29 Mar 2011 18:44:32 -0000 Subject: [llvm-commits] [dragonegg] r128473 - in /dragonegg/trunk: Constants.cpp Constants.h Message-ID: <20110329184432.9429E2A6C12C@llvm.org> Author: baldrick Date: Tue Mar 29 13:44:32 2011 New Revision: 128473 URL: http://llvm.org/viewvc/llvm-project?rev=128473&view=rev Log: Rewrite handling of struct and union initializers, fixing PR7327. The existing code mostly worked for Ada and the C-like languages (though it did like to barf when fields had to be squeezed smaller than the size of the type of the field, which sometimes happens for these languages), but fell over on initializers coming from Fortran equivalences, which get turned into unions with overlapping fields at non-zero offsets from the start, and on just about everything coming from java. The new code works at the level of bits rather than bytes, where, thanks to the way GCC thinks of bitfields (which is not the same as in C), there is no difference between bitfields and other fields. This means that Ada code that has bitfields containing structs or other exciting types should now be handled automatically here (though it still causes trouble elsewhere). The new code is completely unphased about overlapping fields, though in fact they never occur if you take DECL_SIZE seriously (i.e. never let your fields get bigger than DECL_SIZE), allowing the same code to handle both structs and unions. Modified: dragonegg/trunk/Constants.cpp dragonegg/trunk/Constants.h Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=128473&r1=128472&r2=128473&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Tue Mar 29 13:44:32 2011 @@ -24,6 +24,8 @@ #include "Constants.h" #include "Internals.h" #include "Trees.h" +#include "ADT/IntervalList.h" +#include "ADT/Range.h" // LLVM headers #include "llvm/GlobalVariable.h" @@ -56,162 +58,231 @@ // ... InterpretAsType ... //===----------------------------------------------------------------------===// +typedef Range SignedRange; + /// BitSlice - A contiguous range of bits held in memory. class BitSlice { - int First, Last; // Range [First, Last) - Constant *Contents; // May be null for an empty range. + SignedRange R; + Constant *Contents; // Null if and only if the range is empty. - /// ExtendRange - Extend the slice to a wider range. All added bits are zero. - BitSlice ExtendRange(int WideFirst, int WideLast) const { - // Quick exit if the range did not actually increase. - if (WideFirst == First && WideLast == Last) - return *this; - if (WideFirst > First || WideLast < Last || WideLast <= WideFirst) { - assert(empty() && WideLast <= WideFirst && "Not an extension!"); - // The trivial case of extending an empty range to an empty range. - return BitSlice(); - } - const Type *WideTy = IntegerType::get(Context, WideLast - WideFirst); - // If the slice contains no bits then every bit of the extension is zero. + bool contentsValid() const { if (empty()) - return BitSlice(WideFirst, WideLast, Constant::getNullValue(WideTy)); - // Zero extend the contents to the new type; - Constant *C = TheFolder->CreateZExtOrBitCast(Contents, WideTy); - // Position the old contents correctly inside the new contents. - if (BYTES_BIG_ENDIAN && WideLast > Last) { - Constant *ShiftAmt = ConstantInt::get(C->getType(), WideLast - Last); - C = TheFolder->CreateShl(C, ShiftAmt); - } else if (!BYTES_BIG_ENDIAN && WideFirst < First) { - Constant *ShiftAmt = ConstantInt::get(C->getType(), First - WideFirst); - C = TheFolder->CreateShl(C, ShiftAmt); - } - return BitSlice(WideFirst, WideLast, C); - } - - /// ReduceRange - Reduce the slice to a smaller range. - BitSlice ReduceRange(int NarrowFirst, int NarrowLast) const { - // Quick exit if the range did not actually decrease. - if (NarrowFirst == First && NarrowLast == Last) - return *this; - // The trivial case of reducing to an empty range. - if (NarrowLast <= NarrowFirst) - return BitSlice(); - assert(NarrowFirst >= First && NarrowLast <= Last && "Not a reduction!"); - // Move the least-significant bit to the correct position. - Constant *C = Contents; - if (BYTES_BIG_ENDIAN && NarrowLast < Last) { - Constant *ShiftAmt = ConstantInt::get(C->getType(), Last - NarrowLast); - C = TheFolder->CreateLShr(C, ShiftAmt); - } else if (!BYTES_BIG_ENDIAN && NarrowFirst > First) { - Constant *ShiftAmt = ConstantInt::get(C->getType(), NarrowFirst - First); - C = TheFolder->CreateLShr(C, ShiftAmt); - } - // Truncate to the new type. - const Type *NarrowTy = IntegerType::get(Context, NarrowLast - NarrowFirst); - C = TheFolder->CreateTruncOrBitCast(C, NarrowTy); - return BitSlice(NarrowFirst, NarrowLast, C); + return !Contents; + return Contents && isa(Contents->getType()) && + getBitWidth() == Contents->getType()->getPrimitiveSizeInBits(); } public: /// BitSlice - Default constructor: empty bit range. - BitSlice() : First(0), Last(0), Contents(0) {} + BitSlice() : R(), Contents(0) {} + + /// BitSlice - Constructor for the given range of bits. The bits themselves + /// are supplied in 'contents' as a constant of integer type (if the range is + /// empty then 'contents' must be null). On little-endian machines the least + /// significant bit of 'contents' corresponds to the first bit of the range + /// (aka "First"), while on big-endian machines it corresponds to the last bit + /// of the range (aka "Last-1"). + BitSlice(SignedRange r, Constant *contents) : R(r), Contents(contents) { + assert(contentsValid() && "Contents do not match range"); + } - /// BitSlice - Constructor for the range of bits ['first', 'last'). The bits - /// themselves are supplied in 'contents' as a constant of integer type. On - /// little-endian machines the least significant bit of 'contents corresponds - /// to the first bit of the range (aka 'first'), while on big-endian machines - /// it corresponds to the last bit of the range (aka 'last'-1). + /// BitSlice - Constructor for the range of bits ['first', 'last'). BitSlice(int first, int last, Constant *contents) - : First(first), Last(last), Contents(contents) { - assert((empty() || isa(Contents->getType())) && - "Not an integer type!"); - assert((empty() || getBitWidth() == - Contents->getType()->getPrimitiveSizeInBits()) && - "Bitwidth mismatch!"); + : R(first, last), Contents(contents) { + assert(contentsValid() && "Contents do not match range"); } - /// empty - Return whether the range is empty. + /// empty - Return whether the bit range is empty. bool empty() const { - return Last <= First; + return R.empty(); } /// getBitWidth - Return the number of bits in the range. - unsigned getBitWidth() { - return empty() ? 0 : Last - First; + unsigned getBitWidth() const { + return R.getWidth(); + } + + /// getFirst - Return the position of the first bit in the range. + unsigned getFirst() const { + return R.getFirst(); + } + + /// getLast - Return the position of the last bit defining the range. + unsigned getLast() const { + return R.getLast(); + } + + /// getRange - Return the range of bits in this slice. + SignedRange getRange() const { + return R; } /// Displace - Return the result of sliding all bits by the given offset. BitSlice Displace(int Offset) const { - return BitSlice(First + Offset, Last + Offset, Contents); + return BitSlice(R.Displace(Offset), Contents); } - /// getBits - Return the bits in the range [first, last). This range need not + /// getBits - Return the bits in the given range. The supplied range need not /// be contained in the range of the slice, but if not then the bits outside /// the slice get an undefined value. The bits are returned as a constant of /// integer type. On little-endian machine the least significant bit of the - /// returned value corresponds to the first bit of the range (aka 'first'), + /// returned value corresponds to the first bit of the range (aka "First"), /// while on big-endian machines it corresponds to the last bit of the range - /// (aka 'last'-1). - Constant *getBits(int first, int last) { - assert(first < last && "Bit range is empty!"); - // Quick exit if the desired range matches that of the slice. - if (First == first && Last == last) - return Contents; - const Type *RetTy = IntegerType::get(Context, last - first); - // If the slice contains no bits then every returned bit is undefined. - if (empty()) - return UndefValue::get(RetTy); - // Extend to the convex hull of the two ranges. - int WideFirst = first < First ? first : First; - int WideLast = last > Last ? last : Last; - BitSlice Slice = ExtendRange(WideFirst, WideLast); - // Chop the slice down to the requested range. - Slice = Slice.ReduceRange(first, last); - // Now we can just return the bits contained in the slice. - return Slice.Contents; - } + /// (aka "Last-1"). + Constant *getBits(SignedRange r) const; + + /// ExtendRange - Extend the slice to a wider range. The value of the added + /// bits is undefined. + BitSlice ExtendRange(SignedRange r) const; + + /// ReduceRange - Reduce the slice to a smaller range. + BitSlice ReduceRange(SignedRange r) const; /// Merge - Join the slice with another (which must be disjoint), forming the /// convex hull of the ranges. The bits in the range of one of the slices are /// those of that slice. Any other bits have an undefined value. - void Merge(const BitSlice &that) { - // If the other slice is empty, the result is this slice. - if (that.empty()) - return; - // If this slice is empty, the result is the other slice. - if (empty()) { - *this = that; - return; - } - assert((that.Last <= First || that.First >= Last) && "Slices overlap!"); - // Zero extend each slice to the convex hull of the ranges. - int JoinFirst = that.First < First ? that.First : First; - int JoinLast = that.Last > Last ? that.Last : Last; - BitSlice ThisExtended = ExtendRange(JoinFirst, JoinLast); - BitSlice ThatExtended = that.ExtendRange(JoinFirst, JoinLast); - // Since the slices are disjoint and all added bits are zero they can be - // joined via a simple 'or'. - Constant *Join = TheFolder->CreateOr(ThisExtended.Contents, - ThatExtended.Contents); - *this = BitSlice(JoinFirst, JoinLast, Join); - } + void Merge(const BitSlice &other); }; +/// ExtendRange - Extend the slice to a wider range. The value of the added +/// bits is undefined. +BitSlice BitSlice::ExtendRange(SignedRange r) const { + assert(r.contains(R) && "Not an extension!"); + // Quick exit if the range did not actually increase. + if (R == r) + return *this; + assert(!r.empty() && "Empty ranges did not evaluate as equal?"); + const Type *ExtTy = IntegerType::get(Context, r.getWidth()); + // If the slice contains no bits then every bit of the extension is undefined. + if (empty()) + return BitSlice(r, UndefValue::get(ExtTy)); + // Extend the contents to the new type. + Constant *C = TheFolder->CreateZExtOrBitCast(Contents, ExtTy); + // Position the old contents correctly inside the new contents. + unsigned deltaFirst = R.getFirst() - r.getFirst(); + unsigned deltaLast = r.getLast() - R.getLast(); + if (BYTES_BIG_ENDIAN && deltaLast) { + Constant *ShiftAmt = ConstantInt::get(C->getType(), deltaLast); + C = TheFolder->CreateShl(C, ShiftAmt); + } else if (!BYTES_BIG_ENDIAN && deltaFirst) { + Constant *ShiftAmt = ConstantInt::get(C->getType(), deltaFirst); + C = TheFolder->CreateShl(C, ShiftAmt); + } + return BitSlice(r, C); +} + +/// getBits - Return the bits in the given range. The supplied range need not +/// be contained in the range of the slice, but if not then the bits outside +/// the slice get an undefined value. The bits are returned as a constant of +/// integer type. On little-endian machine the least significant bit of the +/// returned value corresponds to the first bit of the range (aka "First"), +/// while on big-endian machines it corresponds to the last bit of the range +/// (aka "Last-1"). +Constant *BitSlice::getBits(SignedRange r) const { + assert(!r.empty() && "Bit range is empty!"); + // Quick exit if the desired range matches that of the slice. + if (R == r) + return Contents; + const Type *RetTy = IntegerType::get(Context, r.getWidth()); + // If the slice contains no bits then every returned bit is undefined. + if (empty()) + return UndefValue::get(RetTy); + // Extend to the convex hull of the two ranges. + BitSlice Slice = ExtendRange(R.Join(r)); + // Chop the slice down to the requested range. + Slice = Slice.ReduceRange(r); + // Now we can just return the bits contained in the slice. + return Slice.Contents; +} + +/// Merge - Join the slice with another (which must be disjoint), forming the +/// convex hull of the ranges. The bits in the range of one of the slices are +/// those of that slice. Any other bits have an undefined value. +void BitSlice::Merge(const BitSlice &other) { + // If the other slice is empty, the result is this slice. + if (other.empty()) + return; + // If this slice is empty, the result is the other slice. + if (empty()) { + *this = other; + return; + } + assert(!R.intersects(other.getRange()) && "Slices overlap!"); + + // Extend each slice to the convex hull of the ranges. + SignedRange Hull = R.Join(other.getRange()); + BitSlice ExtThis = ExtendRange(Hull); + BitSlice ExtOther = other.ExtendRange(Hull); + + // The extra bits added when extending a slice may contain anything. In each + // extended slice clear the bits corresponding to the other slice. + int HullFirst = Hull.getFirst(), HullLast = Hull.getLast(); + unsigned HullWidth = Hull.getWidth(); + // Compute masks with the bits for each slice set to 1. + APInt ThisBits, OtherBits; + if (BYTES_BIG_ENDIAN) { + ThisBits = APInt::getBitsSet(HullWidth, HullLast - getLast(), + HullLast - getFirst()); + OtherBits = APInt::getBitsSet(HullWidth, HullLast - other.getLast(), + HullLast - other.getFirst()); + } else { + ThisBits = APInt::getBitsSet(HullWidth, getFirst() - HullFirst, + getLast() - HullFirst); + OtherBits = APInt::getBitsSet(HullWidth, other.getFirst() - HullFirst, + other.getLast() - HullFirst); + } + // Clear bits which correspond to the other slice. + ConstantInt *ClearThis = ConstantInt::get(Context, ~ThisBits); + ConstantInt *ClearOther = ConstantInt::get(Context, ~OtherBits); + Constant *ThisPart = TheFolder->CreateAnd(ExtThis.Contents, ClearOther); + Constant *OtherPart = TheFolder->CreateAnd(ExtOther.Contents, ClearThis); + + // The slices can now be joined via a simple 'or'. + *this = BitSlice(Hull, TheFolder->CreateOr(ThisPart, OtherPart)); +} + +/// ReduceRange - Reduce the slice to a smaller range. +BitSlice BitSlice::ReduceRange(SignedRange r) const { + assert(R.contains(r) && "Not a reduction!"); + // Quick exit if the range did not actually decrease. + if (R == r) + return *this; + // The trivial case of reducing to an empty range. + if (r.empty()) + return BitSlice(); + assert(!R.empty() && "Empty ranges did not evaluate as equal?"); + // Move the least-significant bit to the correct position. + Constant *C = Contents; + unsigned deltaFirst = r.getFirst() - R.getFirst(); + unsigned deltaLast = R.getLast() - r.getLast(); + if (BYTES_BIG_ENDIAN && deltaLast) { + Constant *ShiftAmt = ConstantInt::get(C->getType(), deltaLast); + C = TheFolder->CreateLShr(C, ShiftAmt); + } else if (!BYTES_BIG_ENDIAN && deltaFirst) { + Constant *ShiftAmt = ConstantInt::get(C->getType(), deltaFirst); + C = TheFolder->CreateLShr(C, ShiftAmt); + } + // Truncate to the new type. + const Type *RedTy = IntegerType::get(Context, r.getWidth()); + C = TheFolder->CreateTruncOrBitCast(C, RedTy); + return BitSlice(r, C); +} + /// ViewAsBits - View the given constant as a bunch of bits, i.e. as one big -/// integer. Only the bits in the range [First, Last) are needed, so there -/// is no need to supply bits outside this range though it is harmless to do -/// so. There is also no need to supply undefined bits inside this range. -static BitSlice ViewAsBits(Constant *C, int First, int Last) { - assert(First < Last && "Empty range!"); +/// integer. Only the bits in the given range are needed, so there is no need +/// to supply bits outside this range though it is harmless to do so. There is +/// also no need to supply undefined bits inside the range. +static BitSlice ViewAsBits(Constant *C, SignedRange R) { + if (R.empty()) + return BitSlice(); // Sanitize the range to make life easier in what follows. const Type *Ty = C->getType(); int StoreSize = getTargetData().getTypeStoreSizeInBits(Ty); - First = First < 0 ? 0 : First; - Last = Last > StoreSize ? StoreSize : Last; + R = R.Meet(SignedRange(0, StoreSize)); // Quick exit if it is clear that there are no bits in the range. - if (Last <= 0 || First >= StoreSize) + if (R.empty()) return BitSlice(); assert(StoreSize > 0 && "Empty range not eliminated?"); @@ -250,17 +321,18 @@ const unsigned Stride = getTargetData().getTypeAllocSizeInBits(EltTy); assert(Stride > 0 && "Store size smaller than alloc size?"); // Elements with indices in [FirstElt, LastElt) overlap the range. - unsigned FirstElt = First / Stride; - unsigned LastElt = (Last + Stride - 1) / Stride; + unsigned FirstElt = R.getFirst() / Stride; + unsigned LastElt = (R.getLast() + Stride - 1) / Stride; assert(LastElt <= NumElts && "Store size bigger than array?"); // Visit all elements that overlap the requested range, accumulating their // bits in Bits. BitSlice Bits; + SignedRange StrideRange(0, Stride); for (unsigned i = FirstElt; i < LastElt; ++i) { // Extract the element. Constant *Elt = TheFolder->CreateExtractValue(C, &i, 1); // View it as a bunch of bits. - BitSlice EltBits = ViewAsBits(Elt, 0, Stride); + BitSlice EltBits = ViewAsBits(Elt, StrideRange); // Add to the already known bits. Bits.Merge(EltBits.Displace(i * Stride)); } @@ -271,8 +343,8 @@ const StructType *STy = cast(Ty); const StructLayout *SL = getTargetData().getStructLayout(STy); // Fields with indices in [FirstIdx, LastIdx) overlap the range. - unsigned FirstIdx = SL->getElementContainingOffset((First+7)/8); - unsigned LastIdx = 1 + SL->getElementContainingOffset((Last+6)/8); + unsigned FirstIdx = SL->getElementContainingOffset((R.getFirst()+7)/8); + unsigned LastIdx = 1 + SL->getElementContainingOffset((R.getLast()+6)/8); // Visit all fields that overlap the requested range, accumulating their // bits in Bits. BitSlice Bits; @@ -282,7 +354,7 @@ // View it as a bunch of bits. const Type *FieldTy = Field->getType(); unsigned FieldStoreSize = getTargetData().getTypeStoreSizeInBits(FieldTy); - BitSlice FieldBits = ViewAsBits(Field, 0, FieldStoreSize); + BitSlice FieldBits = ViewAsBits(Field, SignedRange(0, FieldStoreSize)); // Add to the already known bits. Bits.Merge(FieldBits.Displace(SL->getElementOffset(i)*8)); } @@ -296,18 +368,19 @@ const unsigned Stride = getTargetData().getTypeAllocSizeInBits(EltTy); assert(Stride > 0 && "Store size smaller than alloc size?"); // Elements with indices in [FirstElt, LastElt) overlap the range. - unsigned FirstElt = First / Stride; - unsigned LastElt = (Last + Stride - 1) / Stride; + unsigned FirstElt = R.getFirst() / Stride; + unsigned LastElt = (R.getLast() + Stride - 1) / Stride; assert(LastElt <= NumElts && "Store size bigger than vector?"); // Visit all elements that overlap the requested range, accumulating their // bits in Bits. BitSlice Bits; + SignedRange StrideRange(0, Stride); for (unsigned i = FirstElt; i < LastElt; ++i) { // Extract the element. ConstantInt *Idx = ConstantInt::get(Type::getInt32Ty(Context), i); Constant *Elt = TheFolder->CreateExtractElement(C, Idx); // View it as a bunch of bits. - BitSlice EltBits = ViewAsBits(Elt, 0, Stride); + BitSlice EltBits = ViewAsBits(Elt, StrideRange); // Add to the already known bits. Bits.Merge(EltBits.Displace(i * Stride)); } @@ -321,7 +394,7 @@ /// same constant as you would get by storing the bits of 'C' to memory (with /// the first bit stored being 'StartingBit') and then loading out a (constant) /// value of type 'Ty' from the stored to memory location. -Constant *InterpretAsType(Constant *C, const Type* Ty, unsigned StartingBit) { +Constant *InterpretAsType(Constant *C, const Type* Ty, int StartingBit) { if (C->getType() == Ty) return C; @@ -334,14 +407,16 @@ // Convert the constant into a bunch of bits. Only the bits to be "loaded" // out are needed, so rather than converting the entire constant this only // converts enough to get all of the required bits. - BitSlice Bits = ViewAsBits(C, StartingBit, StartingBit + StoreSize); + BitSlice Bits = ViewAsBits(C, SignedRange(StartingBit, + StartingBit + StoreSize)); // Extract the bits used by the integer. If the integer width is a multiple // of the address unit then the endianness of the target doesn't matter. If // not then the padding bits come at the start on big-endian machines and at // the end on little-endian machines. Bits = Bits.Displace(-StartingBit); return BYTES_BIG_ENDIAN ? - Bits.getBits(StoreSize - BitWidth, StoreSize) : Bits.getBits(0, BitWidth); + Bits.getBits(SignedRange(StoreSize - BitWidth, StoreSize)) : + Bits.getBits(SignedRange(0, BitWidth)); } case Type::PointerTyID: { @@ -624,492 +699,280 @@ return ConstantStruct::get(Context, PadElts, 2, false); } +/// FieldContents - A constant restricted to a range of bits. Any part of the +/// constant outside of the range is discarded. The range may be bigger than +/// the constant in which case any extra bits have an undefined value. +class FieldContents { + SignedRange R; // The range of bits occupied by the constant. + Constant *C; // The constant. May be null, in which case all bits are zero. + int Starts; // The first bit of the constant is positioned at this offset. + + FieldContents(SignedRange r, Constant *c, int starts) + : R(r), C(c), Starts(starts) {} + + /// getAsBits - Return the bits in the range as an integer (or null if the + /// range is empty). + Constant *getAsBits() const { + if (R.empty()) + return 0; + const Type *IntTy = IntegerType::get(Context, R.getWidth()); + if (!C) // Implicit zero. + return Constant::getNullValue(IntTy); + return InterpretAsType(C, IntTy, R.getFirst() - Starts); + } + + /// isSafeToReturnContentsDirectly - Return whether the current value for the + /// constant properly represents the bits in the range and so can be handed to + /// the user as is. + bool isSafeToReturnContentsDirectly(const TargetData &TD) const { + // Implicit zeros need to be made explicit before being passed to the user. + if (!C) + return false; + // If the first bit of the constant is not the first bit of the range then + // it needs to be displaced before being passed to the user. + if (!R.empty() && R.getFirst() != Starts) + return false; + // If the constant is wider than the range then it needs to be truncated + // before being passed to the user. + const Type *Ty = C->getType(); + unsigned AllocBits = TD.getTypeAllocSizeInBits(Ty); + return AllocBits <= (unsigned)R.getWidth(); + } -namespace { -/// ConstantLayoutInfo - A helper class used by ConvertRecordCONSTRUCTOR to -/// lay out struct inits. -struct ConstantLayoutInfo { - const TargetData &TD; - - /// ResultElts - The initializer elements so far. - std::vector ResultElts; +public: + /// FieldContents - Default constructor: empty bit range. + FieldContents() : R(), C(0), Starts(0) {} - /// StructIsPacked - This is set to true if we find out that we have to emit - /// the ConstantStruct as a Packed LLVM struct type (because the LLVM - /// alignment rules would prevent laying out the struct correctly). - bool StructIsPacked; - - /// NextFieldByteStart - This field indicates the *byte* that the next field - /// will start at. Put another way, this is the size of the struct as - /// currently laid out, but without any tail padding considered. - uint64_t NextFieldByteStart; - - /// MaxLLVMFieldAlignment - This is the largest alignment of any IR field, - /// which is the alignment that the ConstantStruct will get. - unsigned MaxLLVMFieldAlignment; - - - ConstantLayoutInfo(const TargetData &TD) : TD(TD) { - StructIsPacked = false; - NextFieldByteStart = 0; - MaxLLVMFieldAlignment = 1; - } - - void ConvertToPacked(); - void AddFieldToRecordConstant(Constant *Val, uint64_t GCCFieldOffsetInBits); - void AddBitFieldToRecordConstant(ConstantInt *Val, - uint64_t GCCFieldOffsetInBits); - void HandleTailPadding(uint64_t GCCStructBitSize); + /// getConstant - Fill the range [first, last) with the given constant. + static FieldContents getConstant(int first, int last, Constant *c) { + return FieldContents(SignedRange(first, last), c, first); + } + + /// getZero - Fill the range [first, last) with zero. + static FieldContents getZero(int first, int last) { + return getConstant(first, last, 0); + } + + /// getRange - Return the range occupied by this field. + SignedRange getRange() const { return R; } + + /// ChangeRangeTo - Change the range occupied by this field. + void ChangeRangeTo(SignedRange r) { R = r; } + + /// JoinWith - Form the union of this field with another field (which must be + /// disjoint from this one). After this the range will be the convex hull of + /// the ranges of the two fields. + void JoinWith(const FieldContents &S); + + /// extractContents - Return the contained bits as a constant which contains + /// every defined bit in the range, yet is guaranteed to have alloc size no + /// larger than the width of the range. Unlike the other methods for this + /// class, this one requires that the width of the range be a multiple of an + /// address unit, which usually means a multiple of 8. + Constant *extractContents(const TargetData &TD) { + /// If the current value for the constant can be used to represent the bits + /// in the range then just return it. + if (isSafeToReturnContentsDirectly(TD)) + return C; + assert(R.getWidth() % BITS_PER_UNIT == 0 && "Boundaries not aligned?"); + unsigned Units = R.getWidth() / BITS_PER_UNIT; + // If this was an implicit zero then make it an explicit zero. This also + // handles the case of an empty range holding a constant of non-zero size. + if (!C || R.empty()) { + // Return an array of zero bytes. Remember the returned value as an + // optimization in case we are called again. + C = Constant::getNullValue(GetUnitType(Context, Units)); + Starts = R.empty() ? 0 : R.getFirst(); + assert(isSafeToReturnContentsDirectly(TD) && "Unit over aligned?"); + return C; + } + // Turn the contents into a bunch of bits. Remember the returned value as + // an optimization in case we are called again. + // TODO: If the contents only need to be truncated and have struct or array + // type then we could try to do the truncation by dropping or modifying the + // last elements of the constant, maybe yielding something less horrible. + C = getAsBits(); + Starts = R.getFirst(); + if (isSafeToReturnContentsDirectly(TD)) + return C; + // The integer type used to hold the bits was too big (for example an i24 + // typically occupies 32 bits so is too big for a range of 24 bits). Turn + // it into an array of bytes instead. + C = InterpretAsType(C, GetUnitType(Context, Units), 0); + assert(isSafeToReturnContentsDirectly(TD) && "Unit over aligned?"); + return C; + } }; +/// JoinWith - Form the union of this field with another field (which must be +/// disjoint from this one). After this the range will be the convex hull of +/// the ranges of the two fields. +void FieldContents::JoinWith(const FieldContents &S) { + // Consider the contents of the fields to be bunches of bits and paste them + // together. This can result in a nasty integer constant expression, but as + // we only get here for bitfields that's mostly harmless. + BitSlice Bits(R, getAsBits()); + Bits.Merge (BitSlice(S.R, S.getAsBits())); + R = Bits.getRange(); + C = Bits.getBits(R); + Starts = R.empty() ? 0 : R.getFirst(); } -/// ConvertToPacked - Given a partially constructed initializer for a LLVM -/// struct constant, change it to make all the implicit padding between elements -/// be fully explicit. -void ConstantLayoutInfo::ConvertToPacked() { - assert(!StructIsPacked && "Struct is already packed"); - uint64_t EltOffs = 0; - for (unsigned i = 0, e = ResultElts.size(); i != e; ++i) { - Constant *Val = ResultElts[i]; - - // Check to see if this element has an alignment that would cause it to get - // offset. If so, insert explicit padding for the offset. - unsigned ValAlign = TD.getABITypeAlignment(Val->getType()); - uint64_t AlignedEltOffs = TargetData::RoundUpAlignment(EltOffs, ValAlign); - - // If the alignment doesn't affect the element offset, then the value is ok. - // Accept the field and keep moving. - if (AlignedEltOffs == EltOffs) { - EltOffs += TD.getTypeAllocSize(Val->getType()); - continue; - } - - // Otherwise, there is padding here. Insert explicit zeros. - const Type *PadTy = Type::getInt8Ty(Context); - if (AlignedEltOffs-EltOffs != 1) - PadTy = ArrayType::get(PadTy, AlignedEltOffs-EltOffs); - ResultElts.insert(ResultElts.begin()+i, - Constant::getNullValue(PadTy)); - - // The padding is now element "i" and just bumped us up to "AlignedEltOffs". - EltOffs = AlignedEltOffs; - ++e; // One extra element to scan. - } - - // Packed now! - MaxLLVMFieldAlignment = 1; - StructIsPacked = true; -} - - -/// AddFieldToRecordConstant - As ConvertRecordCONSTRUCTOR builds up an LLVM -/// constant to represent a GCC CONSTRUCTOR node, it calls this method to add -/// fields. The design of this is that it adds leading/trailing padding as -/// needed to make the piece fit together and honor the GCC layout. This does -/// not handle bitfields. -/// -/// The arguments are: -/// Val: The value to add to the struct, with a size that matches the size of -/// the corresponding GCC field. -/// GCCFieldOffsetInBits: The offset that we have to put Val in the result. -/// -void ConstantLayoutInfo:: -AddFieldToRecordConstant(Constant *Val, uint64_t GCCFieldOffsetInBits) { - // Figure out how to add this non-bitfield value to our constant struct so - // that it ends up at the right offset. There are four cases we have to - // think about: - // 1. We may be able to just slap it onto the end of our struct and have - // everything be ok. - // 2. We may have to insert explicit padding into the LLVM struct to get - // the initializer over into the right space. This is needed when the - // GCC field has a larger alignment than the LLVM field. - // 3. The LLVM field may be too far over and we may be forced to convert - // this to an LLVM packed struct. This is required when the LLVM - // alignment is larger than the GCC alignment. - // 4. We may have a bitfield that needs to be merged into a previous - // field. - // Start by determining which case we have by looking at where LLVM and GCC - // would place the field. - - // Verified that we haven't already laid out bytes that will overlap with - // this new field. - assert(NextFieldByteStart*8 <= GCCFieldOffsetInBits && - "Overlapping LLVM fields!"); - - // Compute the offset the field would get if we just stuck 'Val' onto the - // end of our structure right now. It is NextFieldByteStart rounded up to - // the LLVM alignment of Val's type. - unsigned ValLLVMAlign = 1; - - if (!StructIsPacked) { // Packed structs ignore the alignment of members. - ValLLVMAlign = TD.getABITypeAlignment(Val->getType()); - MaxLLVMFieldAlignment = std::max(MaxLLVMFieldAlignment, ValLLVMAlign); - } - - // LLVMNaturalByteOffset - This is where LLVM would drop the field if we - // slap it onto the end of the struct. - uint64_t LLVMNaturalByteOffset - = TargetData::RoundUpAlignment(NextFieldByteStart, ValLLVMAlign); - - // If adding the LLVM field would push it over too far, then we must have a - // case that requires the LLVM struct to be packed. Do it now if so. - if (LLVMNaturalByteOffset*8 > GCCFieldOffsetInBits) { - // Switch to packed. - ConvertToPacked(); - assert(NextFieldByteStart*8 <= GCCFieldOffsetInBits && - "Packing didn't fix the problem!"); - - // Recurse to add the field after converting to packed. - return AddFieldToRecordConstant(Val, GCCFieldOffsetInBits); - } - - // If the LLVM offset is not large enough, we need to insert explicit - // padding in the LLVM struct between the fields. - if (LLVMNaturalByteOffset*8 < GCCFieldOffsetInBits) { - // Insert enough padding to fully fill in the hole. Insert padding from - // NextFieldByteStart (not LLVMNaturalByteOffset) because the padding will - // not get the same alignment as "Val". - const Type *FillTy = Type::getInt8Ty(Context); - if (GCCFieldOffsetInBits/8-NextFieldByteStart != 1) - FillTy = ArrayType::get(FillTy, - GCCFieldOffsetInBits/8-NextFieldByteStart); - ResultElts.push_back(Constant::getNullValue(FillTy)); - - NextFieldByteStart = GCCFieldOffsetInBits/8; - - // Recurse to add the field. This handles the case when the LLVM struct - // needs to be converted to packed after inserting tail padding. - return AddFieldToRecordConstant(Val, GCCFieldOffsetInBits); - } - - // Slap 'Val' onto the end of our ConstantStruct, it must be known to land - // at the right offset now. - assert(LLVMNaturalByteOffset*8 == GCCFieldOffsetInBits); - ResultElts.push_back(Val); - NextFieldByteStart = LLVMNaturalByteOffset; - NextFieldByteStart += TD.getTypeAllocSize(Val->getType()); -} - -/// AddBitFieldToRecordConstant - Bitfields can span multiple LLVM fields and -/// have other annoying properties, thus requiring extra layout rules. This -/// routine handles the extra complexity and then forwards to -/// AddFieldToRecordConstant. -void ConstantLayoutInfo:: -AddBitFieldToRecordConstant(ConstantInt *ValC, uint64_t GCCFieldOffsetInBits) { - // If the GCC field starts after our current LLVM field then there must have - // been an anonymous bitfield or other thing that shoved it over. No matter, - // just insert some i8 padding until there are bits to fill in. - while (GCCFieldOffsetInBits > NextFieldByteStart*8) { - ResultElts.push_back(ConstantInt::get(Type::getInt8Ty(Context), 0)); - ++NextFieldByteStart; - } - - // If the field is a bitfield, it could partially go in a previously - // laid out structure member, and may add elements to the end of the currently - // laid out structure. - // - // Since bitfields can only partially overlap other bitfields, because we - // always emit components of bitfields as i8, and because we never emit tail - // padding until we know it exists, this boils down to merging pieces of the - // bitfield values into i8's. This is also simplified by the fact that - // bitfields can only be initialized by ConstantInts. An interesting case is - // sharing of tail padding in C++ structures. Because this can only happen - // in inheritance cases, and those are non-POD, we should never see them here. - - // First handle any part of Val that overlaps an already laid out field by - // merging it into it. By the above invariants, we know that it is an i8 that - // we are merging into. Note that we may be inserting *all* of Val into the - // previous field. - if (GCCFieldOffsetInBits < NextFieldByteStart*8) { - unsigned ValBitSize = ValC->getBitWidth(); - assert(!ResultElts.empty() && "Bitfield starts before first element?"); - assert(ResultElts.back()->getType()->isIntegerTy(8) && - isa(ResultElts.back()) && - "Merging bitfield with non-bitfield value?"); - assert(NextFieldByteStart*8 - GCCFieldOffsetInBits < 8 && - "Bitfield overlaps backwards more than one field?"); - - // Figure out how many bits can fit into the previous field given the - // starting point in that field. - unsigned BitsInPreviousField = - unsigned(NextFieldByteStart*8 - GCCFieldOffsetInBits); - assert(BitsInPreviousField != 0 && "Previous field should not be null!"); - - // Split the bits that will be inserted into the previous element out of - // Val into a new constant. If Val is completely contained in the previous - // element, this sets Val to null, otherwise we shrink Val to contain the - // bits to insert in the next element. - APInt ValForPrevField(ValC->getValue()); - if (BitsInPreviousField >= ValBitSize) { - // The whole field fits into the previous field. - ValC = 0; - } else if (!BYTES_BIG_ENDIAN) { - // Little endian, take bits from the bottom of the field value. - ValForPrevField = ValForPrevField.trunc(BitsInPreviousField); - APInt Tmp = ValC->getValue(); - Tmp = Tmp.lshr(BitsInPreviousField); - Tmp = Tmp.trunc(ValBitSize-BitsInPreviousField); - ValC = ConstantInt::get(Context, Tmp); - } else { - // Big endian, take bits from the top of the field value. - ValForPrevField = ValForPrevField.lshr(ValBitSize-BitsInPreviousField); - ValForPrevField = ValForPrevField.trunc(BitsInPreviousField); - - APInt Tmp = ValC->getValue(); - Tmp = Tmp.trunc(ValBitSize-BitsInPreviousField); - ValC = ConstantInt::get(Context, Tmp); - } - - // Okay, we're going to insert ValForPrevField into the previous i8, extend - // it and shift into place. - ValForPrevField = ValForPrevField.zext(8); - if (!BYTES_BIG_ENDIAN) { - ValForPrevField = ValForPrevField.shl(8-BitsInPreviousField); - } else { - // On big endian, if the entire field fits into the remaining space, shift - // over to not take part of the next field's bits. - if (BitsInPreviousField > ValBitSize) - ValForPrevField = ValForPrevField.shl(BitsInPreviousField-ValBitSize); - } - - // "or" in the previous value and install it. - const APInt &LastElt = cast(ResultElts.back())->getValue(); - ResultElts.back() = ConstantInt::get(Context, ValForPrevField | LastElt); - - // If the whole bit-field fit into the previous field, we're done. - if (ValC == 0) return; - GCCFieldOffsetInBits = NextFieldByteStart*8; - } - - APInt Val = ValC->getValue(); - - // Okay, we know that we're plopping bytes onto the end of the struct. - // Iterate while there is stuff to do. - while (1) { - ConstantInt *ValToAppend; - if (Val.getBitWidth() > 8) { - if (!BYTES_BIG_ENDIAN) { - // Little endian lays out low bits first. - APInt Tmp = Val.trunc(8); - ValToAppend = ConstantInt::get(Context, Tmp); - - Val = Val.lshr(8); +static Constant *ConvertRecordCONSTRUCTOR(tree exp) { + // FIXME: This new logic, especially the handling of bitfields, is untested + // and probably wrong on big-endian machines. + IntervalList Layout; + const TargetData &TD = getTargetData(); + uint64_t TypeSize = TD.getTypeAllocSizeInBits(ConvertType(TREE_TYPE(exp))); + + // Ensure that fields without an initial value are default initialized by + // explicitly setting the starting value for all fields to be zero. If an + // initial value is supplied for a field then the value will overwrite and + // replace the zero starting value later. + if (flag_default_initialize_globals) { + for (tree field = TYPE_FIELDS(TREE_TYPE(exp)); field; + field = TREE_CHAIN(field)) { + // Skip contained methods, types etc. + if (TREE_CODE(field) != FIELD_DECL) + continue; + // If the field has variable or unknown position then it cannot be default + // initialized - skip it. + if (!OffsetIsLLVMCompatible(field)) + continue; + uint64_t FirstBit = getFieldOffsetInBits(field); + assert(FirstBit <= TypeSize && "Field off end of type!"); + // Determine the width of the field. + uint64_t BitWidth; + if (DECL_SIZE(field) && isInt64(DECL_SIZE(field), true)) { + // The field has a size and it is a constant, so use it. Note that + // this size may be smaller than the type size. For example, if the + // next field starts inside alignment padding at the end of this one + // then DECL_SIZE will be the size with the padding used by the next + // field not included. + BitWidth = getInt64(DECL_SIZE(field), true); } else { - // Big endian lays out high bits first. - APInt Tmp = Val.lshr(Val.getBitWidth()-8).trunc(8); - ValToAppend = ConstantInt::get(Context, Tmp); + // If the field has variable or unknown size then use the size of the + // LLVM type instead as it gives the minimum size the field may have. + const Type *FieldTy = ConvertType(TREE_TYPE(field)); + if (!FieldTy->isSized()) + // An incomplete type - this field cannot be default initialized. + continue; + BitWidth = TD.getTypeAllocSizeInBits(FieldTy); + if (FirstBit + BitWidth > TypeSize) + BitWidth = TypeSize - FirstBit; } - } else if (Val.getBitWidth() == 8) { - ValToAppend = ConstantInt::get(Context, Val); - } else { - APInt Tmp = Val.zext(8); + uint64_t LastBit = FirstBit + BitWidth; - if (BYTES_BIG_ENDIAN) - Tmp = Tmp << 8-Val.getBitWidth(); - ValToAppend = ConstantInt::get(Context, Tmp); + // Zero the bits occupied by the field. + Layout.AddInterval(FieldContents::getZero(FirstBit, LastBit)); } - - ResultElts.push_back(ValToAppend); - ++NextFieldByteStart; - - if (Val.getBitWidth() <= 8) - break; - Val = Val.trunc(Val.getBitWidth()-8); } -} - -/// HandleTailPadding - Check to see if the struct fields, as laid out so far, -/// will be large enough to make the generated constant struct have the right -/// size. If not, add explicit tail padding. If rounding up based on the LLVM -/// IR alignment would make the struct too large, convert it to a packed LLVM -/// struct. -void ConstantLayoutInfo::HandleTailPadding(uint64_t GCCStructBitSize) { - uint64_t GCCStructSize = (GCCStructBitSize+7)/8; - uint64_t LLVMNaturalSize = - TargetData::RoundUpAlignment(NextFieldByteStart, MaxLLVMFieldAlignment); - - // If the total size of the laid out data is within the size of the GCC type - // but the rounded-up size (including the tail padding induced by LLVM - // alignment) is too big, convert to a packed struct type. We don't do this - // if the size of the laid out fields is too large because initializers like - // - // struct X { int A; char C[]; } x = { 4, "foo" }; - // - // can occur and no amount of packing will help. - if (NextFieldByteStart <= GCCStructSize && // Not flexible init case. - LLVMNaturalSize > GCCStructSize) { // Tail pad will overflow type. - assert(!StructIsPacked && "LLVM Struct type overflow!"); - - // Switch to packed. - ConvertToPacked(); - LLVMNaturalSize = NextFieldByteStart; - - // Verify that packing solved the problem. - assert(LLVMNaturalSize <= GCCStructSize && - "Oversized should be handled by packing"); - } - - // If the LLVM Size is too small, add some tail padding to fill it in. - if (LLVMNaturalSize < GCCStructSize) { - const Type *FillTy = Type::getInt8Ty(Context); - if (GCCStructSize - NextFieldByteStart != 1) - FillTy = ArrayType::get(FillTy, GCCStructSize - NextFieldByteStart); - ResultElts.push_back(Constant::getNullValue(FillTy)); - NextFieldByteStart = GCCStructSize; - - // At this point, we know that our struct should have the right size. - // However, if the size of the struct is not a multiple of the largest - // element alignment, the rounding could bump up the struct more. In this - // case, we have to convert the struct to being packed. - LLVMNaturalSize = - TargetData::RoundUpAlignment(NextFieldByteStart, MaxLLVMFieldAlignment); - - // If the alignment will make the struct too big, convert it to being - // packed. - if (LLVMNaturalSize > GCCStructSize) { - assert(!StructIsPacked && "LLVM Struct type overflow!"); - ConvertToPacked(); - } - } -} - -static Constant *ConvertRecordCONSTRUCTOR(tree exp) { - ConstantLayoutInfo LayoutInfo(getTargetData()); - - tree NextField = TYPE_FIELDS(TREE_TYPE(exp)); - unsigned HOST_WIDE_INT CtorIndex; - tree FieldValue; - tree Field; // The FIELD_DECL for the field. - FOR_EACH_CONSTRUCTOR_ELT(CONSTRUCTOR_ELTS(exp), CtorIndex, Field, FieldValue){ - // If an explicit field is specified, use it. - if (Field == 0) { - Field = NextField; - // Advance to the next FIELD_DECL, skipping over other structure members - // (e.g. enums). + // For each field for which an initial value was specified, set the bits + // occupied by the field to that value. + unsigned HOST_WIDE_INT idx; + tree field, next_field, value; + next_field = TYPE_FIELDS(TREE_TYPE(exp)); + FOR_EACH_CONSTRUCTOR_ELT(CONSTRUCTOR_ELTS(exp), idx, field, value) { + if (!field) { + // Move on to the next FIELD_DECL, skipping contained methods, types etc. + field = next_field; while (1) { - assert(Field && "Fell off end of record!"); - if (TREE_CODE(Field) == FIELD_DECL) break; - Field = TREE_CHAIN(Field); + assert(field && "Fell off end of record!"); + if (TREE_CODE(field) == FIELD_DECL) break; + field = TREE_CHAIN(field); } } + next_field = TREE_CHAIN(field); - // Decode the field's value. - Constant *Val = ConvertInitializer(FieldValue); - - // GCCFieldOffsetInBits is where GCC is telling us to put the current field. - uint64_t GCCFieldOffsetInBits = getFieldOffsetInBits(Field); - NextField = TREE_CHAIN(Field); - - uint64_t FieldSizeInBits = 0; - if (DECL_SIZE(Field)) - FieldSizeInBits = getInt64(DECL_SIZE(Field), true); - uint64_t ValueSizeInBits = Val->getType()->getPrimitiveSizeInBits(); - ConstantInt *ValC = dyn_cast(Val); - if (ValC && ValC->isZero() && DECL_SIZE(Field)) { - // G++ has various bugs handling {} initializers where it doesn't - // synthesize a zero node of the right type. Instead of figuring out G++, - // just hack around it by special casing zero and allowing it to be the - // wrong size. - if (ValueSizeInBits != FieldSizeInBits) { - APInt ValAsInt = ValC->getValue(); - ValC = ConstantInt::get(Context, ValueSizeInBits < FieldSizeInBits ? - ValAsInt.zext(FieldSizeInBits) : - ValAsInt.trunc(FieldSizeInBits)); - ValueSizeInBits = FieldSizeInBits; - Val = ValC; - } + assert(TREE_CODE(field) == FIELD_DECL && "Initial value not for a field!"); + assert(OffsetIsLLVMCompatible(field) && "Field position not known!"); + // Turn the initial value for this field into an LLVM constant. + Constant *Init = ConvertInitializer(value); + // Work out the range of bits occupied by the field. + uint64_t FirstBit = getFieldOffsetInBits(field); + assert(FirstBit <= TypeSize && "Field off end of type!"); + // If a size was specified for the field then use it. Otherwise take the + // size from the initial value. + uint64_t BitWidth = DECL_SIZE(field) && isInt64(DECL_SIZE(field), true) ? + getInt64(DECL_SIZE(field), true) : + TD.getTypeAllocSizeInBits(Init->getType()); + uint64_t LastBit = FirstBit + BitWidth; + + // Set the bits occupied by the field to the initial value. + Layout.AddInterval(FieldContents::getConstant(FirstBit, LastBit, Init)); + } + + // Force all fields to begin and end on a byte boundary. This automagically + // takes care of bitfields. + Layout.AlignBoundaries(BITS_PER_UNIT); + + // Determine whether to return a packed struct. If returning an ordinary + // struct would result in an initializer that is more aligned than its GCC + // type then return a packed struct instead. If a field's alignment would + // make it start after its desired position then also use a packed struct. + bool Pack = false; + unsigned MaxAlign = TYPE_ALIGN(TREE_TYPE(exp)); + for (unsigned i = 0, e = Layout.getNumIntervals(); i != e; ++i) { + FieldContents F = Layout.getInterval(i); + unsigned First = F.getRange().getFirst(); + Constant *Val = F.extractContents(TD); + unsigned Alignment = TD.getABITypeAlignment(Val->getType()) * 8; + if (Alignment > MaxAlign || First % Alignment) { + Pack = true; + break; } + } - // If this is a non-bitfield value, just slap it onto the end of the struct - // with the appropriate padding etc. If it is a bitfield, we have more - // processing to do. - if (!isBitfield(Field)) - LayoutInfo.AddFieldToRecordConstant(Val, GCCFieldOffsetInBits); - else { - // Bitfields can only be initialized with constants (integer constant - // expressions). - assert(ValC); - assert(DECL_SIZE(Field)); - assert(ValueSizeInBits >= FieldSizeInBits && - "disagreement between LLVM and GCC on bitfield size"); - if (ValueSizeInBits != FieldSizeInBits) { - // Fields are allowed to be smaller than their type. Simply discard - // the unwanted upper bits in the field value. - APInt ValAsInt = ValC->getValue(); - ValC = ConstantInt::get(Context, ValAsInt.trunc(FieldSizeInBits)); + // Create the elements that will make up the struct. As well as the fields + // themselves there may also be padding elements. + std::vector Elts; + Elts.reserve(Layout.getNumIntervals()); + unsigned EndOfPrevious = 0; // Offset of first bit after previous element. + for (unsigned i = 0, e = Layout.getNumIntervals(); i != e; ++i) { + FieldContents F = Layout.getInterval(i); + unsigned First = F.getRange().getFirst(); + Constant *Val = F.extractContents(TD); + assert(EndOfPrevious <= First && "Previous field too big!"); + + // If there is a gap then we may need to fill it with padding. + if (First > EndOfPrevious) { + // There is a gap between the end of the previous field and the start of + // this one. The alignment of the field contents may mean that it will + // start at the right offset anyway, but if not then insert padding. + bool NeedPadding = true; + if (!Pack) { + // If the field's alignment will take care of the gap then there is no + // need for padding. + unsigned Alignment = TD.getABITypeAlignment(Val->getType()) * 8; + if (First == (EndOfPrevious + Alignment - 1) / Alignment * Alignment) + NeedPadding = false; + } + if (NeedPadding) { + // Fill the gap with undefined bytes. + assert((First - EndOfPrevious) % BITS_PER_UNIT == 0 && + "Non-unit field boundaries!"); + unsigned Units = (First - EndOfPrevious) / BITS_PER_UNIT; + Elts.push_back(UndefValue::get(GetUnitType(Context, Units))); } - LayoutInfo.AddBitFieldToRecordConstant(ValC, GCCFieldOffsetInBits); } - } - - // Check to see if the struct fields, as laid out so far, will be large enough - // to make the generated constant struct have the right size. If not, add - // explicit tail padding. If rounding up based on the LLVM IR alignment would - // make the struct too large, convert it to a packed LLVM struct. - tree StructTypeSizeTree = TYPE_SIZE(TREE_TYPE(exp)); - if (StructTypeSizeTree && TREE_CODE(StructTypeSizeTree) == INTEGER_CST) - LayoutInfo.HandleTailPadding(getInt64(StructTypeSizeTree, true)); - - // Okay, we're done, return the computed elements. - return ConstantStruct::get(Context, LayoutInfo.ResultElts, - LayoutInfo.StructIsPacked); -} -static Constant *ConvertUnionCONSTRUCTOR(tree exp) { - assert(!VEC_empty(constructor_elt, CONSTRUCTOR_ELTS(exp)) - && "Union CONSTRUCTOR has no elements? Zero?"); - - VEC(constructor_elt, gc) *elt = CONSTRUCTOR_ELTS(exp); - assert(VEC_length(constructor_elt, elt) == 1 - && "Union CONSTRUCTOR with multiple elements?"); - - ConstantLayoutInfo LayoutInfo(getTargetData()); - - // Convert the constant itself. - Constant *Val = ConvertInitializer(VEC_index(constructor_elt, elt, 0)->value); - - // Unions are initialized using the first member field. Find it. - tree Field = TYPE_FIELDS(TREE_TYPE(exp)); - assert(Field && "cannot initialize union with no fields"); - while (TREE_CODE(Field) != FIELD_DECL) { - Field = TREE_CHAIN(Field); - assert(Field && "cannot initialize union with no fields"); - } - - // If this is a non-bitfield value, just slap it onto the end of the struct - // with the appropriate padding etc. If it is a bitfield, we have more - // processing to do. - if (!isBitfield(Field)) - LayoutInfo.AddFieldToRecordConstant(Val, 0); - else { - // Bitfields can only be initialized with constants (integer constant - // expressions). - ConstantInt *ValC = cast(Val); - uint64_t FieldSizeInBits = getInt64(DECL_SIZE(Field), true); - uint64_t ValueSizeInBits = Val->getType()->getPrimitiveSizeInBits(); - - assert(ValueSizeInBits >= FieldSizeInBits && - "disagreement between LLVM and GCC on bitfield size"); - if (ValueSizeInBits != FieldSizeInBits) { - // Fields are allowed to be smaller than their type. Simply discard - // the unwanted upper bits in the field value. - APInt ValAsInt = ValC->getValue(); - ValC = ConstantInt::get(Context, ValAsInt.trunc(FieldSizeInBits)); - } - LayoutInfo.AddBitFieldToRecordConstant(ValC, 0); + // Append the field. + Elts.push_back(Val); + EndOfPrevious = First + TD.getTypeAllocSizeInBits(Val->getType()); } - // If the union has a fixed size, and if the value we converted isn't large - // enough to fill all the bits, add a zero initialized array at the end to pad - // it out. - tree UnionTypeSizeTree = TYPE_SIZE(TREE_TYPE(exp)); - if (UnionTypeSizeTree && TREE_CODE(UnionTypeSizeTree) == INTEGER_CST) - LayoutInfo.HandleTailPadding(getInt64(UnionTypeSizeTree, true)); + // We guarantee that initializers are always at least as big as the LLVM type + // for the initializer. If needed, append padding to ensure this. + if (EndOfPrevious < TypeSize) { + assert((TypeSize - EndOfPrevious) % BITS_PER_UNIT == 0 && + "Non-unit type size?"); + unsigned Units = (TypeSize - EndOfPrevious) / BITS_PER_UNIT; + Elts.push_back(UndefValue::get(GetUnitType(Context, Units))); + } - return ConstantStruct::get(Context, LayoutInfo.ResultElts, - LayoutInfo.StructIsPacked); + // Okay, we're done, return the computed elements. + return ConstantStruct::get(Context, Elts, Pack); } static Constant *ConvertCONSTRUCTOR(tree exp) { @@ -1126,9 +989,9 @@ assert(0 && "Unknown ctor!"); case VECTOR_TYPE: case ARRAY_TYPE: return ConvertArrayCONSTRUCTOR(exp); - case RECORD_TYPE: return ConvertRecordCONSTRUCTOR(exp); case QUAL_UNION_TYPE: - case UNION_TYPE: return ConvertUnionCONSTRUCTOR(exp); + case RECORD_TYPE: + case UNION_TYPE: return ConvertRecordCONSTRUCTOR(exp); } } Modified: dragonegg/trunk/Constants.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.h?rev=128473&r1=128472&r2=128473&view=diff ============================================================================== --- dragonegg/trunk/Constants.h (original) +++ dragonegg/trunk/Constants.h Tue Mar 29 13:44:32 2011 @@ -1,4 +1,4 @@ -//=----- Constants.h - Converting and working with constants --*- C++ -*-----=// +//=----- Constants.h - Converting and working with constants ------*- C++ -*-=// // // Copyright (C) 2011 Duncan Sands. // @@ -55,6 +55,6 @@ /// the first bit stored being 'StartingBit') and then loading out a (constant) /// value of type 'Ty' from the stored to memory location. extern llvm::Constant *InterpretAsType(llvm::Constant *C, const llvm::Type* Ty, - unsigned StartingBit); + int StartingBit); #endif /* DRAGONEGG_CONSTANTS_H */ From akyrtzi at gmail.com Tue Mar 29 13:53:00 2011 From: akyrtzi at gmail.com (Argyrios Kyrtzidis) Date: Tue, 29 Mar 2011 18:53:00 -0000 Subject: [llvm-commits] [llvm] r128474 - /llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Message-ID: <20110329185300.BD8AE2A6C12C@llvm.org> Author: akirtzidis Date: Tue Mar 29 13:53:00 2011 New Revision: 128474 URL: http://llvm.org/viewvc/llvm-project?rev=128474&view=rev Log: For ClangSACheckersEmitter, allow a package to belong to checker group, in which all its checkers will go into the group. Modified: llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp?rev=128474&r1=128473&r2=128474&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Tue Mar 29 13:53:00 2011 @@ -71,7 +71,7 @@ namespace { struct GroupInfo { - std::vector Checkers; + llvm::DenseSet Checkers; llvm::DenseSet SubGroups; bool Hidden; unsigned Index; @@ -80,6 +80,19 @@ }; } +static void addPackageToCheckerGroup(const Record *package, const Record *group, + llvm::DenseMap &recordGroupMap) { + llvm::DenseSet &checkers = recordGroupMap[package]->Checkers; + for (llvm::DenseSet::iterator + I = checkers.begin(), E = checkers.end(); I != E; ++I) + recordGroupMap[group]->Checkers.insert(*I); + + llvm::DenseSet &subGroups = recordGroupMap[package]->SubGroups; + for (llvm::DenseSet::iterator + I = subGroups.begin(), E = subGroups.end(); I != E; ++I) + addPackageToCheckerGroup(*I, group, recordGroupMap); +} + void ClangSACheckersEmitter::run(raw_ostream &OS) { std::vector checkers = Records.getAllDerivedDefinitions("Checker"); llvm::DenseMap checkerRecIndexMap; @@ -150,9 +163,9 @@ GroupInfo &info = groupInfoByName[fullName]; info.Hidden = R->getValueAsBit("Hidden"); recordGroupMap[R] = &info; - info.Checkers.push_back(R); + info.Checkers.insert(R); } else { - recordGroupMap[package]->Checkers.push_back(R); + recordGroupMap[package]->Checkers.insert(R); } Record *currR = isCheckerNamed(R) ? R : package; @@ -166,9 +179,15 @@ } // Insert the checker into the set of its group. if (DefInit *DI = dynamic_cast(R->getValueInit("Group"))) - recordGroupMap[DI->getDef()]->Checkers.push_back(R); + recordGroupMap[DI->getDef()]->Checkers.insert(R); } + // If a package is in group, add all its checkers and its sub-packages + // checkers into the group. + for (unsigned i = 0, e = packages.size(); i != e; ++i) + if (DefInit *DI = dynamic_cast(packages[i]->getValueInit("Group"))) + addPackageToCheckerGroup(packages[i], DI->getDef(), recordGroupMap); + unsigned index = 0; for (std::map::iterator I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) @@ -183,11 +202,12 @@ I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) { maxLen = std::max(maxLen, (unsigned)I->first.size()); - std::vector &V = I->second.Checkers; - if (!V.empty()) { + llvm::DenseSet &checkers = I->second.Checkers; + if (!checkers.empty()) { OS << "static const short CheckerArray" << I->second.Index << "[] = { "; - for (unsigned i = 0, e = V.size(); i != e; ++i) - OS << checkerRecIndexMap[V[i]] << ", "; + for (llvm::DenseSet::iterator + I = checkers.begin(), E = checkers.end(); I != E; ++I) + OS << checkerRecIndexMap[*I] << ", "; OS << "-1 };\n"; } From johnny.chen at apple.com Tue Mar 29 14:08:53 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 29 Mar 2011 19:08:53 -0000 Subject: [llvm-commits] [llvm] r128476 - in /llvm/trunk/test/MC/Disassembler/ARM: arm-tests.txt invalid-VLDMSDB-arm.txt Message-ID: <20110329190853.1238E2A6C12C@llvm.org> Author: johnny Date: Tue Mar 29 14:08:52 2011 New Revision: 128476 URL: http://llvm.org/viewvc/llvm-project?rev=128476&view=rev Log: Add and modify some tests. Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=128476&r1=128475&r2=128476&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Tue Mar 29 14:08:52 2011 @@ -173,6 +173,12 @@ # CHECK: vcmpe.f64 d8, #0 0xc0 0x8b 0xb5 0xee +# CHECK: vldmdb r2!, {s7, s8, s9, s10, s11} +0x05 0x3a 0x72 0xed + +# CHECK: vldr.32 s23, [r2, #660] +0xa5 0xba 0xd2 0xed + # CHECK: strtvc r5, [r3], r0, lsr #20 0x30 0x5a 0xa3 0x76 Modified: llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt?rev=128476&r1=128475&r2=128476&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt Tue Mar 29 14:08:52 2011 @@ -1,5 +1,4 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} -# XFAIL: * # core registers out of range -0xa5 0xba 0xd2 0xed +0xa5 0xba 0x72 0xed From johnny.chen at apple.com Tue Mar 29 14:10:06 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 29 Mar 2011 19:10:06 -0000 Subject: [llvm-commits] [llvm] r128477 - in /llvm/trunk/test/MC/Disassembler/ARM: invalid-VLDMSDB-arm.txt invalid-VLDMSDB_UPD-arm.txt Message-ID: <20110329191006.35E072A6C12C@llvm.org> Author: johnny Date: Tue Mar 29 14:10:06 2011 New Revision: 128477 URL: http://llvm.org/viewvc/llvm-project?rev=128477&view=rev Log: Rename invalid-VLDMSDB-arm.txt to be invalid-VLDMSDB_UPD-arm.txt. Added: llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB_UPD-arm.txt - copied unchanged from r128476, llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt Removed: llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt Removed: llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt?rev=128476&view=auto ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt (removed) @@ -1,4 +0,0 @@ -# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} - -# core registers out of range -0xa5 0xba 0x72 0xed From johnny.chen at apple.com Tue Mar 29 14:49:39 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 29 Mar 2011 19:49:39 -0000 Subject: [llvm-commits] [llvm] r128478 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td test/MC/Disassembler/ARM/arm-tests.txt Message-ID: <20110329194939.2AA202A6C12C@llvm.org> Author: johnny Date: Tue Mar 29 14:49:38 2011 New Revision: 128478 URL: http://llvm.org/viewvc/llvm-project?rev=128478&view=rev Log: A8.6.188 STC, STC2 The STC_OPTION and STC2_OPTION instructions should have their coprocessor option enclosed in {}. rdar://problem/9200661 Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128478&r1=128477&r2=128478&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Mar 29 14:49:38 2011 @@ -3430,8 +3430,8 @@ } def _OPTION : ACI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option), - opc, "\tp$cop, cr$CRd, [$base], $option"> { + (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option), + opc, "\tp$cop, cr$CRd, [$base], \\{$option\\}"> { let Inst{31-28} = op31_28; let Inst{24} = 0; // P = 0 let Inst{23} = 1; // U = 1 @@ -3472,7 +3472,7 @@ def L_OPTION : ACI<(outs), (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> { + !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], \\{$option\\}"> { let Inst{31-28} = op31_28; let Inst{24} = 0; // P = 0 let Inst{23} = 1; // U = 1 Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=128478&r1=128477&r2=128478&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Tue Mar 29 14:49:38 2011 @@ -202,3 +202,9 @@ # CHECK: pli [r3, r1, lsl #2] 0x01 0xf1 0xd3 0xf6 + +# CHECK: stc p2, cr4, [r9], {157} +0x9d 0x42 0x89 0xec + +# CHECK: stc2 p2, cr4, [r9], {157} +0x9d 0x42 0x89 0xfc From tilmann.scheller at googlemail.com Tue Mar 29 15:28:52 2011 From: tilmann.scheller at googlemail.com (Tilmann Scheller) Date: Tue, 29 Mar 2011 22:28:52 +0200 Subject: [llvm-commits] [llvm] r128474 - /llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp In-Reply-To: <20110329185300.BD8AE2A6C12C@llvm.org> References: <20110329185300.BD8AE2A6C12C@llvm.org> Message-ID: Hi Argyrios, please don't use a data structure whose order is non-determinstic (walking over a DenseSet gives different results depending on the memory layout), this leads to Checkers.inc being different on every run :) Regards, Tilmann On Tue, Mar 29, 2011 at 8:53 PM, Argyrios Kyrtzidis wrote: > Author: akirtzidis > Date: Tue Mar 29 13:53:00 2011 > New Revision: 128474 > > URL: http://llvm.org/viewvc/llvm-project?rev=128474&view=rev > Log: > For ClangSACheckersEmitter, allow a package to belong to checker group, in > which all its checkers will go into the group. > > Modified: > llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp > > Modified: llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp?rev=128474&r1=128473&r2=128474&view=diff > > ============================================================================== > --- llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp (original) > +++ llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Tue Mar 29 > 13:53:00 2011 > @@ -71,7 +71,7 @@ > > namespace { > struct GroupInfo { > - std::vector Checkers; > + llvm::DenseSet Checkers; > llvm::DenseSet SubGroups; > bool Hidden; > unsigned Index; > @@ -80,6 +80,19 @@ > }; > } > > +static void addPackageToCheckerGroup(const Record *package, const Record > *group, > + llvm::DenseMap > &recordGroupMap) { > + llvm::DenseSet &checkers = > recordGroupMap[package]->Checkers; > + for (llvm::DenseSet::iterator > + I = checkers.begin(), E = checkers.end(); I != E; ++I) > + recordGroupMap[group]->Checkers.insert(*I); > + > + llvm::DenseSet &subGroups = > recordGroupMap[package]->SubGroups; > + for (llvm::DenseSet::iterator > + I = subGroups.begin(), E = subGroups.end(); I != E; ++I) > + addPackageToCheckerGroup(*I, group, recordGroupMap); > +} > + > void ClangSACheckersEmitter::run(raw_ostream &OS) { > std::vector checkers = > Records.getAllDerivedDefinitions("Checker"); > llvm::DenseMap checkerRecIndexMap; > @@ -150,9 +163,9 @@ > GroupInfo &info = groupInfoByName[fullName]; > info.Hidden = R->getValueAsBit("Hidden"); > recordGroupMap[R] = &info; > - info.Checkers.push_back(R); > + info.Checkers.insert(R); > } else { > - recordGroupMap[package]->Checkers.push_back(R); > + recordGroupMap[package]->Checkers.insert(R); > } > > Record *currR = isCheckerNamed(R) ? R : package; > @@ -166,9 +179,15 @@ > } > // Insert the checker into the set of its group. > if (DefInit *DI = dynamic_cast(R->getValueInit("Group"))) > - recordGroupMap[DI->getDef()]->Checkers.push_back(R); > + recordGroupMap[DI->getDef()]->Checkers.insert(R); > } > > + // If a package is in group, add all its checkers and its sub-packages > + // checkers into the group. > + for (unsigned i = 0, e = packages.size(); i != e; ++i) > + if (DefInit *DI = > dynamic_cast(packages[i]->getValueInit("Group"))) > + addPackageToCheckerGroup(packages[i], DI->getDef(), recordGroupMap); > + > unsigned index = 0; > for (std::map::iterator > I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; > ++I) > @@ -183,11 +202,12 @@ > I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; > ++I) { > maxLen = std::max(maxLen, (unsigned)I->first.size()); > > - std::vector &V = I->second.Checkers; > - if (!V.empty()) { > + llvm::DenseSet &checkers = I->second.Checkers; > + if (!checkers.empty()) { > OS << "static const short CheckerArray" << I->second.Index << "[] = { > "; > - for (unsigned i = 0, e = V.size(); i != e; ++i) > - OS << checkerRecIndexMap[V[i]] << ", "; > + for (llvm::DenseSet::iterator > + I = checkers.begin(), E = checkers.end(); I != E; ++I) > + OS << checkerRecIndexMap[*I] << ", "; > OS << "-1 };\n"; > } > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110329/b82ddd84/attachment.html From resistor at mac.com Tue Mar 29 15:27:38 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 29 Mar 2011 20:27:38 -0000 Subject: [llvm-commits] [llvm] r128481 - /llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Message-ID: <20110329202739.010AB2A6C12C@llvm.org> Author: resistor Date: Tue Mar 29 15:27:38 2011 New Revision: 128481 URL: http://llvm.org/viewvc/llvm-project?rev=128481&view=rev Log: Check early if this is an unsupported opcode, so that we can avoid needlessly instantiating the base register in some cases. Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=128481&r1=128480&r2=128481&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Tue Mar 29 15:27:38 2011 @@ -308,6 +308,10 @@ // VLDM/VSTM do not support DB mode without also updating the base reg. Mode = ARM_AM::db; else if (Offset != 0) { + // Check if this is a supported opcode before we insert instructions to + // calculate a new base register. + if (!getLoadStoreMultipleOpcode(Opcode, Mode)) return false; + // If starting offset isn't zero, insert a MI to materialize a new base. // But only do so if it is cost effective, i.e. merging more than two // loads / stores. From benny.kra at googlemail.com Tue Mar 29 15:28:58 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 29 Mar 2011 20:28:58 -0000 Subject: [llvm-commits] [llvm] r128482 - /llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Message-ID: <20110329202858.24BE12A6C12C@llvm.org> Author: d0k Date: Tue Mar 29 15:28:57 2011 New Revision: 128482 URL: http://llvm.org/viewvc/llvm-project?rev=128482&view=rev Log: DSE: Remove an early exit optimization that depended on the ordering of a SmallPtrSet. Fixes PR9569 and will hopefully make selfhost on ASLR-enabled systems more deterministic. Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=128482&r1=128481&r2=128482&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Tue Mar 29 15:28:57 2011 @@ -640,28 +640,15 @@ if (AA->doesNotAccessMemory(CS)) continue; - unsigned NumModRef = 0, NumOther = 0; - // If the call might load from any of our allocas, then any store above // the call is live. SmallVector LiveAllocas; for (SmallPtrSet::iterator I = DeadStackObjects.begin(), E = DeadStackObjects.end(); I != E; ++I) { - // If we detect that our AA is imprecise, it's not worth it to scan the - // rest of the DeadPointers set. Just assume that the AA will return - // ModRef for everything, and go ahead and bail out. - if (NumModRef >= 16 && NumOther == 0) - return MadeChange; - // See if the call site touches it. AliasAnalysis::ModRefResult A = AA->getModRefInfo(CS, *I, getPointerSize(*I, *AA)); - if (A == AliasAnalysis::ModRef) - ++NumModRef; - else - ++NumOther; - if (A == AliasAnalysis::ModRef || A == AliasAnalysis::Ref) LiveAllocas.push_back(*I); } From ofv at wanadoo.es Tue Mar 29 15:51:08 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 29 Mar 2011 20:51:08 -0000 Subject: [llvm-commits] [llvm] r128484 - in /llvm/trunk/cmake/modules: AddLLVM.cmake LLVMConfig.cmake Message-ID: <20110329205108.BF0DB2A6C12C@llvm.org> Author: ofv Date: Tue Mar 29 15:51:08 2011 New Revision: 128484 URL: http://llvm.org/viewvc/llvm-project?rev=128484&view=rev Log: Fixed the build of Clang's unit tests on MinGW. Also removed some unnecesary conditionals and introduced a new convenience function. The problem was that the list of libraries for Clang's unit tests was . As the llvm libraries references symbols defined on the system libraries, those were reported as undefined. Modified: llvm/trunk/cmake/modules/AddLLVM.cmake llvm/trunk/cmake/modules/LLVMConfig.cmake Modified: llvm/trunk/cmake/modules/AddLLVM.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/AddLLVM.cmake?rev=128484&r1=128483&r2=128484&view=diff ============================================================================== --- llvm/trunk/cmake/modules/AddLLVM.cmake (original) +++ llvm/trunk/cmake/modules/AddLLVM.cmake Tue Mar 29 15:51:08 2011 @@ -11,10 +11,12 @@ if( BUILD_SHARED_LIBS ) llvm_config( ${name} ${LLVM_LINK_COMPONENTS} ) - get_system_libs(sl) - target_link_libraries( ${name} ${sl} ) endif() + # Ensure that the system libraries always comes last on the + # list. Without this, linking the unit tests on MinGW fails. + link_system_libs( ${name} ) + install(TARGETS ${name} LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}) @@ -47,8 +49,7 @@ set_target_properties( ${name} PROPERTIES PREFIX "" ) llvm_config( ${name} ${LLVM_LINK_COMPONENTS} ) - get_system_libs(sl) - target_link_libraries( ${name} ${sl} ) + link_system_libs( ${name} ) if (APPLE) # Darwin-specific linker flags for loadable modules. @@ -73,21 +74,12 @@ add_executable(${name} ${ALL_FILES}) endif() set(EXCLUDE_FROM_ALL OFF) - if( LLVM_USED_LIBS ) - foreach(lib ${LLVM_USED_LIBS}) - target_link_libraries( ${name} ${lib} ) - endforeach(lib) - endif( LLVM_USED_LIBS ) - if( LLVM_LINK_COMPONENTS ) - llvm_config(${name} ${LLVM_LINK_COMPONENTS}) - endif( LLVM_LINK_COMPONENTS ) + target_link_libraries( ${name} ${LLVM_USED_LIBS} ) + llvm_config( ${name} ${LLVM_LINK_COMPONENTS} ) if( LLVM_COMMON_DEPENDS ) add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} ) endif( LLVM_COMMON_DEPENDS ) - get_system_libs(llvm_system_libs) - if( llvm_system_libs ) - target_link_libraries(${name} ${llvm_system_libs}) - endif() + link_system_libs( ${name} ) endmacro(add_llvm_executable name) Modified: llvm/trunk/cmake/modules/LLVMConfig.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMConfig.cmake?rev=128484&r1=128483&r2=128484&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVMConfig.cmake (original) +++ llvm/trunk/cmake/modules/LLVMConfig.cmake Tue Mar 29 15:51:08 2011 @@ -16,6 +16,12 @@ endfunction(get_system_libs) +function(link_system_libs target) + get_system_libs(llvm_system_libs) + target_link_libraries(${target} ${llvm_system_libs}) +endfunction(link_system_libs) + + function(is_llvm_target_library library return_var) # Sets variable `return_var' to ON if `library' corresponds to a # LLVM supported target. To OFF if it doesn't. From clattner at apple.com Tue Mar 29 15:58:54 2011 From: clattner at apple.com (Chris Lattner) Date: Tue, 29 Mar 2011 13:58:54 -0700 Subject: [llvm-commits] [PATCH] remove PHINode::reserveOperandSpace() In-Reply-To: References: Message-ID: <49487A5A-0A5F-4CDA-9444-F09D0CE84535@apple.com> On Mar 29, 2011, at 1:25 AM, Jay Foad wrote: > I noticed that: > > - All calls to PHINode::reserveOperandSpace() are on newly created PHINodes. > - Most places that create a PHINode immediately call > reserveOperandSpace(), to reserve space for the (known or expected) > number of operands. > - Those that don't, probably should. > > These patches enforce and simplify this by making the number of > operands an argument to PHINode::Create(), and removing the > reserveOperandSpace() method altogether. > > The patches are: > > 1. (Almost) always call reserveOperandSpace() on newly created PHINodes. > 2. Add parameter to PHINode::Create() and remove PHINode::reserveOperandSpace(). > > Tested with "make check", LLVM and Clang. OK to apply? > > My motivation for working on this is that it removes one caller of > PHINode::resizeOperands(), which in turn should allow some > simplification of that function. Sounds great! -Chris From grosbach at apple.com Tue Mar 29 16:03:05 2011 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 29 Mar 2011 21:03:05 -0000 Subject: [llvm-commits] [llvm] r128485 - in /llvm/trunk: include/llvm/ExecutionEngine/RuntimeDyld.h lib/ExecutionEngine/MCJIT/MCJIT.cpp lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp tools/llvm-rtdyld/Makefile tools/llvm-rtdyld/llvm-rtdyld.cpp Message-ID: <20110329210305.9D6EC2A6C12C@llvm.org> Author: grosbach Date: Tue Mar 29 16:03:05 2011 New Revision: 128485 URL: http://llvm.org/viewvc/llvm-project?rev=128485&view=rev Log: Instantiate a JITMemoryManager for MCJIT Dyld Modified: llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp llvm/trunk/tools/llvm-rtdyld/Makefile llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp Modified: llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h?rev=128485&r1=128484&r2=128485&view=diff ============================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h (original) +++ llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h Tue Mar 29 16:03:05 2011 @@ -21,6 +21,7 @@ class RuntimeDyldImpl; class MemoryBuffer; +class JITMemoryManager; class RuntimeDyld { RuntimeDyld(const RuntimeDyld &); // DO NOT IMPLEMENT @@ -30,7 +31,7 @@ // interface. RuntimeDyldImpl *Dyld; public: - RuntimeDyld(); + RuntimeDyld(JITMemoryManager*); ~RuntimeDyld(); bool loadObject(MemoryBuffer *InputBuffer); Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=128485&r1=128484&r2=128485&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp Tue Mar 29 16:03:05 2011 @@ -67,7 +67,7 @@ MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji, JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool AllocateGVsWithCode) - : ExecutionEngine(m), TM(tm), M(m), OS(Buffer) { + : ExecutionEngine(m), TM(tm), M(m), OS(Buffer), Dyld(JMM) { PM.add(new TargetData(*TM->getTargetData())); Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=128485&r1=128484&r2=128485&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Tue Mar 29 16:03:05 2011 @@ -18,6 +18,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" +#include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/Object/MachOObject.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -34,6 +35,9 @@ unsigned CPUType; unsigned CPUSubtype; + // The JITMemoryManager to load objects into. + JITMemoryManager *JMM; + // Master symbol table. As modules are loaded and external symbols are // resolved, their addresses are stored here. StringMap SymbolTable; @@ -68,7 +72,7 @@ const InMemoryStruct &SymtabLC); public: - RuntimeDyldImpl() : HasError(false) {} + RuntimeDyldImpl(JITMemoryManager *jmm) : JMM(jmm), HasError(false) {} bool loadObject(MemoryBuffer *InputBuffer); @@ -526,8 +530,8 @@ //===----------------------------------------------------------------------===// // RuntimeDyld class implementation -RuntimeDyld::RuntimeDyld() { - Dyld = new RuntimeDyldImpl; +RuntimeDyld::RuntimeDyld(JITMemoryManager *JMM) { + Dyld = new RuntimeDyldImpl(JMM); } RuntimeDyld::~RuntimeDyld() { Modified: llvm/trunk/tools/llvm-rtdyld/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/Makefile?rev=128485&r1=128484&r2=128485&view=diff ============================================================================== --- llvm/trunk/tools/llvm-rtdyld/Makefile (original) +++ llvm/trunk/tools/llvm-rtdyld/Makefile Tue Mar 29 16:03:05 2011 @@ -18,6 +18,6 @@ # early so we can set up LINK_COMPONENTS before including Makefile.rules include $(LEVEL)/Makefile.config -LINK_COMPONENTS := $(TARGETS_TO_BUILD) support MC object RuntimeDyld +LINK_COMPONENTS := $(TARGETS_TO_BUILD) support MC object RuntimeDyld JIT include $(LLVM_SRC_ROOT)/Makefile.rules Modified: llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp?rev=128485&r1=128484&r2=128485&view=diff ============================================================================== --- llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp (original) +++ llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp Tue Mar 29 16:03:05 2011 @@ -13,6 +13,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/Object/MachOObject.h" #include "llvm/Support/CommandLine.h" @@ -60,7 +61,7 @@ return Error("unable to read input: '" + ec.message() + "'"); // Instantiate a dynamic linker. - RuntimeDyld Dyld; + RuntimeDyld Dyld(JITMemoryManager::CreateDefaultMemManager()); // Load the object file into it. if (Dyld.loadObject(InputBuffer.take())) { From johnny.chen at apple.com Tue Mar 29 16:09:30 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 29 Mar 2011 21:09:30 -0000 Subject: [llvm-commits] [llvm] r128487 - /llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt Message-ID: <20110329210930.578292A6C12C@llvm.org> Author: johnny Date: Tue Mar 29 16:09:30 2011 New Revision: 128487 URL: http://llvm.org/viewvc/llvm-project?rev=128487&view=rev Log: Add a thumb test file for printf (iOS 4.3). Added: llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt Added: llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt?rev=128487&view=auto ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt (added) +++ llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt Tue Mar 29 16:09:30 2011 @@ -0,0 +1,76 @@ +# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 | FileCheck %s + +# CHECK: push {r0, r1, r2, r3} +# CHECK-NEXT: push {r4, r5, r7, lr} +# CHECK-NEXT: add r7, sp, #8 +# CHECK-NEXT: sub sp, #4 +# CHECK-NEXT: add r3, sp, #20 +# CHECK-NEXT: ldr r5, [r3], #4 +# CHECK-NEXT: str r3, [sp] +# CHECK-NEXT: ldr.n r3, #52 +# CHECK-NEXT: add r3, pc +# CHECK-NEXT: ldr r0, [r3] +# CHECK-NEXT: ldr r4, [r0] +# CHECK-NEXT: ldr.n r0, #48 +# CHECK-NEXT: add r0, pc +# CHECK-NEXT: ldr r0, [r0] +# CHECK-NEXT: ldr r0, [r0] +# CHECK-NEXT: blx #191548 +# CHECK-NEXT: cbnz r0, #6 +# CHECK-NEXT: ldr.n r1, #40 +# CHECK-NEXT: add r1, pc +# CHECK-NEXT: ldr r1, [r1] +# CHECK-NEXT: b #0 +# CHECK-NEXT: mov r1, r0 +# CHECK-NEXT: mov r0, r4 +# CHECK-NEXT: mov r2, r5 +# CHECK-NEXT: ldr r3, [sp] +# CHECK-NEXT: bl #-8390 +# CHECK-NEXT: sub.w sp, r7, #8 +# CHECK-NEXT: pop.w {r4, r5, r7, lr} +# CHECK-NEXT: add sp, #16 +# CHECK-NEXT: bx lr +# CHECK-NEXT: nop +# CHECK-NEXT: movs r3, #142 +# CHECK-NEXT: movs r5, r0 +# CHECK-NEXT: adds r1, #122 +# CHECK-NEXT: movs r5, r0 +# CHECK-NEXT: adds r1, #104 +# CHECK-NEXT: movs r5, r0 +0x0f 0xb4 +0xb0 0xb5 +0x02 0xaf +0x81 0xb0 +0x05 0xab +0x53 0xf8 0x04 0x5b +0x00 0x93 +0x0d 0x4b +0x7b 0x44 +0x18 0x68 +0x04 0x68 +0x0c 0x48 +0x78 0x44 +0x00 0x68 +0x00 0x68 +0x2e 0xf0 0x1e 0xee +0x18 0xb9 +0x0a 0x49 +0x79 0x44 +0x09 0x68 +0x00 0xe0 +0x01 0x46 +0x20 0x46 +0x2a 0x46 +0x00 0x9b +0xfd 0xf7 0x9d 0xff +0xa7 0xf1 0x08 0x0d +0xbd 0xe8 0xb0 0x40 +0x04 0xb0 +0x70 0x47 +0x00 0xbf +0x8e 0x23 +0x05 0x00 +0x7a 0x31 +0x05 0x00 +0x68 0x31 +0x05 0x00 From enderby at apple.com Tue Mar 29 16:11:52 2011 From: enderby at apple.com (Kevin Enderby) Date: Tue, 29 Mar 2011 21:11:52 -0000 Subject: [llvm-commits] [llvm] r128488 - in /llvm/trunk: lib/MC/MCParser/AsmParser.cpp test/MC/AsmParser/floating-literals.s Message-ID: <20110329211152.4A22E2A6C12C@llvm.org> Author: enderby Date: Tue Mar 29 16:11:52 2011 New Revision: 128488 URL: http://llvm.org/viewvc/llvm-project?rev=128488&view=rev Log: Added support symbolic floating point constants in the MC assembler for Infinity and Nans with the same strings as GAS supports. rdar://8673024 Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp llvm/trunk/test/MC/AsmParser/floating-literals.s Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=128488&r1=128487&r2=128488&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original) +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Tue Mar 29 16:11:52 2011 @@ -1552,13 +1552,21 @@ Lex(); if (getLexer().isNot(AsmToken::Integer) && - getLexer().isNot(AsmToken::Real)) + getLexer().isNot(AsmToken::Real) && + getLexer().isNot(AsmToken::Identifier)) return TokError("unexpected token in directive"); // Convert to an APFloat. APFloat Value(Semantics); - if (Value.convertFromString(getTok().getString(), - APFloat::rmNearestTiesToEven) == + StringRef IDVal = getTok().getString(); + if (getLexer().is(AsmToken::Identifier)) { + if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf")) + Value = APFloat::getInf(Semantics); + else if (!IDVal.compare_lower("nan")) + Value = APFloat::getNaN(Semantics, false, ~0); + else + return TokError("invalid floating point literal"); + } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) == APFloat::opInvalidOp) return TokError("invalid floating point literal"); if (IsNeg) Modified: llvm/trunk/test/MC/AsmParser/floating-literals.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/floating-literals.s?rev=128488&r1=128487&r2=128488&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/floating-literals.s (original) +++ llvm/trunk/test/MC/AsmParser/floating-literals.s Tue Mar 29 16:11:52 2011 @@ -6,6 +6,12 @@ # CHECK: .long 1082549862 .single 1.2455, +2.3, 3, + 4.2 +# CHECK: .long 2139095040 +.single InFinIty + +# CHECK: .long 2147483647 +.single nAN + # CHECK: .long 1067928519 .float 1.307 From akyrtzi at gmail.com Tue Mar 29 16:16:19 2011 From: akyrtzi at gmail.com (Argyrios Kyrtzidis) Date: Tue, 29 Mar 2011 21:16:19 -0000 Subject: [llvm-commits] [llvm] r128489 - /llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Message-ID: <20110329211619.AE7BA2A6C12C@llvm.org> Author: akirtzidis Date: Tue Mar 29 16:16:19 2011 New Revision: 128489 URL: http://llvm.org/viewvc/llvm-project?rev=128489&view=rev Log: In ClangSACheckersEmitter: - Also emit a list of packages and groups sorted by name - Avoid iterating over DenseSet so that the output of the arrays is deterministic. Modified: llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp?rev=128489&r1=128488&r2=128489&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Tue Mar 29 16:16:19 2011 @@ -148,6 +148,48 @@ } } + typedef std::map SortedRecords; + + OS << "\n#ifdef GET_PACKAGES\n"; + { + SortedRecords sortedPackages; + for (unsigned i = 0, e = packages.size(); i != e; ++i) + sortedPackages[getPackageFullName(packages[i])] = packages[i]; + + for (SortedRecords::iterator + I = sortedPackages.begin(), E = sortedPackages.end(); I != E; ++I) { + const Record &R = *I->second; + + OS << "PACKAGE(" << "\""; + OS.write_escaped(getPackageFullName(&R)) << "\", "; + // Hidden bit + if (isHidden(R)) + OS << "true"; + else + OS << "false"; + OS << ")\n"; + } + } + OS << "#endif // GET_PACKAGES\n\n"; + + OS << "\n#ifdef GET_GROUPS\n"; + { + SortedRecords sortedGroups; + for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) + sortedGroups[checkerGroups[i]->getValueAsString("GroupName")] + = checkerGroups[i]; + + for (SortedRecords::iterator + I = sortedGroups.begin(), E = sortedGroups.end(); I != E; ++I) { + const Record &R = *I->second; + + OS << "GROUP(" << "\""; + OS.write_escaped(R.getValueAsString("GroupName")) << "\""; + OS << ")\n"; + } + } + OS << "#endif // GET_GROUPS\n\n"; + for (unsigned i = 0, e = checkers.size(); i != e; ++i) { Record *R = checkers[i]; Record *package = 0; @@ -201,22 +243,34 @@ for (std::map::iterator I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) { maxLen = std::max(maxLen, (unsigned)I->first.size()); - + llvm::DenseSet &checkers = I->second.Checkers; if (!checkers.empty()) { - OS << "static const short CheckerArray" << I->second.Index << "[] = { "; + // Make the output order deterministic. + std::map sorted; for (llvm::DenseSet::iterator - I = checkers.begin(), E = checkers.end(); I != E; ++I) - OS << checkerRecIndexMap[*I] << ", "; + I = checkers.begin(), E = checkers.end(); I != E; ++I) + sorted[(*I)->getID()] = *I; + + OS << "static const short CheckerArray" << I->second.Index << "[] = { "; + for (std::map::iterator + I = sorted.begin(), E = sorted.end(); I != E; ++I) + OS << checkerRecIndexMap[I->second] << ", "; OS << "-1 };\n"; } llvm::DenseSet &subGroups = I->second.SubGroups; if (!subGroups.empty()) { - OS << "static const short SubPackageArray" << I->second.Index << "[] = { "; + // Make the output order deterministic. + std::map sorted; for (llvm::DenseSet::iterator - I = subGroups.begin(), E = subGroups.end(); I != E; ++I) { - OS << recordGroupMap[*I]->Index << ", "; + I = subGroups.begin(), E = subGroups.end(); I != E; ++I) + sorted[(*I)->getID()] = *I; + + OS << "static const short SubPackageArray" << I->second.Index << "[] = { "; + for (std::map::iterator + I = sorted.begin(), E = sorted.end(); I != E; ++I) { + OS << recordGroupMap[I->second]->Index << ", "; } OS << "-1 };\n"; } From echristo at apple.com Tue Mar 29 16:20:59 2011 From: echristo at apple.com (Eric Christopher) Date: Tue, 29 Mar 2011 14:20:59 -0700 Subject: [llvm-commits] [llvm] r128487 - /llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt In-Reply-To: <20110329210930.578292A6C12C@llvm.org> References: <20110329210930.578292A6C12C@llvm.org> Message-ID: On Mar 29, 2011, at 2:09 PM, Johnny Chen wrote: > Add a thumb test file for printf (iOS 4.3). Seems like an odd thing to add on purpose. Was this triggering some sort of bug? -eric From stoklund at 2pi.dk Tue Mar 29 16:20:20 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 29 Mar 2011 21:20:20 -0000 Subject: [llvm-commits] [llvm] r128490 - in /llvm/trunk/lib/CodeGen: CalcSpillWeights.cpp InlineSpiller.cpp LiveRangeEdit.cpp LiveRangeEdit.h RegAllocGreedy.cpp SplitKit.cpp Message-ID: <20110329212020.18CE32A6C12C@llvm.org> Author: stoklund Date: Tue Mar 29 16:20:19 2011 New Revision: 128490 URL: http://llvm.org/viewvc/llvm-project?rev=128490&view=rev Log: Recompute register class and hint for registers created during spilling. The spill weight is not recomputed for an unspillable register - it stays infinite. Modified: llvm/trunk/lib/CodeGen/CalcSpillWeights.cpp llvm/trunk/lib/CodeGen/InlineSpiller.cpp llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp llvm/trunk/lib/CodeGen/LiveRangeEdit.h llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp llvm/trunk/lib/CodeGen/SplitKit.cpp Modified: llvm/trunk/lib/CodeGen/CalcSpillWeights.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CalcSpillWeights.cpp?rev=128490&r1=128489&r2=128490&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CalcSpillWeights.cpp (original) +++ llvm/trunk/lib/CodeGen/CalcSpillWeights.cpp Tue Mar 29 16:20:19 2011 @@ -103,6 +103,9 @@ // Don't recompute a target specific hint. bool noHint = mri.getRegAllocationHint(li.reg).first != 0; + // Don't recompute spill weight for an unspillable register. + bool Spillable = li.isSpillable(); + for (MachineRegisterInfo::reg_iterator I = mri.reg_begin(li.reg); MachineInstr *mi = I.skipInstruction();) { if (mi->isIdentityCopy() || mi->isImplicitDef() || mi->isDebugValue()) @@ -110,24 +113,27 @@ if (!visited.insert(mi)) continue; - // Get loop info for mi. - if (mi->getParent() != mbb) { - mbb = mi->getParent(); - loop = loops_.getLoopFor(mbb); - loopDepth = loop ? loop->getLoopDepth() : 0; - isExiting = loop ? loop->isLoopExiting(mbb) : false; - } - - // Calculate instr weight. - bool reads, writes; - tie(reads, writes) = mi->readsWritesVirtualRegister(li.reg); - float weight = LiveIntervals::getSpillWeight(writes, reads, loopDepth); - - // Give extra weight to what looks like a loop induction variable update. - if (writes && isExiting && lis_.isLiveOutOfMBB(li, mbb)) - weight *= 3; + float weight = 1.0f; + if (Spillable) { + // Get loop info for mi. + if (mi->getParent() != mbb) { + mbb = mi->getParent(); + loop = loops_.getLoopFor(mbb); + loopDepth = loop ? loop->getLoopDepth() : 0; + isExiting = loop ? loop->isLoopExiting(mbb) : false; + } + + // Calculate instr weight. + bool reads, writes; + tie(reads, writes) = mi->readsWritesVirtualRegister(li.reg); + weight = LiveIntervals::getSpillWeight(writes, reads, loopDepth); + + // Give extra weight to what looks like a loop induction variable update. + if (writes && isExiting && lis_.isLiveOutOfMBB(li, mbb)) + weight *= 3; - totalWeight += weight; + totalWeight += weight; + } // Get allocation hints from copies. if (noHint || !mi->isCopy()) @@ -150,10 +156,14 @@ // Always prefer the physreg hint. if (unsigned hint = hintPhys ? hintPhys : hintVirt) { mri.setRegAllocationHint(li.reg, 0, hint); - // Weakly boost the spill weifght of hinted registers. + // Weakly boost the spill weight of hinted registers. totalWeight *= 1.01F; } + // If the live interval was already unspillable, leave it that way. + if (!Spillable) + return; + // Mark li as unspillable if all live ranges are tiny. if (li.isZeroLength()) { li.markNotSpillable(); Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InlineSpiller.cpp?rev=128490&r1=128489&r2=128490&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/InlineSpiller.cpp (original) +++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp Tue Mar 29 16:20:19 2011 @@ -139,6 +139,7 @@ MachineBasicBlock::iterator MI); void spillAroundUses(unsigned Reg); + void spillAll(); }; } @@ -629,10 +630,6 @@ LiveInterval &NewLI = Edit->createFrom(VirtReg.reg, LIS, VRM); NewLI.markNotSpillable(); - // Rematting for a copy: Set allocation hint to be the destination register. - if (MI->isCopy()) - MRI.setRegAllocationHint(NewLI.reg, 0, MI->getOperand(0).getReg()); - // Finally we can rematerialize OrigMI before MI. SlotIndex DefIdx = Edit->rematerializeAt(*MI->getParent(), MI, NewLI.reg, RM, LIS, TII, TRI); @@ -718,6 +715,11 @@ DEBUG(dbgs() << RegsToSpill.size() << " registers to spill after remat.\n"); } + +//===----------------------------------------------------------------------===// +// Spilling +//===----------------------------------------------------------------------===// + /// If MI is a load or store of StackSlot, it can be removed. bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, unsigned Reg) { int FI = 0; @@ -906,31 +908,8 @@ } } -void InlineSpiller::spill(LiveRangeEdit &edit) { - Edit = &edit; - assert(!TargetRegisterInfo::isStackSlot(edit.getReg()) - && "Trying to spill a stack slot."); - // Share a stack slot among all descendants of Original. - Original = VRM.getOriginal(edit.getReg()); - StackSlot = VRM.getStackSlot(Original); - StackInt = 0; - - DEBUG(dbgs() << "Inline spilling " - << MRI.getRegClass(edit.getReg())->getName() - << ':' << edit.getParent() << "\nFrom original " - << LIS.getInterval(Original) << '\n'); - assert(edit.getParent().isSpillable() && - "Attempting to spill already spilled value."); - assert(DeadDefs.empty() && "Previous spill didn't remove dead defs"); - - collectRegsToSpill(); - analyzeSiblingValues(); - reMaterializeAll(); - - // Remat may handle everything. - if (RegsToSpill.empty()) - return; - +/// spillAll - Spill all registers remaining after rematerialization. +void InlineSpiller::spillAll() { // Update LiveStacks now that we are committed to spilling. if (StackSlot == VirtRegMap::NO_STACK_SLOT) { StackSlot = VRM.assignVirt2StackSlot(Original); @@ -939,8 +918,8 @@ } else StackInt = &LSS.getInterval(StackSlot); - if (Original != edit.getReg()) - VRM.assignVirt2StackSlot(edit.getReg(), StackSlot); + if (Original != Edit->getReg()) + VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot); assert(StackInt->getNumValNums() == 1 && "Bad stack interval values"); for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) @@ -959,7 +938,7 @@ } // Finally delete the SnippetCopies. - for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(edit.getReg()); + for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Edit->getReg()); MachineInstr *MI = RI.skipInstruction();) { assert(SnippetCopies.count(MI) && "Remaining use wasn't a snippet copy"); // FIXME: Do this with a LiveRangeEdit callback. @@ -968,6 +947,35 @@ MI->eraseFromParent(); } + // Delete all spilled registers. for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) - edit.eraseVirtReg(RegsToSpill[i], LIS); + Edit->eraseVirtReg(RegsToSpill[i], LIS); +} + +void InlineSpiller::spill(LiveRangeEdit &edit) { + Edit = &edit; + assert(!TargetRegisterInfo::isStackSlot(edit.getReg()) + && "Trying to spill a stack slot."); + // Share a stack slot among all descendants of Original. + Original = VRM.getOriginal(edit.getReg()); + StackSlot = VRM.getStackSlot(Original); + StackInt = 0; + + DEBUG(dbgs() << "Inline spilling " + << MRI.getRegClass(edit.getReg())->getName() + << ':' << edit.getParent() << "\nFrom original " + << LIS.getInterval(Original) << '\n'); + assert(edit.getParent().isSpillable() && + "Attempting to spill already spilled value."); + assert(DeadDefs.empty() && "Previous spill didn't remove dead defs"); + + collectRegsToSpill(); + analyzeSiblingValues(); + reMaterializeAll(); + + // Remat may handle everything. + if (!RegsToSpill.empty()) + spillAll(); + + Edit->calculateRegClassAndHint(MF, LIS, Loops); } Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp?rev=128490&r1=128489&r2=128490&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp Tue Mar 29 16:20:19 2011 @@ -15,6 +15,7 @@ #include "LiveRangeEdit.h" #include "VirtRegMap.h" #include "llvm/ADT/SetVector.h" +#include "llvm/CodeGen/CalcSpillWeights.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" @@ -236,3 +237,13 @@ } } +void LiveRangeEdit::calculateRegClassAndHint(MachineFunction &MF, + LiveIntervals &LIS, + const MachineLoopInfo &Loops) { + VirtRegAuxInfo VRAI(MF, LIS, Loops); + for (iterator I = begin(), E = end(); I != E; ++I) { + LiveInterval &LI = **I; + VRAI.CalculateRegClass(LI.reg); + VRAI.CalculateWeightAndHint(LI); + } +} Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.h?rev=128490&r1=128489&r2=128490&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.h (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.h Tue Mar 29 16:20:19 2011 @@ -25,6 +25,7 @@ class AliasAnalysis; class LiveIntervals; +class MachineLoopInfo; class MachineRegisterInfo; class VirtRegMap; @@ -179,6 +180,10 @@ LiveIntervals&, VirtRegMap&, const TargetInstrInfo&); + /// calculateRegClassAndHint - Recompute register class and hint for each new + /// register. + void calculateRegClassAndHint(MachineFunction&, LiveIntervals&, + const MachineLoopInfo&); }; } Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=128490&r1=128489&r2=128490&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Tue Mar 29 16:20:19 2011 @@ -1164,6 +1164,7 @@ NamedRegionTimer T("Spiller", TimerGroupName, TimePassesIsEnabled); LiveRangeEdit LRE(VirtReg, NewVRegs, this); spiller().spill(LRE); + setStage(NewVRegs.begin(), NewVRegs.end(), RS_Spill); if (VerifyEnabled) MF->verify(this, "After spilling"); Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=128490&r1=128489&r2=128490&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.cpp (original) +++ llvm/trunk/lib/CodeGen/SplitKit.cpp Tue Mar 29 16:20:19 2011 @@ -17,7 +17,6 @@ #include "LiveRangeEdit.h" #include "VirtRegMap.h" #include "llvm/ADT/Statistic.h" -#include "llvm/CodeGen/CalcSpillWeights.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -881,14 +880,7 @@ } // Calculate spill weight and allocation hints for new intervals. - VirtRegAuxInfo vrai(VRM.getMachineFunction(), LIS, SA.Loops); - for (LiveRangeEdit::iterator I = Edit->begin(), E = Edit->end(); I != E; ++I){ - LiveInterval &li = **I; - vrai.CalculateRegClass(li.reg); - vrai.CalculateWeightAndHint(li); - DEBUG(dbgs() << " new interval " << MRI.getRegClass(li.reg)->getName() - << ":" << li << '\n'); - } + Edit->calculateRegClassAndHint(VRM.getMachineFunction(), LIS, SA.Loops); } From eli.friedman at gmail.com Tue Mar 29 16:26:43 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Tue, 29 Mar 2011 14:26:43 -0700 Subject: [llvm-commits] [llvm] r128488 - in /llvm/trunk: lib/MC/MCParser/AsmParser.cpp test/MC/AsmParser/floating-literals.s In-Reply-To: <20110329211152.4A22E2A6C12C@llvm.org> References: <20110329211152.4A22E2A6C12C@llvm.org> Message-ID: n Tue, Mar 29, 2011 at 2:11 PM, Kevin Enderby wrote: > Author: enderby > Date: Tue Mar 29 16:11:52 2011 > New Revision: 128488 > > URL: http://llvm.org/viewvc/llvm-project?rev=128488&view=rev > Log: > Added support symbolic floating point constants in the MC assembler for Infinity > and Nans with the same strings as GAS supports. ?rdar://8673024 > > Modified: > ? ?llvm/trunk/lib/MC/MCParser/AsmParser.cpp > ? ?llvm/trunk/test/MC/AsmParser/floating-literals.s > > Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=128488&r1=128487&r2=128488&view=diff > ============================================================================== > --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original) > +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Tue Mar 29 16:11:52 2011 > @@ -1552,13 +1552,21 @@ > ? ? ? ? Lex(); > > ? ? ? if (getLexer().isNot(AsmToken::Integer) && > - ? ? ? ? ?getLexer().isNot(AsmToken::Real)) > + ? ? ? ? ?getLexer().isNot(AsmToken::Real) && > + ? ? ? ? ?getLexer().isNot(AsmToken::Identifier)) > ? ? ? ? return TokError("unexpected token in directive"); > > ? ? ? // Convert to an APFloat. > ? ? ? APFloat Value(Semantics); > - ? ? ?if (Value.convertFromString(getTok().getString(), > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?APFloat::rmNearestTiesToEven) == > + ? ? ?StringRef IDVal = getTok().getString(); > + ? ? ?if (getLexer().is(AsmToken::Identifier)) { > + ? ? ? ?if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf")) > + ? ? ? ? ?Value = APFloat::getInf(Semantics); > + ? ? ? ?else if (!IDVal.compare_lower("nan")) > + ? ? ? ? ?Value = APFloat::getNaN(Semantics, false, ~0); > + ? ? ? ?else > + ? ? ? ? ?return TokError("invalid floating point literal"); > + ? ? ?} else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) == > ? ? ? ? ? APFloat::opInvalidOp) > ? ? ? ? return TokError("invalid floating point literal"); > ? ? ? if (IsNeg) > > Modified: llvm/trunk/test/MC/AsmParser/floating-literals.s > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/floating-literals.s?rev=128488&r1=128487&r2=128488&view=diff > ============================================================================== > --- llvm/trunk/test/MC/AsmParser/floating-literals.s (original) > +++ llvm/trunk/test/MC/AsmParser/floating-literals.s Tue Mar 29 16:11:52 2011 > @@ -6,6 +6,12 @@ > ?# CHECK: .long 1082549862 > ?.single 1.2455, +2.3, 3, + 4.2 > > +# CHECK: .long 2139095040 > +.single InFinIty > + > +# CHECK: .long 2147483647 > +.single nAN > + > ?# CHECK: .long ?1067928519 > ?.float 1.307 Might be worth adding a test for "-inf" as well. -Eli From zwarich at apple.com Tue Mar 29 16:41:55 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 29 Mar 2011 21:41:55 -0000 Subject: [llvm-commits] [llvm] r128492 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/int-to-fp.ll Message-ID: <20110329214156.0F96E2A6C12C@llvm.org> Author: zwarich Date: Tue Mar 29 16:41:55 2011 New Revision: 128492 URL: http://llvm.org/viewvc/llvm-project?rev=128492&view=rev Log: Add Neon SINT_TO_FP and UINT_TO_FP lowering from v4i16 to v4f32. Fixes and . Added: llvm/trunk/test/CodeGen/ARM/int-to-fp.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=128492&r1=128491&r2=128492&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Mar 29 16:41:55 2011 @@ -461,6 +461,10 @@ setOperationAction(ISD::UDIV, MVT::v8i8, Custom); setOperationAction(ISD::VSETCC, MVT::v1i64, Expand); setOperationAction(ISD::VSETCC, MVT::v2i64, Expand); + // Neon does not have single instruction SINT_TO_FP and UINT_TO_FP with + // a destination type that is wider than the source. + setOperationAction(ISD::SINT_TO_FP, MVT::v4i16, Custom); + setOperationAction(ISD::UINT_TO_FP, MVT::v4i16, Custom); setTargetDAGCombine(ISD::INTRINSIC_VOID); setTargetDAGCombine(ISD::INTRINSIC_W_CHAIN); @@ -2854,8 +2858,39 @@ return DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op); } +static SDValue LowerVectorINT_TO_FP(SDValue Op, SelectionDAG &DAG) { + EVT VT = Op.getValueType(); + DebugLoc dl = Op.getDebugLoc(); + + EVT OperandVT = Op.getOperand(0).getValueType(); + assert(OperandVT == MVT::v4i16 && "Invalid type for custom lowering!"); + if (VT != MVT::v4f32) + return DAG.UnrollVectorOp(Op.getNode()); + + unsigned CastOpc; + unsigned Opc; + switch (Op.getOpcode()) { + default: + assert(0 && "Invalid opcode!"); + case ISD::SINT_TO_FP: + CastOpc = ISD::SIGN_EXTEND; + Opc = ISD::SINT_TO_FP; + break; + case ISD::UINT_TO_FP: + CastOpc = ISD::ZERO_EXTEND; + Opc = ISD::UINT_TO_FP; + break; + } + + Op = DAG.getNode(CastOpc, dl, MVT::v4i32, Op.getOperand(0)); + return DAG.getNode(Opc, dl, VT, Op); +} + static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) { EVT VT = Op.getValueType(); + if (VT.isVector()) + return LowerVectorINT_TO_FP(Op, DAG); + DebugLoc dl = Op.getDebugLoc(); unsigned Opc; Added: llvm/trunk/test/CodeGen/ARM/int-to-fp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/int-to-fp.ll?rev=128492&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/int-to-fp.ll (added) +++ llvm/trunk/test/CodeGen/ARM/int-to-fp.ll Tue Mar 29 16:41:55 2011 @@ -0,0 +1,19 @@ +; RUN: llc < %s | FileCheck %s +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32" +target triple = "thumbv7-apple-darwin10.0.0" + +; CHECK: sint_to_fp +; CHECK: vmovl.s16 +; CHECK: vcvt.f32.s32 +define <4 x float> @sint_to_fp(<4 x i16> %x) nounwind ssp { + %a = sitofp <4 x i16> %x to <4 x float> + ret <4 x float> %a +} + +; CHECK: uint_to_fp +; CHECK: vmovl.u16 +; CHECK: vcvt.f32.u32 +define <4 x float> @uint_to_fp(<4 x i16> %x) nounwind ssp { + %a = uitofp <4 x i16> %x to <4 x float> + ret <4 x float> %a +} From johnny.chen at apple.com Tue Mar 29 16:52:03 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 29 Mar 2011 21:52:03 -0000 Subject: [llvm-commits] [llvm] r128494 - /llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Message-ID: <20110329215203.270BE2A6C12C@llvm.org> Author: johnny Date: Tue Mar 29 16:52:02 2011 New Revision: 128494 URL: http://llvm.org/viewvc/llvm-project?rev=128494&view=rev Log: Add a test case for MSRi. Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=128494&r1=128493&r2=128494&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Tue Mar 29 16:52:02 2011 @@ -140,6 +140,9 @@ # CHECK: msr cpsr_fc, r0 0x00 0xf0 0x29 0xe1 +# CHECK: msrmi cpsr_c, #241, 8 +0xf1 0xf4 0x21 0x43 + # CHECK: rsbs r6, r7, r8 0x08 0x60 0x77 0xe0 From enderby at apple.com Tue Mar 29 16:54:10 2011 From: enderby at apple.com (Kevin Enderby) Date: Tue, 29 Mar 2011 21:54:10 -0000 Subject: [llvm-commits] [llvm] r128495 - /llvm/trunk/test/MC/AsmParser/floating-literals.s Message-ID: <20110329215410.D303B2A6C12C@llvm.org> Author: enderby Date: Tue Mar 29 16:54:10 2011 New Revision: 128495 URL: http://llvm.org/viewvc/llvm-project?rev=128495&view=rev Log: Adding a test for "-inf" as well. Modified: llvm/trunk/test/MC/AsmParser/floating-literals.s Modified: llvm/trunk/test/MC/AsmParser/floating-literals.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/floating-literals.s?rev=128495&r1=128494&r2=128495&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/floating-literals.s (original) +++ llvm/trunk/test/MC/AsmParser/floating-literals.s Tue Mar 29 16:54:10 2011 @@ -9,6 +9,9 @@ # CHECK: .long 2139095040 .single InFinIty +# CHECK: .long 4286578688 +.single -iNf + # CHECK: .long 2147483647 .single nAN From benny.kra at googlemail.com Tue Mar 29 17:06:41 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 29 Mar 2011 22:06:41 -0000 Subject: [llvm-commits] [llvm] r128496 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp test/Transforms/InstCombine/sign-test-and-or.ll Message-ID: <20110329220641.C222F2A6C12C@llvm.org> Author: d0k Date: Tue Mar 29 17:06:41 2011 New Revision: 128496 URL: http://llvm.org/viewvc/llvm-project?rev=128496&view=rev Log: InstCombine: Add a few missing combines for ANDs and ORs of sign bit tests. On x86 we now compile "if (a < 0 && b < 0)" into testl %edi, %esi js IF.THEN Added: llvm/trunk/test/Transforms/InstCombine/sign-test-and-or.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=128496&r1=128495&r2=128496&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Tue Mar 29 17:06:41 2011 @@ -756,6 +756,18 @@ Value *NewOr = Builder->CreateOr(Val, Val2); return Builder->CreateICmp(LHSCC, NewOr, LHSCst); } + + // (icmp slt A, 0) & (icmp slt B, 0) --> (icmp slt (A&B), 0) + if (LHSCC == ICmpInst::ICMP_SLT && LHSCst->isZero()) { + Value *NewAnd = Builder->CreateAnd(Val, Val2); + return Builder->CreateICmp(LHSCC, NewAnd, LHSCst); + } + + // (icmp sgt A, -1) & (icmp sgt B, -1) --> (icmp sgt (A|B), -1) + if (LHSCC == ICmpInst::ICMP_SGT && LHSCst->isAllOnesValue()) { + Value *NewOr = Builder->CreateOr(Val, Val2); + return Builder->CreateICmp(LHSCC, NewOr, LHSCst); + } } // From here on, we only handle: @@ -1442,6 +1454,18 @@ Value *NewOr = Builder->CreateOr(Val, Val2); return Builder->CreateICmp(LHSCC, NewOr, LHSCst); } + + // (icmp slt A, 0) | (icmp slt B, 0) --> (icmp slt (A|B), 0) + if (LHSCC == ICmpInst::ICMP_SLT && LHSCst->isZero()) { + Value *NewOr = Builder->CreateOr(Val, Val2); + return Builder->CreateICmp(LHSCC, NewOr, LHSCst); + } + + // (icmp sgt A, -1) | (icmp sgt B, -1) --> (icmp sgt (A&B), -1) + if (LHSCC == ICmpInst::ICMP_SGT && LHSCst->isAllOnesValue()) { + Value *NewAnd = Builder->CreateAnd(Val, Val2); + return Builder->CreateICmp(LHSCC, NewAnd, LHSCst); + } } // (icmp ult (X + CA), C1) | (icmp eq X, C2) -> (icmp ule (X + CA), C1) Added: llvm/trunk/test/Transforms/InstCombine/sign-test-and-or.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sign-test-and-or.ll?rev=128496&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/sign-test-and-or.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/sign-test-and-or.ll Tue Mar 29 17:06:41 2011 @@ -0,0 +1,79 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +declare void @foo() + +define void @test1(i32 %a, i32 %b) nounwind { + %1 = icmp slt i32 %a, 0 + %2 = icmp slt i32 %b, 0 + %or.cond = or i1 %1, %2 + br i1 %or.cond, label %if.then, label %if.end + +; CHECK: @test1 +; CHECK-NEXT: %1 = or i32 %a, %b +; CHECK-NEXT: %2 = icmp slt i32 %1, 0 +; CHECK-NEXT: br + +if.then: + tail call void @foo() nounwind + ret void + +if.end: + ret void +} + +define void @test2(i32 %a, i32 %b) nounwind { + %1 = icmp sgt i32 %a, -1 + %2 = icmp sgt i32 %b, -1 + %or.cond = or i1 %1, %2 + br i1 %or.cond, label %if.then, label %if.end + +; CHECK: @test2 +; CHECK-NEXT: %1 = and i32 %a, %b +; CHECK-NEXT: %2 = icmp sgt i32 %1, -1 +; CHECK-NEXT: br + +if.then: + tail call void @foo() nounwind + ret void + +if.end: + ret void +} + +define void @test3(i32 %a, i32 %b) nounwind { + %1 = icmp slt i32 %a, 0 + %2 = icmp slt i32 %b, 0 + %or.cond = and i1 %1, %2 + br i1 %or.cond, label %if.then, label %if.end + +; CHECK: @test3 +; CHECK-NEXT: %1 = and i32 %a, %b +; CHECK-NEXT: %2 = icmp slt i32 %1, 0 +; CHECK-NEXT: br + +if.then: + tail call void @foo() nounwind + ret void + +if.end: + ret void +} + +define void @test4(i32 %a, i32 %b) nounwind { + %1 = icmp sgt i32 %a, -1 + %2 = icmp sgt i32 %b, -1 + %or.cond = and i1 %1, %2 + br i1 %or.cond, label %if.then, label %if.end + +; CHECK: @test4 +; CHECK-NEXT: %1 = or i32 %a, %b +; CHECK-NEXT: %2 = icmp sgt i32 %1, -1 +; CHECK-NEXT: br + +if.then: + tail call void @foo() nounwind + ret void + +if.end: + ret void +} From matthewbg at google.com Tue Mar 29 17:25:36 2011 From: matthewbg at google.com (Matt Beaumont-Gay) Date: Tue, 29 Mar 2011 22:25:36 -0000 Subject: [llvm-commits] [llvm] r128497 - in /llvm/trunk: cmake/modules/LLVMLibDeps.cmake utils/TableGen/ClangSACheckersEmitter.cpp Message-ID: <20110329222536.B614F2A6C12C@llvm.org> Author: matthewbg Date: Tue Mar 29 17:25:36 2011 New Revision: 128497 URL: http://llvm.org/viewvc/llvm-project?rev=128497&view=rev Log: Quiet a gcc warning about changed name lookup rules Modified: llvm/trunk/cmake/modules/LLVMLibDeps.cmake llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Modified: llvm/trunk/cmake/modules/LLVMLibDeps.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMLibDeps.cmake?rev=128497&r1=128496&r2=128497&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVMLibDeps.cmake (original) +++ llvm/trunk/cmake/modules/LLVMLibDeps.cmake Tue Mar 29 17:25:36 2011 @@ -33,7 +33,7 @@ set(MSVC_LIB_DEPS_LLVMMBlazeDisassembler LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMBlazeInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen LLVMMSP430Info LLVMMipsCodeGen LLVMMipsInfo LLVMPTXCodeGen LLVMPTXInfo LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcInfo LLVMSupport LLVMSystemZCodeGen LLVMSystemZInfo LLVMX86AsmParser LLVMX86CodeGen LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreInfo) +set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen LLVMMSP430Info LLVMMipsCodeGen LLVMMipsInfo LLVMPTXCodeGen LLVMPTXInfo LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcInfo LLVMSupport LLVMSystemZCodeGen LLVMSystemZInfo LLVMTarget LLVMX86AsmParser LLVMX86CodeGen LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreInfo) set(MSVC_LIB_DEPS_LLVMMCJIT LLVMCore LLVMExecutionEngine LLVMRuntimeDyld LLVMSupport LLVMTarget) set(MSVC_LIB_DEPS_LLVMMCParser LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMMC LLVMSupport) Modified: llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp?rev=128497&r1=128496&r2=128497&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Tue Mar 29 17:25:36 2011 @@ -246,13 +246,13 @@ llvm::DenseSet &checkers = I->second.Checkers; if (!checkers.empty()) { + OS << "static const short CheckerArray" << I->second.Index << "[] = { "; // Make the output order deterministic. std::map sorted; for (llvm::DenseSet::iterator I = checkers.begin(), E = checkers.end(); I != E; ++I) sorted[(*I)->getID()] = *I; - OS << "static const short CheckerArray" << I->second.Index << "[] = { "; for (std::map::iterator I = sorted.begin(), E = sorted.end(); I != E; ++I) OS << checkerRecIndexMap[I->second] << ", "; @@ -261,13 +261,13 @@ llvm::DenseSet &subGroups = I->second.SubGroups; if (!subGroups.empty()) { + OS << "static const short SubPackageArray" << I->second.Index << "[] = { "; // Make the output order deterministic. std::map sorted; for (llvm::DenseSet::iterator I = subGroups.begin(), E = subGroups.end(); I != E; ++I) sorted[(*I)->getID()] = *I; - OS << "static const short SubPackageArray" << I->second.Index << "[] = { "; for (std::map::iterator I = sorted.begin(), E = sorted.end(); I != E; ++I) { OS << recordGroupMap[I->second]->Index << ", "; From matthewbg at google.com Tue Mar 29 17:34:10 2011 From: matthewbg at google.com (Matt Beaumont-Gay) Date: Tue, 29 Mar 2011 15:34:10 -0700 Subject: [llvm-commits] [llvm] r128497 - in /llvm/trunk: cmake/modules/LLVMLibDeps.cmake utils/TableGen/ClangSACheckersEmitter.cpp In-Reply-To: <20110329222536.B614F2A6C12C@llvm.org> References: <20110329222536.B614F2A6C12C@llvm.org> Message-ID: On Tue, Mar 29, 2011 at 15:25, Matt Beaumont-Gay wrote: > Author: matthewbg > Date: Tue Mar 29 17:25:36 2011 > New Revision: 128497 > > URL: http://llvm.org/viewvc/llvm-project?rev=128497&view=rev > Log: > Quiet a gcc warning about changed name lookup rules > > Modified: > ? ?llvm/trunk/cmake/modules/LLVMLibDeps.cmake > ? ?llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp > > Modified: llvm/trunk/cmake/modules/LLVMLibDeps.cmake > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMLibDeps.cmake?rev=128497&r1=128496&r2=128497&view=diff > ============================================================================== > --- llvm/trunk/cmake/modules/LLVMLibDeps.cmake (original) > +++ llvm/trunk/cmake/modules/LLVMLibDeps.cmake Tue Mar 29 17:25:36 2011 > @@ -33,7 +33,7 @@ > ?set(MSVC_LIB_DEPS_LLVMMBlazeDisassembler LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMSupport) > ?set(MSVC_LIB_DEPS_LLVMMBlazeInfo LLVMMC LLVMSupport) > ?set(MSVC_LIB_DEPS_LLVMMC LLVMSupport) > -set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen LLVMMSP430Info LLVMMipsCodeGen LLVMMipsInfo LLVMPTXCodeGen LLVMPTXInfo LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcInfo LLVMSupport LLVMSystemZCodeGen LLVMSystemZInfo LLVMX86AsmParser LLVMX86CodeGen LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreInfo) > +set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen LLVMMSP430Info LLVMMipsCodeGen LLVMMipsInfo LLVMPTXCodeGen LLVMPTXInfo LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcInfo LLVMSupport LLVMSystemZCodeGen LLVMSystemZInfo LLVMTarget LLVMX86AsmParser LLVMX86CodeGen LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreInfo) Argh, I don't know how this got in there -- I blame git-svn. Fixing... > ?set(MSVC_LIB_DEPS_LLVMMCJIT LLVMCore LLVMExecutionEngine LLVMRuntimeDyld LLVMSupport LLVMTarget) > ?set(MSVC_LIB_DEPS_LLVMMCParser LLVMMC LLVMSupport) > ?set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMMC LLVMSupport) > > Modified: llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp?rev=128497&r1=128496&r2=128497&view=diff > ============================================================================== > --- llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp (original) > +++ llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Tue Mar 29 17:25:36 2011 > @@ -246,13 +246,13 @@ > > ? ? llvm::DenseSet &checkers = I->second.Checkers; > ? ? if (!checkers.empty()) { > + ? ? ?OS << "static const short CheckerArray" << I->second.Index << "[] = { "; > ? ? ? // Make the output order deterministic. > ? ? ? std::map sorted; > ? ? ? for (llvm::DenseSet::iterator > ? ? ? ? ? ? ?I = checkers.begin(), E = checkers.end(); I != E; ++I) > ? ? ? ? sorted[(*I)->getID()] = *I; > > - ? ? ?OS << "static const short CheckerArray" << I->second.Index << "[] = { "; > ? ? ? for (std::map::iterator > ? ? ? ? ? ? ?I = sorted.begin(), E = sorted.end(); I != E; ++I) > ? ? ? ? OS << checkerRecIndexMap[I->second] << ", "; > @@ -261,13 +261,13 @@ > > ? ? llvm::DenseSet &subGroups = I->second.SubGroups; > ? ? if (!subGroups.empty()) { > + ? ? ?OS << "static const short SubPackageArray" << I->second.Index << "[] = { "; > ? ? ? // Make the output order deterministic. > ? ? ? std::map sorted; > ? ? ? for (llvm::DenseSet::iterator > ? ? ? ? ? ? ?I = subGroups.begin(), E = subGroups.end(); I != E; ++I) > ? ? ? ? sorted[(*I)->getID()] = *I; > > - ? ? ?OS << "static const short SubPackageArray" << I->second.Index << "[] = { "; > ? ? ? for (std::map::iterator > ? ? ? ? ? ? ?I = sorted.begin(), E = sorted.end(); I != E; ++I) { > ? ? ? ? OS << recordGroupMap[I->second]->Index << ", "; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From matthewbg at google.com Tue Mar 29 17:42:41 2011 From: matthewbg at google.com (Matt Beaumont-Gay) Date: Tue, 29 Mar 2011 22:42:41 -0000 Subject: [llvm-commits] [llvm] r128499 - /llvm/trunk/cmake/modules/LLVMLibDeps.cmake Message-ID: <20110329224241.491322A6C12C@llvm.org> Author: matthewbg Date: Tue Mar 29 17:42:41 2011 New Revision: 128499 URL: http://llvm.org/viewvc/llvm-project?rev=128499&view=rev Log: Revert accidental change to LLVMLibDeps.cmake Modified: llvm/trunk/cmake/modules/LLVMLibDeps.cmake Modified: llvm/trunk/cmake/modules/LLVMLibDeps.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMLibDeps.cmake?rev=128499&r1=128498&r2=128499&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVMLibDeps.cmake (original) +++ llvm/trunk/cmake/modules/LLVMLibDeps.cmake Tue Mar 29 17:42:41 2011 @@ -33,7 +33,7 @@ set(MSVC_LIB_DEPS_LLVMMBlazeDisassembler LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMBlazeInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen LLVMMSP430Info LLVMMipsCodeGen LLVMMipsInfo LLVMPTXCodeGen LLVMPTXInfo LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcInfo LLVMSupport LLVMSystemZCodeGen LLVMSystemZInfo LLVMTarget LLVMX86AsmParser LLVMX86CodeGen LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreInfo) +set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen LLVMMSP430Info LLVMMipsCodeGen LLVMMipsInfo LLVMPTXCodeGen LLVMPTXInfo LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcInfo LLVMSupport LLVMSystemZCodeGen LLVMSystemZInfo LLVMX86AsmParser LLVMX86CodeGen LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreInfo) set(MSVC_LIB_DEPS_LLVMMCJIT LLVMCore LLVMExecutionEngine LLVMRuntimeDyld LLVMSupport LLVMTarget) set(MSVC_LIB_DEPS_LLVMMCParser LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMMC LLVMSupport) From johnny.chen at apple.com Tue Mar 29 18:05:27 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 29 Mar 2011 16:05:27 -0700 Subject: [llvm-commits] [llvm] r128487 - /llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt In-Reply-To: References: <20110329210930.578292A6C12C@llvm.org> Message-ID: <4E0F38B3-3B32-4106-BF73-91A93002F517@apple.com> The intention was to add more test cases. Do you want me to remove this file? On Mar 29, 2011, at 2:20 PM, Eric Christopher wrote: > > On Mar 29, 2011, at 2:09 PM, Johnny Chen wrote: > >> Add a thumb test file for printf (iOS 4.3). > > Seems like an odd thing to add on purpose. Was this triggering some sort of bug? > > -eric From echristo at apple.com Tue Mar 29 18:07:08 2011 From: echristo at apple.com (Eric Christopher) Date: Tue, 29 Mar 2011 16:07:08 -0700 Subject: [llvm-commits] [llvm] r128487 - /llvm/trunk/test/MC/Disassembler/ARM/thumb-printf.txt In-Reply-To: <4E0F38B3-3B32-4106-BF73-91A93002F517@apple.com> References: <20110329210930.578292A6C12C@llvm.org> <4E0F38B3-3B32-4106-BF73-91A93002F517@apple.com> Message-ID: On Mar 29, 2011, at 4:05 PM, Johnny Chen wrote: > The intention was to add more test cases. > Do you want me to remove this file? Not necessarily, I'm curious as to the aim though that's not solved by a general disassembler testcase? -eric From isanbard at gmail.com Tue Mar 29 18:05:41 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 29 Mar 2011 23:05:41 -0000 Subject: [llvm-commits] [llvm] r128501 - /llvm/trunk/lib/Linker/LinkModules.cpp Message-ID: <20110329230541.EBEB82A6C12C@llvm.org> Author: void Date: Tue Mar 29 18:05:41 2011 New Revision: 128501 URL: http://llvm.org/viewvc/llvm-project?rev=128501&view=rev Log: We need to copy over the unnamed_addr attribute. Modified: llvm/trunk/lib/Linker/LinkModules.cpp Modified: llvm/trunk/lib/Linker/LinkModules.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=128501&r1=128500&r2=128501&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp (original) +++ llvm/trunk/lib/Linker/LinkModules.cpp Tue Mar 29 18:05:41 2011 @@ -352,6 +352,7 @@ unsigned Alignment = std::max(DestGV->getAlignment(), SrcGV->getAlignment()); DestGV->copyAttributesFrom(SrcGV); DestGV->setAlignment(Alignment); + DestGV->setUnnamedAddr(SrcGV->hasUnnamedAddr()); } /// GetLinkageResult - This analyzes the two global values and determines what From evan.cheng at apple.com Tue Mar 29 18:06:19 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 29 Mar 2011 23:06:19 -0000 Subject: [llvm-commits] [llvm] r128502 - in /llvm/trunk: include/llvm/IntrinsicsARM.td lib/Target/ARM/ARMISelLowering.cpp lib/VMCore/AutoUpgrade.cpp test/Bitcode/neon-intrinsics.ll test/CodeGen/ARM/vmul.ll Message-ID: <20110329230619.C616A2A6C12C@llvm.org> Author: evancheng Date: Tue Mar 29 18:06:19 2011 New Revision: 128502 URL: http://llvm.org/viewvc/llvm-project?rev=128502&view=rev Log: Add intrinsics @llvm.arm.neon.vmulls and @llvm.arm.neon.vmullu.* back. Frontends was lowering them to sext / uxt + mul instructions. Unfortunately the optimization passes may hoist the extensions out of the loop and separate them. When that happens, the long multiplication instructions can be broken into several scalar instructions, causing significant performance issue. Note the vmla and vmls intrinsics are not added back. Frontend will codegen them as intrinsics vmull* + add / sub. Also note the isel optimizations for catching mul + sext / zext are not changed either. First part of rdar://8832507, rdar://9203134 Modified: llvm/trunk/include/llvm/IntrinsicsARM.td llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/VMCore/AutoUpgrade.cpp llvm/trunk/test/Bitcode/neon-intrinsics.ll llvm/trunk/test/CodeGen/ARM/vmul.ll Modified: llvm/trunk/include/llvm/IntrinsicsARM.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsARM.td?rev=128502&r1=128501&r2=128502&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsARM.td (original) +++ llvm/trunk/include/llvm/IntrinsicsARM.td Tue Mar 29 18:06:19 2011 @@ -129,8 +129,12 @@ def int_arm_neon_vmulp : Neon_2Arg_Intrinsic; def int_arm_neon_vqdmulh : Neon_2Arg_Intrinsic; def int_arm_neon_vqrdmulh : Neon_2Arg_Intrinsic; + def int_arm_neon_vmulls : Neon_2Arg_Long_Intrinsic; + def int_arm_neon_vmullu : Neon_2Arg_Long_Intrinsic; def int_arm_neon_vmullp : Neon_2Arg_Long_Intrinsic; def int_arm_neon_vqdmull : Neon_2Arg_Long_Intrinsic; + + // Vector Multiply and Accumulate/Subtract. def int_arm_neon_vqdmlal : Neon_3Arg_Long_Intrinsic; def int_arm_neon_vqdmlsl : Neon_3Arg_Long_Intrinsic; @@ -292,7 +296,7 @@ def int_arm_neon_vcvthf2fp : Intrinsic<[llvm_v4f32_ty], [llvm_v4i16_ty], [IntrNoMem]>; -// Narrowing Saturating Vector Moves. +// Narrowing and Lengthening Vector Moves. def int_arm_neon_vqmovns : Neon_1Arg_Narrow_Intrinsic; def int_arm_neon_vqmovnu : Neon_1Arg_Narrow_Intrinsic; def int_arm_neon_vqmovnsu : Neon_1Arg_Narrow_Intrinsic; Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=128502&r1=128501&r2=128502&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Mar 29 18:06:19 2011 @@ -2157,6 +2157,13 @@ } return Result; } + case Intrinsic::arm_neon_vmulls: + case Intrinsic::arm_neon_vmullu: { + unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmulls) + ? ARMISD::VMULLs : ARMISD::VMULLu; + return DAG.getNode(NewOpc, Op.getDebugLoc(), Op.getValueType(), + Op.getOperand(1), Op.getOperand(2)); + } } } Modified: llvm/trunk/lib/VMCore/AutoUpgrade.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AutoUpgrade.cpp?rev=128502&r1=128501&r2=128502&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AutoUpgrade.cpp (original) +++ llvm/trunk/lib/VMCore/AutoUpgrade.cpp Tue Mar 29 18:06:19 2011 @@ -84,7 +84,6 @@ Name.compare(14, 5, "vsubl", 5) == 0 || Name.compare(14, 5, "vaddw", 5) == 0 || Name.compare(14, 5, "vsubw", 5) == 0 || - Name.compare(14, 5, "vmull", 5) == 0 || Name.compare(14, 5, "vmlal", 5) == 0 || Name.compare(14, 5, "vmlsl", 5) == 0 || Name.compare(14, 5, "vabdl", 5) == 0 || Modified: llvm/trunk/test/Bitcode/neon-intrinsics.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/neon-intrinsics.ll?rev=128502&r1=128501&r2=128502&view=diff ============================================================================== --- llvm/trunk/test/Bitcode/neon-intrinsics.ll (original) +++ llvm/trunk/test/Bitcode/neon-intrinsics.ll Tue Mar 29 18:06:19 2011 @@ -76,20 +76,13 @@ ; CHECK: zext <4 x i16> ; CHECK-NEXT: sub <4 x i32> -; vmull should be auto-upgraded to multiply with sext/zext -; (but vmullp should remain an intrinsic) +; vmull* intrinsics will remain intrinsics ; CHECK: vmulls8 -; CHECK-NOT: arm.neon.vmulls.v8i16 -; CHECK: sext <8 x i8> -; CHECK-NEXT: sext <8 x i8> -; CHECK-NEXT: mul <8 x i16> +; CHECK: arm.neon.vmulls.v8i16 ; CHECK: vmullu16 -; CHECK-NOT: arm.neon.vmullu.v4i32 -; CHECK: zext <4 x i16> -; CHECK-NEXT: zext <4 x i16> -; CHECK-NEXT: mul <4 x i32> +; CHECK: arm.neon.vmullu.v4i32 ; CHECK: vmullp8 ; CHECK: arm.neon.vmullp.v8i16 Modified: llvm/trunk/test/CodeGen/ARM/vmul.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vmul.ll?rev=128502&r1=128501&r2=128502&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vmul.ll (original) +++ llvm/trunk/test/CodeGen/ARM/vmul.ll Tue Mar 29 18:06:19 2011 @@ -158,6 +158,15 @@ ret <8 x i16> %tmp5 } +define <8 x i16> @vmulls8_int(<8 x i8>* %A, <8 x i8>* %B) nounwind { +;CHECK: vmulls8_int: +;CHECK: vmull.s8 + %tmp1 = load <8 x i8>* %A + %tmp2 = load <8 x i8>* %B + %tmp3 = call <8 x i16> @llvm.arm.neon.vmulls.v8i16(<8 x i8> %tmp1, <8 x i8> %tmp2) + ret <8 x i16> %tmp3 +} + define <4 x i32> @vmulls16(<4 x i16>* %A, <4 x i16>* %B) nounwind { ;CHECK: vmulls16: ;CHECK: vmull.s16 @@ -169,6 +178,15 @@ ret <4 x i32> %tmp5 } +define <4 x i32> @vmulls16_int(<4 x i16>* %A, <4 x i16>* %B) nounwind { +;CHECK: vmulls16_int: +;CHECK: vmull.s16 + %tmp1 = load <4 x i16>* %A + %tmp2 = load <4 x i16>* %B + %tmp3 = call <4 x i32> @llvm.arm.neon.vmulls.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) + ret <4 x i32> %tmp3 +} + define <2 x i64> @vmulls32(<2 x i32>* %A, <2 x i32>* %B) nounwind { ;CHECK: vmulls32: ;CHECK: vmull.s32 @@ -180,6 +198,15 @@ ret <2 x i64> %tmp5 } +define <2 x i64> @vmulls32_int(<2 x i32>* %A, <2 x i32>* %B) nounwind { +;CHECK: vmulls32_int: +;CHECK: vmull.s32 + %tmp1 = load <2 x i32>* %A + %tmp2 = load <2 x i32>* %B + %tmp3 = call <2 x i64> @llvm.arm.neon.vmulls.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) + ret <2 x i64> %tmp3 +} + define <8 x i16> @vmullu8(<8 x i8>* %A, <8 x i8>* %B) nounwind { ;CHECK: vmullu8: ;CHECK: vmull.u8 @@ -191,6 +218,15 @@ ret <8 x i16> %tmp5 } +define <8 x i16> @vmullu8_int(<8 x i8>* %A, <8 x i8>* %B) nounwind { +;CHECK: vmullu8_int: +;CHECK: vmull.u8 + %tmp1 = load <8 x i8>* %A + %tmp2 = load <8 x i8>* %B + %tmp3 = call <8 x i16> @llvm.arm.neon.vmullu.v8i16(<8 x i8> %tmp1, <8 x i8> %tmp2) + ret <8 x i16> %tmp3 +} + define <4 x i32> @vmullu16(<4 x i16>* %A, <4 x i16>* %B) nounwind { ;CHECK: vmullu16: ;CHECK: vmull.u16 @@ -202,6 +238,15 @@ ret <4 x i32> %tmp5 } +define <4 x i32> @vmullu16_int(<4 x i16>* %A, <4 x i16>* %B) nounwind { +;CHECK: vmullu16_int: +;CHECK: vmull.u16 + %tmp1 = load <4 x i16>* %A + %tmp2 = load <4 x i16>* %B + %tmp3 = call <4 x i32> @llvm.arm.neon.vmullu.v4i32(<4 x i16> %tmp1, <4 x i16> %tmp2) + ret <4 x i32> %tmp3 +} + define <2 x i64> @vmullu32(<2 x i32>* %A, <2 x i32>* %B) nounwind { ;CHECK: vmullu32: ;CHECK: vmull.u32 @@ -213,6 +258,15 @@ ret <2 x i64> %tmp5 } +define <2 x i64> @vmullu32_int(<2 x i32>* %A, <2 x i32>* %B) nounwind { +;CHECK: vmullu32_int: +;CHECK: vmull.u32 + %tmp1 = load <2 x i32>* %A + %tmp2 = load <2 x i32>* %B + %tmp3 = call <2 x i64> @llvm.arm.neon.vmullu.v2i64(<2 x i32> %tmp1, <2 x i32> %tmp2) + ret <2 x i64> %tmp3 +} + define <8 x i16> @vmullp8(<8 x i8>* %A, <8 x i8>* %B) nounwind { ;CHECK: vmullp8: ;CHECK: vmull.p8 @@ -233,6 +287,15 @@ ret <4 x i32> %3 } +define arm_aapcs_vfpcc <4 x i32> @test_vmull_lanes16_int(<4 x i16> %arg0_int16x4_t, <4 x i16> %arg1_int16x4_t) nounwind readnone { +entry: +; CHECK: test_vmull_lanes16_int +; CHECK: vmull.s16 q0, d0, d1[1] + %0 = shufflevector <4 x i16> %arg1_int16x4_t, <4 x i16> undef, <4 x i32> ; <<4 x i16>> [#uses=1] + %1 = tail call <4 x i32> @llvm.arm.neon.vmulls.v4i32(<4 x i16> %arg0_int16x4_t, <4 x i16> %0) ; <<4 x i32>> [#uses=1] + ret <4 x i32> %1 +} + define arm_aapcs_vfpcc <2 x i64> @test_vmull_lanes32(<2 x i32> %arg0_int32x2_t, <2 x i32> %arg1_int32x2_t) nounwind readnone { entry: ; CHECK: test_vmull_lanes32 @@ -244,6 +307,15 @@ ret <2 x i64> %3 } +define arm_aapcs_vfpcc <2 x i64> @test_vmull_lanes32_int(<2 x i32> %arg0_int32x2_t, <2 x i32> %arg1_int32x2_t) nounwind readnone { +entry: +; CHECK: test_vmull_lanes32_int +; CHECK: vmull.s32 q0, d0, d1[1] + %0 = shufflevector <2 x i32> %arg1_int32x2_t, <2 x i32> undef, <2 x i32> ; <<2 x i32>> [#uses=1] + %1 = tail call <2 x i64> @llvm.arm.neon.vmulls.v2i64(<2 x i32> %arg0_int32x2_t, <2 x i32> %0) ; <<2 x i64>> [#uses=1] + ret <2 x i64> %1 +} + define arm_aapcs_vfpcc <4 x i32> @test_vmull_laneu16(<4 x i16> %arg0_uint16x4_t, <4 x i16> %arg1_uint16x4_t) nounwind readnone { entry: ; CHECK: test_vmull_laneu16 @@ -255,6 +327,15 @@ ret <4 x i32> %3 } +define arm_aapcs_vfpcc <4 x i32> @test_vmull_laneu16_int(<4 x i16> %arg0_uint16x4_t, <4 x i16> %arg1_uint16x4_t) nounwind readnone { +entry: +; CHECK: test_vmull_laneu16_int +; CHECK: vmull.u16 q0, d0, d1[1] + %0 = shufflevector <4 x i16> %arg1_uint16x4_t, <4 x i16> undef, <4 x i32> ; <<4 x i16>> [#uses=1] + %1 = tail call <4 x i32> @llvm.arm.neon.vmullu.v4i32(<4 x i16> %arg0_uint16x4_t, <4 x i16> %0) ; <<4 x i32>> [#uses=1] + ret <4 x i32> %1 +} + define arm_aapcs_vfpcc <2 x i64> @test_vmull_laneu32(<2 x i32> %arg0_uint32x2_t, <2 x i32> %arg1_uint32x2_t) nounwind readnone { entry: ; CHECK: test_vmull_laneu32 @@ -266,6 +347,23 @@ ret <2 x i64> %3 } +define arm_aapcs_vfpcc <2 x i64> @test_vmull_laneu32_int(<2 x i32> %arg0_uint32x2_t, <2 x i32> %arg1_uint32x2_t) nounwind readnone { +entry: +; CHECK: test_vmull_laneu32_int +; CHECK: vmull.u32 q0, d0, d1[1] + %0 = shufflevector <2 x i32> %arg1_uint32x2_t, <2 x i32> undef, <2 x i32> ; <<2 x i32>> [#uses=1] + %1 = tail call <2 x i64> @llvm.arm.neon.vmullu.v2i64(<2 x i32> %arg0_uint32x2_t, <2 x i32> %0) ; <<2 x i64>> [#uses=1] + ret <2 x i64> %1 +} + +declare <8 x i16> @llvm.arm.neon.vmulls.v8i16(<8 x i8>, <8 x i8>) nounwind readnone +declare <4 x i32> @llvm.arm.neon.vmulls.v4i32(<4 x i16>, <4 x i16>) nounwind readnone +declare <2 x i64> @llvm.arm.neon.vmulls.v2i64(<2 x i32>, <2 x i32>) nounwind readnone + +declare <8 x i16> @llvm.arm.neon.vmullu.v8i16(<8 x i8>, <8 x i8>) nounwind readnone +declare <4 x i32> @llvm.arm.neon.vmullu.v4i32(<4 x i16>, <4 x i16>) nounwind readnone +declare <2 x i64> @llvm.arm.neon.vmullu.v2i64(<2 x i32>, <2 x i32>) nounwind readnone + declare <8 x i16> @llvm.arm.neon.vmullp.v8i16(<8 x i8>, <8 x i8>) nounwind readnone From pichet2000 at gmail.com Tue Mar 29 18:18:51 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Tue, 29 Mar 2011 23:18:51 -0000 Subject: [llvm-commits] [llvm] r128503 - /llvm/trunk/tools/llvm-rtdyld/CMakeLists.txt Message-ID: <20110329231851.B85862A6C12C@llvm.org> Author: fpichet Date: Tue Mar 29 18:18:51 2011 New Revision: 128503 URL: http://llvm.org/viewvc/llvm-project?rev=128503&view=rev Log: Update CMake link dependency. Modified: llvm/trunk/tools/llvm-rtdyld/CMakeLists.txt Modified: llvm/trunk/tools/llvm-rtdyld/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/CMakeLists.txt?rev=128503&r1=128502&r2=128503&view=diff ============================================================================== --- llvm/trunk/tools/llvm-rtdyld/CMakeLists.txt (original) +++ llvm/trunk/tools/llvm-rtdyld/CMakeLists.txt Tue Mar 29 18:18:51 2011 @@ -1,4 +1,4 @@ -set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC object RuntimeDyld) +set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC object RuntimeDyld JIT) add_llvm_tool(llvm-rtdyld llvm-rtdyld.cpp From grosbach at apple.com Tue Mar 29 18:20:22 2011 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 29 Mar 2011 23:20:22 -0000 Subject: [llvm-commits] [llvm] r128504 - /llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Message-ID: <20110329232022.6E0D62A6C12C@llvm.org> Author: grosbach Date: Tue Mar 29 18:20:22 2011 New Revision: 128504 URL: http://llvm.org/viewvc/llvm-project?rev=128504&view=rev Log: Tidy up. 80 columns and trailing whitespace. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=128504&r1=128503&r2=128504&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Tue Mar 29 18:20:22 2011 @@ -70,17 +70,17 @@ unsigned NumBits = 0; if (const GlobalVariable *GVar = dyn_cast(GV)) NumBits = TD.getPreferredAlignmentLog(GVar); - + // If InBits is specified, round it to it. if (InBits > NumBits) NumBits = InBits; - + // If the GV has a specified alignment, take it into account. if (GV->getAlignment() == 0) return NumBits; - + unsigned GVAlign = Log2_32(GV->getAlignment()); - + // If the GVAlign is larger than NumBits, or if we are required to obey // NumBits because the GV has an assigned section, obey it. if (GVAlign > NumBits || GV->hasSection()) @@ -104,16 +104,16 @@ AsmPrinter::~AsmPrinter() { assert(DD == 0 && DE == 0 && "Debug/EH info didn't get finalized"); - + if (GCMetadataPrinters != 0) { gcp_map_type &GCMap = getGCMap(GCMetadataPrinters); - + for (gcp_map_type::iterator I = GCMap.begin(), E = GCMap.end(); I != E; ++I) delete I->second; delete &GCMap; GCMetadataPrinters = 0; } - + delete &OutStreamer; } @@ -156,9 +156,9 @@ // Initialize TargetLoweringObjectFile. const_cast(getObjFileLowering()) .Initialize(OutContext, TM); - + Mang = new Mangler(OutContext, *TM.getTargetData()); - + // Allow the target to emit any magic that it wants at the start of the file. EmitStartOfAsmFile(M); @@ -255,7 +255,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { if (!GV->hasInitializer()) // External globals require no code. return; - + // Check to see if this is a special global used by LLVM, if so, emit it. if (EmitSpecialLLVMGlobal(GV)) return; @@ -265,44 +265,44 @@ /*PrintType=*/false, GV->getParent()); OutStreamer.GetCommentOS() << '\n'; } - + MCSymbol *GVSym = Mang->getSymbol(GV); EmitVisibility(GVSym, GV->getVisibility()); if (MAI->hasDotTypeDotSizeDirective()) OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject); - + SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM); const TargetData *TD = TM.getTargetData(); uint64_t Size = TD->getTypeAllocSize(GV->getType()->getElementType()); - + // If the alignment is specified, we *must* obey it. Overaligning a global // with a specified alignment is a prompt way to break globals emitted to // sections and expected to be contiguous (e.g. ObjC metadata). unsigned AlignLog = getGVAlignmentLog2(GV, *TD); - + // Handle common and BSS local symbols (.lcomm). if (GVKind.isCommon() || GVKind.isBSSLocal()) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - + if (isVerbose()) { WriteAsOperand(OutStreamer.GetCommentOS(), GV, /*PrintType=*/false, GV->getParent()); OutStreamer.GetCommentOS() << '\n'; } - + // Handle common symbols. if (GVKind.isCommon()) { unsigned Align = 1 << AlignLog; if (!getObjFileLowering().getCommDirectiveSupportsAlignment()) Align = 0; - + // .comm _foo, 42, 4 OutStreamer.EmitCommonSymbol(GVSym, Size, Align); return; } - + // Handle local BSS symbols. if (MAI->hasMachoZeroFillDirective()) { const MCSection *TheSection = @@ -311,7 +311,7 @@ OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog); return; } - + if (MAI->hasLCOMMDirective()) { // .lcomm _foo, 42 OutStreamer.EmitLocalCommonSymbol(GVSym, Size); @@ -321,14 +321,14 @@ unsigned Align = 1 << AlignLog; if (!getObjFileLowering().getCommDirectiveSupportsAlignment()) Align = 0; - + // .local _foo OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Local); // .comm _foo, 42, 4 OutStreamer.EmitCommonSymbol(GVSym, Size, Align); return; } - + const MCSection *TheSection = getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM); @@ -336,14 +336,14 @@ // emission. if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) { if (Size == 0) Size = 1; // zerofill of 0 bytes is undefined. - + // .globl _foo OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); // .zerofill __DATA, __common, _foo, 400, 5 OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog); return; } - + // Handle thread local data for mach-o which requires us to output an // additional structure of data and mangle the original symbol so that we // can reference it later. @@ -356,31 +356,31 @@ // specific code. if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) { // Emit the .tbss symbol - MCSymbol *MangSym = + MCSymbol *MangSym = OutContext.GetOrCreateSymbol(GVSym->getName() + Twine("$tlv$init")); - + if (GVKind.isThreadBSS()) OutStreamer.EmitTBSSSymbol(TheSection, MangSym, Size, 1 << AlignLog); else if (GVKind.isThreadData()) { OutStreamer.SwitchSection(TheSection); - EmitAlignment(AlignLog, GV); + EmitAlignment(AlignLog, GV); OutStreamer.EmitLabel(MangSym); - + EmitGlobalConstant(GV->getInitializer()); } - + OutStreamer.AddBlankLine(); - + // Emit the variable struct for the runtime. - const MCSection *TLVSect + const MCSection *TLVSect = getObjFileLowering().getTLSExtraDataSection(); - + OutStreamer.SwitchSection(TLVSect); // Emit the linkage here. EmitLinkage(GV->getLinkage(), GVSym); OutStreamer.EmitLabel(GVSym); - + // Three pointers in size: // - __tlv_bootstrap - used to make sure support exists // - spare pointer, used when mapped by the runtime @@ -390,7 +390,7 @@ PtrSize, 0); OutStreamer.EmitIntValue(0, PtrSize, 0); OutStreamer.EmitSymbolValue(MangSym, PtrSize, 0); - + OutStreamer.AddBlankLine(); return; } @@ -407,7 +407,7 @@ if (MAI->hasDotTypeDotSizeDirective()) // .size foo, 42 OutStreamer.EmitELFSize(GVSym, MCConstantExpr::Create(Size, OutContext)); - + OutStreamer.AddBlankLine(); } @@ -416,7 +416,7 @@ void AsmPrinter::EmitFunctionHeader() { // Print out constants referenced by the function EmitConstantPool(); - + // Print the 'header' of function. const Function *F = MF->getFunction(); @@ -438,7 +438,7 @@ // Emit the CurrentFnSym. This is a virtual function to allow targets to // do their wild and crazy things as required. EmitFunctionEntryLabel(); - + // If the function had address-taken blocks that got deleted, then we have // references to the dangling symbols. Emit them at the start of the function // so that we don't get references to undefined symbols. @@ -448,17 +448,17 @@ OutStreamer.AddComment("Address taken block that was later removed"); OutStreamer.EmitLabel(DeadBlockSyms[i]); } - + // Add some workaround for linkonce linkage on Cygwin\MinGW. if (MAI->getLinkOnceDirective() != 0 && (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) { // FIXME: What is this? - MCSymbol *FakeStub = + MCSymbol *FakeStub = OutContext.GetOrCreateSymbol(Twine("Lllvm$workaround$fake$stub$")+ CurrentFnSym->getName()); OutStreamer.EmitLabel(FakeStub); } - + // Emit pre-function debug and/or EH information. if (DE) { NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled); @@ -483,7 +483,7 @@ } -static void EmitDebugLoc(DebugLoc DL, const MachineFunction *MF, +static void EmitDebugLoc(DebugLoc DL, const MachineFunction *MF, raw_ostream &CommentOS) { const LLVMContext &Ctx = MF->getFunction()->getContext(); if (!DL.isUnknown()) { // Print source line info. @@ -509,18 +509,18 @@ static void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) { const MachineFunction *MF = MI.getParent()->getParent(); const TargetMachine &TM = MF->getTarget(); - + DebugLoc DL = MI.getDebugLoc(); if (!DL.isUnknown()) { // Print source line info. EmitDebugLoc(DL, MF, CommentOS); CommentOS << '\n'; } - + // Check for spills and reloads int FI; - + const MachineFrameInfo *FrameInfo = MF->getFrameInfo(); - + // We assume a single instruction only has a spill or reload, not // both. const MachineMemOperand *MMO; @@ -541,7 +541,7 @@ if (FrameInfo->isSpillSlotObjectIndex(FI)) CommentOS << MMO->getSize() << "-byte Folded Spill\n"; } - + // Check for spill-induced copies if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse)) CommentOS << " Reload Reuse\n"; @@ -615,7 +615,7 @@ } OS << AP.TM.getRegisterInfo()->getName(MI->getOperand(0).getReg()); } - + OS << '+' << MI->getOperand(1).getImm(); // NOTE: Want this comment at start of line, don't emit with AddComment. AP.OutStreamer.EmitRawText(OS.str()); @@ -627,9 +627,9 @@ void AsmPrinter::EmitFunctionBody() { // Emit target-specific gunk before the function body. EmitFunctionBodyStart(); - + bool ShouldPrintDebugScopes = DD && MMI->hasDebugInfo(); - + // Print out code for the function. bool HasAnyRealCode = false; const MachineInstr *LastMI = 0; @@ -652,7 +652,7 @@ NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); DD->beginInstruction(II); } - + if (isVerbose()) EmitComments(*II, OutStreamer.GetCommentOS()); @@ -681,7 +681,7 @@ EmitInstruction(II); break; } - + if (ShouldPrintDebugScopes) { NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); DD->endInstruction(II); @@ -708,10 +708,10 @@ } else // Target not mc-ized yet. OutStreamer.EmitRawText(StringRef("\tnop\n")); } - + // Emit target-specific gunk after the function body. EmitFunctionBodyEnd(); - + // If the target wants a .size directive for the size of the function, emit // it. if (MAI->hasDotTypeDotSizeDirective()) { @@ -719,14 +719,14 @@ // difference between the function label and the temp label. MCSymbol *FnEndLabel = OutContext.CreateTempSymbol(); OutStreamer.EmitLabel(FnEndLabel); - + const MCExpr *SizeExp = MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(FnEndLabel, OutContext), MCSymbolRefExpr::Create(CurrentFnSym, OutContext), OutContext); OutStreamer.EmitELFSize(CurrentFnSym, SizeExp); } - + // Emit post-function debug information. if (DD) { NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); @@ -737,16 +737,17 @@ DE->EndFunction(); } MMI->EndFunction(); - + // Print out jump tables referenced by the function. EmitJumpTableInfo(); - + OutStreamer.AddBlankLine(); } /// getDebugValueLocation - Get location information encoded by DBG_VALUE /// operands. -MachineLocation AsmPrinter::getDebugValueLocation(const MachineInstr *MI) const { +MachineLocation AsmPrinter:: +getDebugValueLocation(const MachineInstr *MI) const { // Target specific DBG_VALUE instructions are handled by each target. return MachineLocation(); } @@ -785,7 +786,7 @@ } delete DD; DD = 0; } - + // If the target wants to know about weak references, print them all. if (MAI->getWeakRefDirective()) { // FIXME: This is not lazy, it would be nice to only print weak references @@ -799,7 +800,7 @@ if (!I->hasExternalWeakLinkage()) continue; OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference); } - + for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { if (!I->hasExternalWeakLinkage()) continue; OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference); @@ -825,7 +826,7 @@ EmitVisibility(Name, I->getVisibility()); // Emit the directives as assignments aka .set: - OutStreamer.EmitAssignment(Name, + OutStreamer.EmitAssignment(Name, MCSymbolRefExpr::Create(Target, OutContext)); } } @@ -842,14 +843,14 @@ if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty()) if (const MCSection *S = MAI->getNonexecutableStackSection(OutContext)) OutStreamer.SwitchSection(S); - + // Allow the target to emit any magic that it wants at the end of the file, // after everything else has gone out. EmitEndOfAsmFile(M); - + delete Mang; Mang = 0; MMI = 0; - + OutStreamer.Finish(); return false; } @@ -889,7 +890,7 @@ for (unsigned i = 0, e = CP.size(); i != e; ++i) { const MachineConstantPoolEntry &CPE = CP[i]; unsigned Align = CPE.getAlignment(); - + SectionKind Kind; switch (CPE.getRelocationInfo()) { default: llvm_unreachable("Unknown section kind"); @@ -907,7 +908,7 @@ } const MCSection *S = getObjFileLowering().getSectionForConstant(Kind); - + // The number of sections are small, just do a linear search from the // last section to the first. bool Found = false; @@ -956,7 +957,7 @@ } /// EmitJumpTableInfo - Print assembly representations of the jump tables used -/// by the current function to the current output stream. +/// by the current function to the current output stream. /// void AsmPrinter::EmitJumpTableInfo() { const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); @@ -965,7 +966,7 @@ const std::vector &JT = MJTI->getJumpTables(); if (JT.empty()) return; - // Pick the directive to use to print the jump table entries, and switch to + // Pick the directive to use to print the jump table entries, and switch to // the appropriate section. const Function *F = MF->getFunction(); bool JTInDiffSection = false; @@ -981,18 +982,18 @@ OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F,Mang,TM)); } else { // Otherwise, drop it in the readonly section. - const MCSection *ReadOnlySection = + const MCSection *ReadOnlySection = getObjFileLowering().getSectionForConstant(SectionKind::getReadOnly()); OutStreamer.SwitchSection(ReadOnlySection); JTInDiffSection = true; } EmitAlignment(Log2_32(MJTI->getEntryAlignment(*TM.getTargetData()))); - + for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) { const std::vector &JTBBs = JT[JTI].MBBs; - - // If this jump table was deleted, ignore it. + + // If this jump table was deleted, ignore it. if (JTBBs.empty()) continue; // For the EK_LabelDifference32 entry, if the target supports .set, emit a @@ -1006,15 +1007,15 @@ for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { const MachineBasicBlock *MBB = JTBBs[ii]; if (!EmittedSets.insert(MBB)) continue; - + // .set LJTSet, LBB32-base const MCExpr *LHS = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); OutStreamer.EmitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()), MCBinaryExpr::CreateSub(LHS, Base, OutContext)); } - } - + } + // On some targets (e.g. Darwin) we want to emit two consecutive labels // before each jump table. The first label is never referenced, but tells // the assembler and linker the extents of the jump table object. The @@ -1067,8 +1068,8 @@ // If the .set directive is supported, this is emitted as: // .set L4_5_set_123, LBB123 - LJTI1_2 // .word L4_5_set_123 - - // If we have emitted set directives for the jump table entries, print + + // If we have emitted set directives for the jump table entries, print // them rather than the entries themselves. If we're emitting PIC, then // emit the table entries as differences between two text section labels. if (MAI->hasSetDirective()) { @@ -1084,9 +1085,9 @@ break; } } - + assert(Value && "Unknown entry kind!"); - + unsigned EntrySize = MJTI->getEntrySize(*TM.getTargetData()); OutStreamer.EmitValue(Value, EntrySize, /*addrspace*/0); } @@ -1106,18 +1107,18 @@ if (GV->getSection() == "llvm.metadata" || GV->hasAvailableExternallyLinkage()) return true; - + if (!GV->hasAppendingLinkage()) return false; assert(GV->hasInitializer() && "Not a special LLVM global!"); - + const TargetData *TD = TM.getTargetData(); unsigned Align = Log2_32(TD->getPointerPrefAlignment()); if (GV->getName() == "llvm.global_ctors") { OutStreamer.SwitchSection(getObjFileLowering().getStaticCtorSection()); EmitAlignment(Align); EmitXXStructorList(GV->getInitializer()); - + if (TM.getRelocationModel() == Reloc::Static && MAI->hasStaticCtorDtorReferenceInStaticMode()) { StringRef Sym(".constructors_used"); @@ -1125,8 +1126,8 @@ MCSA_Reference); } return true; - } - + } + if (GV->getName() == "llvm.global_dtors") { OutStreamer.SwitchSection(getObjFileLowering().getStaticDtorSection()); EmitAlignment(Align); @@ -1140,7 +1141,7 @@ } return true; } - + return false; } @@ -1151,7 +1152,7 @@ // Should be an array of 'i8*'. ConstantArray *InitList = dyn_cast(List); if (InitList == 0) return; - + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { const GlobalValue *GV = dyn_cast(InitList->getOperand(i)->stripPointerCasts()); @@ -1160,7 +1161,7 @@ } } -/// EmitXXStructorList - Emit the ctor or dtor list. This just prints out the +/// EmitXXStructorList - Emit the ctor or dtor list. This just prints out the /// function pointers, ignoring the init priority. void AsmPrinter::EmitXXStructorList(Constant *List) { // Should be an array of '{ int, void ()* }' structs. The first value is the @@ -1206,11 +1207,11 @@ void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) const { // Get the Hi-Lo expression. - const MCExpr *Diff = + const MCExpr *Diff = MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(Hi, OutContext), MCSymbolRefExpr::Create(Lo, OutContext), OutContext); - + if (!MAI->hasSetDirective()) { OutStreamer.EmitValue(Diff, Size, 0/*AddrSpace*/); return; @@ -1222,27 +1223,27 @@ OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/); } -/// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo" +/// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo" /// where the size in bytes of the directive is specified by Size and Hi/Lo /// specify the labels. This implicitly uses .set if it is available. void AsmPrinter::EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset, - const MCSymbol *Lo, unsigned Size) + const MCSymbol *Lo, unsigned Size) const { - + // Emit Hi+Offset - Lo // Get the Hi+Offset expression. const MCExpr *Plus = - MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Hi, OutContext), + MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Hi, OutContext), MCConstantExpr::Create(Offset, OutContext), OutContext); - + // Get the Hi+Offset-Lo expression. - const MCExpr *Diff = + const MCExpr *Diff = MCBinaryExpr::CreateSub(Plus, MCSymbolRefExpr::Create(Lo, OutContext), OutContext); - - if (!MAI->hasSetDirective()) + + if (!MAI->hasSetDirective()) OutStreamer.EmitValue(Diff, 4, 0/*AddrSpace*/); else { // Otherwise, emit with .set (aka assignment). @@ -1252,22 +1253,22 @@ } } -/// EmitLabelPlusOffset - Emit something like ".long Label+Offset" +/// EmitLabelPlusOffset - Emit something like ".long Label+Offset" /// where the size in bytes of the directive is specified by Size and Label /// specifies the label. This implicitly uses .set if it is available. void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, - unsigned Size) + unsigned Size) const { - + // Emit Label+Offset const MCExpr *Plus = - MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Label, OutContext), + MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Label, OutContext), MCConstantExpr::Create(Offset, OutContext), OutContext); - + OutStreamer.EmitValue(Plus, 4, 0/*AddrSpace*/); } - + //===----------------------------------------------------------------------===// @@ -1279,9 +1280,9 @@ // void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const { if (GV) NumBits = getGVAlignmentLog2(GV, *TM.getTargetData(), NumBits); - + if (NumBits == 0) return; // 1-byte aligned: no need to emit alignment. - + if (getCurrentSection()->getKind().isText()) OutStreamer.EmitCodeAlignment(1 << NumBits); else @@ -1296,25 +1297,25 @@ /// static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { MCContext &Ctx = AP.OutContext; - + if (CV->isNullValue() || isa(CV)) return MCConstantExpr::Create(0, Ctx); if (const ConstantInt *CI = dyn_cast(CV)) return MCConstantExpr::Create(CI->getZExtValue(), Ctx); - + if (const GlobalValue *GV = dyn_cast(CV)) return MCSymbolRefExpr::Create(AP.Mang->getSymbol(GV), Ctx); if (const BlockAddress *BA = dyn_cast(CV)) return MCSymbolRefExpr::Create(AP.GetBlockAddressSymbol(BA), Ctx); - + const ConstantExpr *CE = dyn_cast(CV); if (CE == 0) { llvm_unreachable("Unknown constant value to lower!"); return MCConstantExpr::Create(0, Ctx); } - + switch (CE->getOpcode()) { default: // If the code isn't optimized, there may be outstanding folding @@ -1342,21 +1343,21 @@ SmallVector IdxVec(CE->op_begin()+1, CE->op_end()); int64_t Offset = TD.getIndexedOffset(PtrVal->getType(), &IdxVec[0], IdxVec.size()); - + const MCExpr *Base = LowerConstant(CE->getOperand(0), AP); if (Offset == 0) return Base; - + // Truncate/sext the offset to the pointer size. if (TD.getPointerSizeInBits() != 64) { int SExtAmount = 64-TD.getPointerSizeInBits(); Offset = (Offset << SExtAmount) >> SExtAmount; } - + return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx), Ctx); } - + case Instruction::Trunc: // We emit the value and depend on the assembler to truncate the generated // expression properly. This is important for differences between @@ -1375,7 +1376,7 @@ false/*ZExt*/); return LowerConstant(Op, AP); } - + case Instruction::PtrToInt: { const TargetData &TD = *AP.TM.getTargetData(); // Support only foldable casts to/from pointers that can be eliminated by @@ -1397,7 +1398,7 @@ const MCExpr *MaskExpr = MCConstantExpr::Create(~0ULL >> (64-InBits), Ctx); return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx); } - + // The MC library also has a right-shift operator, but it isn't consistently // signed or unsigned between different targets. case Instruction::Add: @@ -1438,7 +1439,7 @@ EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP); return; } - + // Otherwise, it can be emitted as .ascii. SmallVector TmpVec; TmpVec.reserve(CA->getNumOperands()); @@ -1496,7 +1497,7 @@ AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace); return; } - + if (CFP->getType()->isFloatTy()) { if (AP.isVerbose()) { float Val = CFP->getValueAPF().convertToFloat(); @@ -1506,7 +1507,7 @@ AP.OutStreamer.EmitIntValue(Val, 4, AddrSpace); return; } - + if (CFP->getType()->isX86_FP80Ty()) { // all long double variants are printed as hex // API needed to prevent premature destruction @@ -1521,7 +1522,7 @@ AP.OutStreamer.GetCommentOS() << "x86_fp80 ~= " << DoubleVal.convertToDouble() << '\n'; } - + if (AP.TM.getTargetData()->isBigEndian()) { AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace); AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); @@ -1529,14 +1530,14 @@ AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace); } - + // Emit the tail padding for the long double. const TargetData &TD = *AP.TM.getTargetData(); AP.OutStreamer.EmitZeros(TD.getTypeAllocSize(CFP->getType()) - TD.getTypeStoreSize(CFP->getType()), AddrSpace); return; } - + assert(CFP->getType()->isPPC_FP128Ty() && "Floating point constant type not handled"); // All long double variants are printed as hex @@ -1591,10 +1592,10 @@ return; } } - + if (const ConstantArray *CVA = dyn_cast(CV)) return EmitGlobalConstantArray(CVA, AddrSpace, AP); - + if (const ConstantStruct *CVS = dyn_cast(CV)) return EmitGlobalConstantStruct(CVS, AddrSpace, AP); @@ -1606,10 +1607,10 @@ AP.OutStreamer.EmitIntValue(0, Size, AddrSpace); return; } - + if (const ConstantVector *V = dyn_cast(CV)) return EmitGlobalConstantVector(V, AddrSpace, AP); - + // Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it // thread the streamer with EmitValue. AP.OutStreamer.EmitValue(LowerConstant(CV, AP), @@ -1706,7 +1707,7 @@ SmallString<60> NameStr; Mang->getNameWithPrefix(NameStr, Sym); return OutContext.GetOrCreateSymbol(NameStr.str()); -} +} @@ -1743,10 +1744,10 @@ // Add loop depth information const MachineLoop *Loop = LI->getLoopFor(&MBB); if (Loop == 0) return; - + MachineBasicBlock *Header = Loop->getHeader(); assert(Header && "No header for loop"); - + // If this block is not a loop header, just print out what is the loop header // and return. if (Header != &MBB) { @@ -1756,21 +1757,21 @@ " Depth="+Twine(Loop->getLoopDepth())); return; } - + // Otherwise, it is a loop header. Print out information about child and // parent loops. raw_ostream &OS = AP.OutStreamer.GetCommentOS(); - - PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber()); - + + PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber()); + OS << "=>"; OS.indent(Loop->getLoopDepth()*2-2); - + OS << "This "; if (Loop->empty()) OS << "Inner "; OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n'; - + PrintChildLoopComment(OS, Loop, AP.getFunctionNumber()); } @@ -1791,7 +1792,7 @@ const BasicBlock *BB = MBB->getBasicBlock(); if (isVerbose()) OutStreamer.AddComment("Block address taken"); - + std::vector Syms = MMI->getAddrLabelSymbolToEmit(BB); for (unsigned i = 0, e = Syms.size(); i != e; ++i) @@ -1804,9 +1805,9 @@ if (const BasicBlock *BB = MBB->getBasicBlock()) if (BB->hasName()) OutStreamer.AddComment("%" + BB->getName()); - + EmitBasicBlockLoopComments(*MBB, LI, *this); - + // NOTE: Want this comment at start of line, don't emit with AddComment. OutStreamer.EmitRawText(Twine(MAI->getCommentString()) + " BB#" + Twine(MBB->getNumber()) + ":"); @@ -1826,7 +1827,7 @@ void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility, bool IsDefinition) const { MCSymbolAttr Attr = MCSA_Invalid; - + switch (Visibility) { default: break; case GlobalValue::HiddenVisibility: @@ -1853,23 +1854,23 @@ // then nothing falls through to it. if (MBB->isLandingPad() || MBB->pred_empty()) return false; - + // If there isn't exactly one predecessor, it can't be a fall through. MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; ++PI2; if (PI2 != MBB->pred_end()) return false; - + // The predecessor has to be immediately before this block. const MachineBasicBlock *Pred = *PI; - + if (!Pred->isLayoutSuccessor(MBB)) return false; - + // If the block is completely empty, then it definitely does fall through. if (Pred->empty()) return true; - + // Otherwise, check the last instruction. const MachineInstr &LastInst = Pred->back(); return !LastInst.getDesc().isBarrier(); @@ -1885,9 +1886,9 @@ gcp_map_type::iterator GCPI = GCMap.find(S); if (GCPI != GCMap.end()) return GCPI->second; - + const char *Name = S->getName().c_str(); - + for (GCMetadataPrinterRegistry::iterator I = GCMetadataPrinterRegistry::begin(), E = GCMetadataPrinterRegistry::end(); I != E; ++I) @@ -1897,7 +1898,7 @@ GCMap.insert(std::make_pair(S, GMP)); return GMP; } - + report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name)); return 0; } From isanbard at gmail.com Tue Mar 29 18:28:02 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 29 Mar 2011 23:28:02 -0000 Subject: [llvm-commits] [llvm] r128506 - /llvm/trunk/lib/Linker/LinkModules.cpp Message-ID: <20110329232802.42E902A6C12C@llvm.org> Author: void Date: Tue Mar 29 18:28:02 2011 New Revision: 128506 URL: http://llvm.org/viewvc/llvm-project?rev=128506&view=rev Log: Revert r128501. It caused test failures. Modified: llvm/trunk/lib/Linker/LinkModules.cpp Modified: llvm/trunk/lib/Linker/LinkModules.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=128506&r1=128505&r2=128506&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp (original) +++ llvm/trunk/lib/Linker/LinkModules.cpp Tue Mar 29 18:28:02 2011 @@ -352,7 +352,6 @@ unsigned Alignment = std::max(DestGV->getAlignment(), SrcGV->getAlignment()); DestGV->copyAttributesFrom(SrcGV); DestGV->setAlignment(Alignment); - DestGV->setUnnamedAddr(SrcGV->hasUnnamedAddr()); } /// GetLinkageResult - This analyzes the two global values and determines what From isanbard at gmail.com Tue Mar 29 18:31:06 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 29 Mar 2011 23:31:06 -0000 Subject: [llvm-commits] [llvm] r128507 - /llvm/trunk/lib/Linker/LinkModules.cpp Message-ID: <20110329233106.A5BFB2A6C12C@llvm.org> Author: void Date: Tue Mar 29 18:31:06 2011 New Revision: 128507 URL: http://llvm.org/viewvc/llvm-project?rev=128507&view=rev Log: Set the unnamed_addr only when we're creating a new GV in the dest module. Modified: llvm/trunk/lib/Linker/LinkModules.cpp Modified: llvm/trunk/lib/Linker/LinkModules.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=128507&r1=128506&r2=128507&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp (original) +++ llvm/trunk/lib/Linker/LinkModules.cpp Tue Mar 29 18:31:06 2011 @@ -505,6 +505,7 @@ SGV->getType()->getAddressSpace()); // Propagate alignment, visibility and section info. CopyGVAttributes(NewDGV, SGV); + NewDGV->setUnnamedAddr(SGV->hasUnnamedAddr()); // If the LLVM runtime renamed the global, but it is an externally visible // symbol, DGV must be an existing global with internal linkage. Rename From evan.cheng at apple.com Tue Mar 29 18:51:37 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 29 Mar 2011 23:51:37 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r128510 - /llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm.cpp Message-ID: <20110329235137.5658A2A6C12C@llvm.org> Author: evancheng Date: Tue Mar 29 18:51:37 2011 New Revision: 128510 URL: http://llvm.org/viewvc/llvm-project?rev=128510&view=rev Log: Lower __builtin_neon_vmull* etc. directly to llvm intrinsics @llvm.arm.neon.vmulls and @llvm.arm.neon.vmullu.*. Also lower __builtin_neon_vmlal*, __builtin_neon_vmlsl* etc. to the intrinsics plus an add / sub instruction. This change ensures optimizer won't hoist the sext / zext away from the mul instruction which would cause performance regression. Second part of rdar://8832507, rdar://9203134 Modified: llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm.cpp Modified: llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm.cpp?rev=128510&r1=128509&r2=128510&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm.cpp Tue Mar 29 18:51:37 2011 @@ -929,17 +929,16 @@ return UnexpectedError("%Hinvalid lane number", exp, Result); Ops[2] = BuildDupLane(Ops[2], LaneVal, NUnits, Builder); } - if (datatype == neon_datatype_signed) { - Ops[1] = Builder.CreateSExt(Ops[1], ResultType); - Ops[2] = Builder.CreateSExt(Ops[2], ResultType); - } else if (datatype == neon_datatype_unsigned) { - Ops[1] = Builder.CreateZExt(Ops[1], ResultType); - Ops[2] = Builder.CreateZExt(Ops[2], ResultType); - } else + if (datatype == neon_datatype_signed) + intID = Intrinsic::arm_neon_vmulls; + else if (datatype == neon_datatype_unsigned) + intID = Intrinsic::arm_neon_vmullu; + else return BadImmediateError(exp, Result); - Ops[1] = Builder.CreateMul(Ops[1], Ops[2]); - Result = Builder.CreateAdd(Ops[0], Ops[1]); + intFn = Intrinsic::getDeclaration(TheModule, intID, &ResultType, 1); + Result = Builder.CreateCall2(intFn, Ops[1], Ops[2]); + Result = Builder.CreateAdd(Ops[0], Result); break; case NEON_BUILTIN_vmlsl_lane: @@ -954,17 +953,16 @@ return UnexpectedError("%Hinvalid lane number", exp, Result); Ops[2] = BuildDupLane(Ops[2], LaneVal, NUnits, Builder); } - if (datatype == neon_datatype_signed) { - Ops[1] = Builder.CreateSExt(Ops[1], ResultType); - Ops[2] = Builder.CreateSExt(Ops[2], ResultType); - } else if (datatype == neon_datatype_unsigned) { - Ops[1] = Builder.CreateZExt(Ops[1], ResultType); - Ops[2] = Builder.CreateZExt(Ops[2], ResultType); - } else + if (datatype == neon_datatype_signed) + intID = Intrinsic::arm_neon_vmulls; + else if (datatype == neon_datatype_unsigned) + intID = Intrinsic::arm_neon_vmullu; + else return BadImmediateError(exp, Result); - Ops[1] = Builder.CreateMul(Ops[1], Ops[2]); - Result = Builder.CreateSub(Ops[0], Ops[1]); + intFn = Intrinsic::getDeclaration(TheModule, intID, &ResultType, 1); + Result = Builder.CreateCall2(intFn, Ops[1], Ops[2]); + Result = Builder.CreateSub(Ops[0], Result); break; case NEON_BUILTIN_vqdmulh_lane: @@ -1044,22 +1042,17 @@ return UnexpectedError("%Hinvalid lane number", exp, Result); Ops[1] = BuildDupLane(Ops[1], LaneVal, NUnits, Builder); } - if (datatype == neon_datatype_polynomial) { + if (datatype == neon_datatype_polynomial) intID = Intrinsic::arm_neon_vmullp; - intFn = Intrinsic::getDeclaration(TheModule, intID, &ResultType, 1); - Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]); - break; - } - if (datatype == neon_datatype_signed) { - Ops[0] = Builder.CreateSExt(Ops[0], ResultType); - Ops[1] = Builder.CreateSExt(Ops[1], ResultType); - } else if (datatype == neon_datatype_unsigned) { - Ops[0] = Builder.CreateZExt(Ops[0], ResultType); - Ops[1] = Builder.CreateZExt(Ops[1], ResultType); - } else + else if (datatype == neon_datatype_signed) + intID = Intrinsic::arm_neon_vmulls; + else if (datatype == neon_datatype_unsigned) + intID = Intrinsic::arm_neon_vmullu; + else return BadImmediateError(exp, Result); - Result = Builder.CreateMul(Ops[0], Ops[1]); + intFn = Intrinsic::getDeclaration(TheModule, intID, &ResultType, 1); + Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]); break; case NEON_BUILTIN_vqdmull_n: From akyrtzi at gmail.com Tue Mar 29 19:22:00 2011 From: akyrtzi at gmail.com (Argyrios Kyrtzidis) Date: Wed, 30 Mar 2011 00:22:00 -0000 Subject: [llvm-commits] [llvm] r128515 - /llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Message-ID: <20110330002200.D884E2A6C12C@llvm.org> Author: akirtzidis Date: Tue Mar 29 19:22:00 2011 New Revision: 128515 URL: http://llvm.org/viewvc/llvm-project?rev=128515&view=rev Log: ClangSAEmClangSACheckersEmitter, emit info about groups. Modified: llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp?rev=128515&r1=128514&r2=128515&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Tue Mar 29 19:22:00 2011 @@ -98,28 +98,6 @@ llvm::DenseMap checkerRecIndexMap; for (unsigned i = 0, e = checkers.size(); i != e; ++i) checkerRecIndexMap[checkers[i]] = i; - - OS << "\n#ifdef GET_CHECKERS\n"; - for (unsigned i = 0, e = checkers.size(); i != e; ++i) { - const Record &R = *checkers[i]; - - OS << "CHECKER(" << "\""; - std::string name; - if (isCheckerNamed(&R)) - name = getCheckerFullName(&R); - OS.write_escaped(name) << "\", "; - OS << R.getName() << ", "; - OS << getStringValue(R, "DescFile") << ", "; - OS << "\""; - OS.write_escaped(getStringValue(R, "HelpText")) << "\", "; - // Hidden bit - if (isHidden(R)) - OS << "true"; - else - OS << "false"; - OS << ")\n"; - } - OS << "#endif // GET_CHECKERS\n\n"; // Invert the mapping of checkers to package/group into a one to many // mapping of packages/groups to checkers. @@ -148,48 +126,6 @@ } } - typedef std::map SortedRecords; - - OS << "\n#ifdef GET_PACKAGES\n"; - { - SortedRecords sortedPackages; - for (unsigned i = 0, e = packages.size(); i != e; ++i) - sortedPackages[getPackageFullName(packages[i])] = packages[i]; - - for (SortedRecords::iterator - I = sortedPackages.begin(), E = sortedPackages.end(); I != E; ++I) { - const Record &R = *I->second; - - OS << "PACKAGE(" << "\""; - OS.write_escaped(getPackageFullName(&R)) << "\", "; - // Hidden bit - if (isHidden(R)) - OS << "true"; - else - OS << "false"; - OS << ")\n"; - } - } - OS << "#endif // GET_PACKAGES\n\n"; - - OS << "\n#ifdef GET_GROUPS\n"; - { - SortedRecords sortedGroups; - for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) - sortedGroups[checkerGroups[i]->getValueAsString("GroupName")] - = checkerGroups[i]; - - for (SortedRecords::iterator - I = sortedGroups.begin(), E = sortedGroups.end(); I != E; ++I) { - const Record &R = *I->second; - - OS << "GROUP(" << "\""; - OS.write_escaped(R.getValueAsString("GroupName")) << "\""; - OS << ")\n"; - } - } - OS << "#endif // GET_GROUPS\n\n"; - for (unsigned i = 0, e = checkers.size(); i != e; ++i) { Record *R = checkers[i]; Record *package = 0; @@ -230,6 +166,85 @@ if (DefInit *DI = dynamic_cast(packages[i]->getValueInit("Group"))) addPackageToCheckerGroup(packages[i], DI->getDef(), recordGroupMap); + typedef std::map SortedRecords; + typedef llvm::DenseMap RecToSortIndex; + + SortedRecords sortedGroups; + RecToSortIndex groupToSortIndex; + OS << "\n#ifdef GET_GROUPS\n"; + { + for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) + sortedGroups[checkerGroups[i]->getValueAsString("GroupName")] + = checkerGroups[i]; + + unsigned sortIndex = 0; + for (SortedRecords::iterator + I = sortedGroups.begin(), E = sortedGroups.end(); I != E; ++I) { + const Record *R = I->second; + + OS << "GROUP(" << "\""; + OS.write_escaped(R->getValueAsString("GroupName")) << "\""; + OS << ")\n"; + + groupToSortIndex[R] = sortIndex++; + } + } + OS << "#endif // GET_GROUPS\n\n"; + + OS << "\n#ifdef GET_PACKAGES\n"; + { + SortedRecords sortedPackages; + for (unsigned i = 0, e = packages.size(); i != e; ++i) + sortedPackages[getPackageFullName(packages[i])] = packages[i]; + + for (SortedRecords::iterator + I = sortedPackages.begin(), E = sortedPackages.end(); I != E; ++I) { + const Record &R = *I->second; + + OS << "PACKAGE(" << "\""; + OS.write_escaped(getPackageFullName(&R)) << "\", "; + // Group index + if (DefInit *DI = dynamic_cast(R.getValueInit("Group"))) + OS << groupToSortIndex[DI->getDef()] << ", "; + else + OS << "-1, "; + // Hidden bit + if (isHidden(R)) + OS << "true"; + else + OS << "false"; + OS << ")\n"; + } + } + OS << "#endif // GET_PACKAGES\n\n"; + + OS << "\n#ifdef GET_CHECKERS\n"; + for (unsigned i = 0, e = checkers.size(); i != e; ++i) { + const Record &R = *checkers[i]; + + OS << "CHECKER(" << "\""; + std::string name; + if (isCheckerNamed(&R)) + name = getCheckerFullName(&R); + OS.write_escaped(name) << "\", "; + OS << R.getName() << ", "; + OS << getStringValue(R, "DescFile") << ", "; + OS << "\""; + OS.write_escaped(getStringValue(R, "HelpText")) << "\", "; + // Group index + if (DefInit *DI = dynamic_cast(R.getValueInit("Group"))) + OS << groupToSortIndex[DI->getDef()] << ", "; + else + OS << "-1, "; + // Hidden bit + if (isHidden(R)) + OS << "true"; + else + OS << "false"; + OS << ")\n"; + } + OS << "#endif // GET_CHECKERS\n\n"; + unsigned index = 0; for (std::map::iterator I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) From gohman at apple.com Tue Mar 29 19:37:59 2011 From: gohman at apple.com (Dan Gohman) Date: Tue, 29 Mar 2011 17:37:59 -0700 Subject: [llvm-commits] [llvm] r128333 - /llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp In-Reply-To: References: <20110326093207.F321E2A6C12C@llvm.org> <689909C8-632D-42DC-81DD-310B056D372D@apple.com> Message-ID: On Mar 26, 2011, at 5:42 PM, Bill Wendling wrote: > On Mar 26, 2011, at 8:52 AM, Frits van Bommel wrote: > >> On Sat, Mar 26, 2011 at 4:39 PM, Dan Gohman wrote: >>> On Mar 26, 2011, at 2:32 AM, Bill Wendling wrote: >>>> Simplification noticed by Frits. >>>> >>>> Modified: >>>> llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp >> >>>> - if ((EarlierOff == LaterOff && Earlier.Size <= Later.Size) || >>>> - (EarlierOff > LaterOff && >>>> - EarlierOff + Earlier.Size <= LaterOff + Later.Size)) >>>> + if (EarlierOff >= LaterOff && >>>> + EarlierOff + Earlier.Size <= LaterOff + Later.Size) >>>> return true; >>> >>> I don't have time to fully investigate, but the testcase passes without the fix, >> >> What testcase? This commit doesn't have a testcase (and doesn't need >> one, given the next point). >> >>> and the new code is now equivalent by De Morgan's law to the old code. >> >> Hint: the commit message called it a "simplification" because it *is* >> equivalent (but simpler) code. >> >> I'm not sure where you're getting De Morgan's law from though, since >> there's no negation anywhere... >> (The only De Morgan's laws I know about are these: >> ) > > I think he means from what it originally was. The reason I'm messing with this code is because of PR9561. What I did is a De Morgan's change from the old code. Being equivalent means it doesn't fix the bug. > But I disagree that the testcase passed before the previous change: > > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20110321/118574.html > > At least it didn't pass for me. :) Please check again :). Dan From johnny.chen at apple.com Tue Mar 29 20:02:06 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 30 Mar 2011 01:02:06 -0000 Subject: [llvm-commits] [llvm] r128517 - /llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt Message-ID: <20110330010206.D64CF2A6C12C@llvm.org> Author: johnny Date: Tue Mar 29 20:02:06 2011 New Revision: 128517 URL: http://llvm.org/viewvc/llvm-project?rev=128517&view=rev Log: Add a test case for thumb stc2 instruction. Modified: llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt Modified: llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt?rev=128517&r1=128516&r2=128517&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt Tue Mar 29 20:02:06 2011 @@ -196,3 +196,6 @@ # CHECK: pld [pc, #-16] 0x1f 0xf8 0x10 0xf0 + +# CHECK: stc2 p12, cr15, [r9], {137} +0x89 0xfc 0x89 0xfc From isanbard at gmail.com Tue Mar 29 20:03:48 2011 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 30 Mar 2011 01:03:48 -0000 Subject: [llvm-commits] [llvm] r128519 - /llvm/trunk/lib/VMCore/AutoUpgrade.cpp Message-ID: <20110330010348.64AA52A6C12C@llvm.org> Author: void Date: Tue Mar 29 20:03:48 2011 New Revision: 128519 URL: http://llvm.org/viewvc/llvm-project?rev=128519&view=rev Log: Remove dead code. Modified: llvm/trunk/lib/VMCore/AutoUpgrade.cpp Modified: llvm/trunk/lib/VMCore/AutoUpgrade.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AutoUpgrade.cpp?rev=128519&r1=128518&r2=128519&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AutoUpgrade.cpp (original) +++ llvm/trunk/lib/VMCore/AutoUpgrade.cpp Tue Mar 29 20:03:48 2011 @@ -1179,74 +1179,6 @@ break; } -#if 0 - case Intrinsic::x86_mmx_cvtsi32_si64: { - // The return type needs to be changed. - Value *Operands[1]; - Operands[0] = CI->getArgOperand(0); - ConstructNewCallInst(NewFn, CI, Operands, 1); - break; - } - case Intrinsic::x86_mmx_cvtsi64_si32: { - Value *Operands[1]; - - // Cast the operand to the X86 MMX type. - Operands[0] = new BitCastInst(CI->getArgOperand(0), - NewFn->getFunctionType()->getParamType(0), - "upgraded.", CI); - - ConstructNewCallInst(NewFn, CI, Operands, 1); - break; - } - case Intrinsic::x86_mmx_vec_init_b: - case Intrinsic::x86_mmx_vec_init_w: - case Intrinsic::x86_mmx_vec_init_d: { - // The return type needs to be changed. - Value *Operands[8]; - unsigned NumOps = 0; - - switch (NewFn->getIntrinsicID()) { - default: break; - case Intrinsic::x86_mmx_vec_init_b: NumOps = 8; break; - case Intrinsic::x86_mmx_vec_init_w: NumOps = 4; break; - case Intrinsic::x86_mmx_vec_init_d: NumOps = 2; break; - } - - switch (NewFn->getIntrinsicID()) { - default: break; - case Intrinsic::x86_mmx_vec_init_b: - Operands[7] = CI->getArgOperand(7); - Operands[6] = CI->getArgOperand(6); - Operands[5] = CI->getArgOperand(5); - Operands[4] = CI->getArgOperand(4); - // FALLTHRU - case Intrinsic::x86_mmx_vec_init_w: - Operands[3] = CI->getArgOperand(3); - Operands[2] = CI->getArgOperand(2); - // FALLTHRU - case Intrinsic::x86_mmx_vec_init_d: - Operands[1] = CI->getArgOperand(1); - Operands[0] = CI->getArgOperand(0); - break; - } - - ConstructNewCallInst(NewFn, CI, Operands, NumOps); - break; - } - case Intrinsic::x86_mmx_vec_ext_d: { - Value *Operands[2]; - - // Cast the operand to the X86 MMX type. - Operands[0] = new BitCastInst(CI->getArgOperand(0), - NewFn->getFunctionType()->getParamType(0), - "upgraded.", CI); - Operands[1] = CI->getArgOperand(1); - - ConstructNewCallInst(NewFn, CI, Operands, 2); - break; - } -#endif - case Intrinsic::ctlz: case Intrinsic::ctpop: case Intrinsic::cttz: { From kyrtzidis at apple.com Tue Mar 29 16:05:20 2011 From: kyrtzidis at apple.com (Argyrios Kyrtzidis) Date: Tue, 29 Mar 2011 14:05:20 -0700 Subject: [llvm-commits] [llvm] r128474 - /llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp In-Reply-To: References: <20110329185300.BD8AE2A6C12C@llvm.org> Message-ID: On Mar 29, 2011, at 1:28 PM, Tilmann Scheller wrote: > Hi Argyrios, > > please don't use a data structure whose order is non-determinstic (walking over a DenseSet gives different results depending on the memory layout), this leads to Checkers.inc being different on every run :) Oops, I'll change it, thanks! -Argyrios > > Regards, > > Tilmann > > On Tue, Mar 29, 2011 at 8:53 PM, Argyrios Kyrtzidis wrote: > Author: akirtzidis > Date: Tue Mar 29 13:53:00 2011 > New Revision: 128474 > > URL: http://llvm.org/viewvc/llvm-project?rev=128474&view=rev > Log: > For ClangSACheckersEmitter, allow a package to belong to checker group, in which all its checkers will go into the group. > > Modified: > llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp > > Modified: llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp?rev=128474&r1=128473&r2=128474&view=diff > ============================================================================== > --- llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp (original) > +++ llvm/trunk/utils/TableGen/ClangSACheckersEmitter.cpp Tue Mar 29 13:53:00 2011 > @@ -71,7 +71,7 @@ > > namespace { > struct GroupInfo { > - std::vector Checkers; > + llvm::DenseSet Checkers; > llvm::DenseSet SubGroups; > bool Hidden; > unsigned Index; > @@ -80,6 +80,19 @@ > }; > } > > +static void addPackageToCheckerGroup(const Record *package, const Record *group, > + llvm::DenseMap &recordGroupMap) { > + llvm::DenseSet &checkers = recordGroupMap[package]->Checkers; > + for (llvm::DenseSet::iterator > + I = checkers.begin(), E = checkers.end(); I != E; ++I) > + recordGroupMap[group]->Checkers.insert(*I); > + > + llvm::DenseSet &subGroups = recordGroupMap[package]->SubGroups; > + for (llvm::DenseSet::iterator > + I = subGroups.begin(), E = subGroups.end(); I != E; ++I) > + addPackageToCheckerGroup(*I, group, recordGroupMap); > +} > + > void ClangSACheckersEmitter::run(raw_ostream &OS) { > std::vector checkers = Records.getAllDerivedDefinitions("Checker"); > llvm::DenseMap checkerRecIndexMap; > @@ -150,9 +163,9 @@ > GroupInfo &info = groupInfoByName[fullName]; > info.Hidden = R->getValueAsBit("Hidden"); > recordGroupMap[R] = &info; > - info.Checkers.push_back(R); > + info.Checkers.insert(R); > } else { > - recordGroupMap[package]->Checkers.push_back(R); > + recordGroupMap[package]->Checkers.insert(R); > } > > Record *currR = isCheckerNamed(R) ? R : package; > @@ -166,9 +179,15 @@ > } > // Insert the checker into the set of its group. > if (DefInit *DI = dynamic_cast(R->getValueInit("Group"))) > - recordGroupMap[DI->getDef()]->Checkers.push_back(R); > + recordGroupMap[DI->getDef()]->Checkers.insert(R); > } > > + // If a package is in group, add all its checkers and its sub-packages > + // checkers into the group. > + for (unsigned i = 0, e = packages.size(); i != e; ++i) > + if (DefInit *DI = dynamic_cast(packages[i]->getValueInit("Group"))) > + addPackageToCheckerGroup(packages[i], DI->getDef(), recordGroupMap); > + > unsigned index = 0; > for (std::map::iterator > I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) > @@ -183,11 +202,12 @@ > I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) { > maxLen = std::max(maxLen, (unsigned)I->first.size()); > > - std::vector &V = I->second.Checkers; > - if (!V.empty()) { > + llvm::DenseSet &checkers = I->second.Checkers; > + if (!checkers.empty()) { > OS << "static const short CheckerArray" << I->second.Index << "[] = { "; > - for (unsigned i = 0, e = V.size(); i != e; ++i) > - OS << checkerRecIndexMap[V[i]] << ", "; > + for (llvm::DenseSet::iterator > + I = checkers.begin(), E = checkers.end(); I != E; ++I) > + OS << checkerRecIndexMap[*I] << ", "; > OS << "-1 };\n"; > } > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110329/ac3fb67b/attachment.html From stoklund at 2pi.dk Tue Mar 29 21:52:40 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 30 Mar 2011 02:52:40 -0000 Subject: [llvm-commits] [llvm] r128524 - in /llvm/trunk/lib/CodeGen: LiveRangeEdit.cpp LiveRangeEdit.h RegAllocGreedy.cpp Message-ID: <20110330025240.2D4592A6C12C@llvm.org> Author: stoklund Date: Tue Mar 29 21:52:39 2011 New Revision: 128524 URL: http://llvm.org/viewvc/llvm-project?rev=128524&view=rev Log: Treat clones the same as their origin. When DCE clones a live range because it separates into connected components, make sure that the clones enter the same register allocator stage as the register they were cloned from. For instance, clones may be split even when they where created during spilling. Other registers created during spilling are not candidates for splitting or even (re-)spilling. Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp llvm/trunk/lib/CodeGen/LiveRangeEdit.h llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp?rev=128524&r1=128523&r2=128524&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp Tue Mar 29 21:52:39 2011 @@ -231,8 +231,11 @@ continue; DEBUG(dbgs() << NumComp << " components: " << *LI << '\n'); SmallVector Dups(1, LI); - for (unsigned i = 1; i != NumComp; ++i) + for (unsigned i = 1; i != NumComp; ++i) { Dups.push_back(&createFrom(LI->reg, LIS, VRM)); + if (delegate_) + delegate_->LRE_DidCloneVirtReg(Dups.back()->reg, LI->reg); + } ConEQ.Distribute(&Dups[0], VRM.getRegInfo()); } } Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.h?rev=128524&r1=128523&r2=128524&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.h (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.h Tue Mar 29 21:52:39 2011 @@ -43,6 +43,10 @@ /// Called before shrinking the live range of a virtual register. virtual void LRE_WillShrinkVirtReg(unsigned) {} + /// Called after cloning a virtual register. + /// This is used for new registers representing connected components of Old. + virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old) {} + virtual ~Delegate() {} }; Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=128524&r1=128523&r2=128524&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Tue Mar 29 21:52:39 2011 @@ -90,7 +90,8 @@ // range splitting algorithm terminates, something that is otherwise hard to // ensure. enum LiveRangeStage { - RS_Original, ///< Never seen before, never split. + RS_New, ///< Never seen before. + RS_First, ///< First time in the queue. RS_Second, ///< Second time in the queue. RS_Region, ///< Produced by region splitting. RS_Block, ///< Produced by per-block splitting. @@ -107,8 +108,11 @@ template void setStage(Iterator Begin, Iterator End, LiveRangeStage NewStage) { LRStage.resize(MRI->getNumVirtRegs()); - for (;Begin != End; ++Begin) - LRStage[(*Begin)->reg] = NewStage; + for (;Begin != End; ++Begin) { + unsigned Reg = (*Begin)->reg; + if (LRStage[Reg] == RS_New) + LRStage[Reg] = NewStage; + } } // splitting state. @@ -162,6 +166,7 @@ void LRE_WillEraseInstruction(MachineInstr*); bool LRE_CanEraseVirtReg(unsigned); void LRE_WillShrinkVirtReg(unsigned); + void LRE_DidCloneVirtReg(unsigned, unsigned); void mapGlobalInterference(unsigned, SmallVectorImpl&); float calcSplitConstraints(const SmallVectorImpl&); @@ -192,7 +197,7 @@ return new RAGreedy(); } -RAGreedy::RAGreedy(): MachineFunctionPass(ID), LRStage(RS_Original) { +RAGreedy::RAGreedy(): MachineFunctionPass(ID), LRStage(RS_New) { initializeSlotIndexesPass(*PassRegistry::getPassRegistry()); initializeLiveIntervalsPass(*PassRegistry::getPassRegistry()); initializeSlotIndexesPass(*PassRegistry::getPassRegistry()); @@ -265,6 +270,14 @@ enqueue(&LI); } +void RAGreedy::LRE_DidCloneVirtReg(unsigned New, unsigned Old) { + // LRE may clone a virtual register because dead code elimination causes it to + // be split into connected components. Ensure that the new register gets the + // same stage as the parent. + LRStage.grow(New); + LRStage[New] = LRStage[Old]; +} + void RAGreedy::releaseMemory() { SpillerInstance.reset(0); LRStage.clear(); @@ -281,6 +294,9 @@ unsigned Prio; LRStage.grow(Reg); + if (LRStage[Reg] == RS_New) + LRStage[Reg] = RS_First; + if (LRStage[Reg] == RS_Second) // Unsplit ranges that couldn't be allocated immediately are deferred until // everything else has been allocated. Long ranges are allocated last so @@ -1146,7 +1162,7 @@ // Wait until the second time, when all smaller ranges have been allocated. // This gives a better picture of the interference to split around. LiveRangeStage Stage = getStage(VirtReg); - if (Stage == RS_Original) { + if (Stage == RS_First) { LRStage[VirtReg.reg] = RS_Second; DEBUG(dbgs() << "wait for second round\n"); NewVRegs.push_back(&VirtReg); From nicholas at mxc.ca Tue Mar 29 23:30:08 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 29 Mar 2011 21:30:08 -0700 Subject: [llvm-commits] [llvm] r128501 - /llvm/trunk/lib/Linker/LinkModules.cpp In-Reply-To: <20110329230541.EBEB82A6C12C@llvm.org> References: <20110329230541.EBEB82A6C12C@llvm.org> Message-ID: <4D92B1D0.8000408@mxc.ca> Bill Wendling wrote: > Author: void > Date: Tue Mar 29 18:05:41 2011 > New Revision: 128501 > > URL: http://llvm.org/viewvc/llvm-project?rev=128501&view=rev > Log: > We need to copy over the unnamed_addr attribute. Oh hey! I was just wondering why I didn't see the unnamed_addr attribute show up anywhere! Thanks Bill! Nick > > Modified: > llvm/trunk/lib/Linker/LinkModules.cpp > > Modified: llvm/trunk/lib/Linker/LinkModules.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=128501&r1=128500&r2=128501&view=diff > ============================================================================== > --- llvm/trunk/lib/Linker/LinkModules.cpp (original) > +++ llvm/trunk/lib/Linker/LinkModules.cpp Tue Mar 29 18:05:41 2011 > @@ -352,6 +352,7 @@ > unsigned Alignment = std::max(DestGV->getAlignment(), SrcGV->getAlignment()); > DestGV->copyAttributesFrom(SrcGV); > DestGV->setAlignment(Alignment); > + DestGV->setUnnamedAddr(SrcGV->hasUnnamedAddr()); > } > > /// GetLinkageResult - This analyzes the two global values and determines what > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From isanbard at gmail.com Tue Mar 29 23:57:29 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 29 Mar 2011 21:57:29 -0700 Subject: [llvm-commits] [llvm] r128501 - /llvm/trunk/lib/Linker/LinkModules.cpp In-Reply-To: <4D92B1D0.8000408@mxc.ca> References: <20110329230541.EBEB82A6C12C@llvm.org> <4D92B1D0.8000408@mxc.ca> Message-ID: On Mar 29, 2011, at 9:30 PM, Nick Lewycky wrote: > Bill Wendling wrote: >> Author: void >> Date: Tue Mar 29 18:05:41 2011 >> New Revision: 128501 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=128501&view=rev >> Log: >> We need to copy over the unnamed_addr attribute. > > Oh hey! I was just wondering why I didn't see the unnamed_addr attribute show up anywhere! Thanks Bill! > Don't thank me too much yet. :-) I had to pull this patch and apply it in a different place. It appears that if you have a merge of an unnamed_addr with a regular GV, then it gets a real address. I just fixed it in the LTO case... -bw From bob.wilson at apple.com Wed Mar 30 00:26:51 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 30 Mar 2011 05:26:51 -0000 Subject: [llvm-commits] [llvm] r128526 - /llvm/trunk/include/llvm/IntrinsicsARM.td Message-ID: <20110330052651.4A9D72A6C12C@llvm.org> Author: bwilson Date: Wed Mar 30 00:26:51 2011 New Revision: 128526 URL: http://llvm.org/viewvc/llvm-project?rev=128526&view=rev Log: Revert a minor comment change inadvertently included with r128502. Modified: llvm/trunk/include/llvm/IntrinsicsARM.td Modified: llvm/trunk/include/llvm/IntrinsicsARM.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsARM.td?rev=128526&r1=128525&r2=128526&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsARM.td (original) +++ llvm/trunk/include/llvm/IntrinsicsARM.td Wed Mar 30 00:26:51 2011 @@ -296,7 +296,7 @@ def int_arm_neon_vcvthf2fp : Intrinsic<[llvm_v4f32_ty], [llvm_v4i16_ty], [IntrNoMem]>; -// Narrowing and Lengthening Vector Moves. +// Narrowing Saturating Vector Moves. def int_arm_neon_vqmovns : Neon_1Arg_Narrow_Intrinsic; def int_arm_neon_vqmovnu : Neon_1Arg_Narrow_Intrinsic; def int_arm_neon_vqmovnsu : Neon_1Arg_Narrow_Intrinsic; From baldrick at free.fr Wed Mar 30 01:30:55 2011 From: baldrick at free.fr (Duncan Sands) Date: Wed, 30 Mar 2011 06:30:55 -0000 Subject: [llvm-commits] [dragonegg] r128529 - in /dragonegg/trunk: Backend.cpp Constants.cpp Message-ID: <20110330063055.DFA8E2A6C12C@llvm.org> Author: baldrick Date: Wed Mar 30 01:30:55 2011 New Revision: 128529 URL: http://llvm.org/viewvc/llvm-project?rev=128529&view=rev Log: Remove checks that initializers are constant (TREE_CONSTANT) since they are not really helpful and can be harmful. They don't help much since if the initializer really isn't constant then the constant conversion logic will fail with an appropriate error anyway. They are harmful since some frontends, in particular the Fortran frontend when compiling Fortran 90 code, and the java frontend, forget to set TREE_CONSTANT sometimes on constants, resulting in dragonegg barfing even though there is no real problem. Modified: dragonegg/trunk/Backend.cpp dragonegg/trunk/Constants.cpp Modified: dragonegg/trunk/Backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Backend.cpp?rev=128529&r1=128528&r2=128529&view=diff ============================================================================== --- dragonegg/trunk/Backend.cpp (original) +++ dragonegg/trunk/Backend.cpp Wed Mar 30 01:30:55 2011 @@ -1010,10 +1010,6 @@ const Type *Ty = ConvertType(TREE_TYPE(decl)); Init = getDefaultValue(Ty); } else { - assert((TREE_CONSTANT(DECL_INITIAL(decl)) || - TREE_CODE(DECL_INITIAL(decl)) == STRING_CST) && - "Global initializer should be constant!"); - // Temporarily set an initializer for the global, so we don't infinitely // recurse. If we don't do this, we can hit cases where we see "oh a global // with an initializer hasn't been initialized yet, call emit_global on it". Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=128529&r1=128528&r2=128529&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Wed Mar 30 01:30:55 2011 @@ -1063,8 +1063,6 @@ /// that it has the same alloc size as the original expression and has alignment /// equal to or less than that of the original expression. Constant *ConvertInitializer(tree exp) { - assert(TREE_CONSTANT(exp) && "Isn't a constant!"); - Constant *Init; switch (TREE_CODE(exp)) { default: From baldrick at free.fr Wed Mar 30 03:35:19 2011 From: baldrick at free.fr (Duncan Sands) Date: Wed, 30 Mar 2011 10:35:19 +0200 Subject: [llvm-commits] [PATCH] remove PHINode::reserveOperandSpace() In-Reply-To: References: Message-ID: <4D92EB47.7010703@free.fr> Hi Jay, > Tested with "make check", LLVM and Clang. OK to apply? this will presumably break dragonegg since it calls reserveOperandSpace (it converts GCC's SSA form directly into LLVM's, generating phi nodes). So can you please let me know when you are about to commit and I will update dragonegg (unless you prefer to do this yourself). Ciao, Duncan. From baldrick at free.fr Wed Mar 30 04:23:16 2011 From: baldrick at free.fr (Duncan Sands) Date: Wed, 30 Mar 2011 09:23:16 -0000 Subject: [llvm-commits] [dragonegg] r128530 - /dragonegg/trunk/Convert.cpp Message-ID: <20110330092316.772602A6C12C@llvm.org> Author: baldrick Date: Wed Mar 30 04:23:16 2011 New Revision: 128530 URL: http://llvm.org/viewvc/llvm-project?rev=128530&view=rev Log: CastToAnyType could not handle pointer <-> float casts. These come up when compiling Fortran because the Fortran front-end gets the prototype of frexp and friends wrong, declaring it as frexp(ptr, float) when in fact it is frexp(float,ptr). Modified: dragonegg/trunk/Convert.cpp Modified: dragonegg/trunk/Convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Convert.cpp?rev=128530&r1=128529&r2=128530&view=diff ============================================================================== --- dragonegg/trunk/Convert.cpp (original) +++ dragonegg/trunk/Convert.cpp Wed Mar 30 04:23:16 2011 @@ -1330,18 +1330,39 @@ /// CastToAnyType - Cast the specified value to the specified type making no /// assumptions about the types of the arguments. This creates an inferred cast. Value *TreeToLLVM::CastToAnyType(Value *V, bool VisSigned, - const Type* Ty, bool TyIsSigned) { + const Type* DestTy, bool DestIsSigned) { + const Type *SrcTy = V->getType(); + // Eliminate useless casts of a type to itself. - if (V->getType() == Ty) + if (SrcTy == DestTy) return V; + // Check whether the cast needs to be done in two steps, for example a pointer + // to float cast requires converting the pointer to an integer before casting + // to the float. + if (!CastInst::isCastable(SrcTy, DestTy)) { + unsigned SrcBits = SrcTy->getScalarSizeInBits(); + unsigned DestBits = DestTy->getScalarSizeInBits(); + if (SrcBits && !isa(SrcTy)) { + const Type *IntTy = IntegerType::get(Context, SrcBits); + V = Builder.CreateBitCast(V, IntTy); + return CastToAnyType(V, VisSigned, DestTy, DestIsSigned); + } + if (DestBits && !isa(DestTy)) { + const Type *IntTy = IntegerType::get(Context, DestBits); + V = CastToAnyType(V, VisSigned, IntTy, DestIsSigned); + return Builder.CreateBitCast(V, DestTy); + } + assert(false && "Unable to cast between these types!"); + } + // The types are different so we must cast. Use getCastOpcode to create an // inferred cast opcode. Instruction::CastOps opc = - CastInst::getCastOpcode(V, VisSigned, Ty, TyIsSigned); + CastInst::getCastOpcode(V, VisSigned, DestTy, DestIsSigned); // Generate the cast and return it. - return Builder.CreateCast(opc, V, Ty); + return Builder.CreateCast(opc, V, DestTy); } /// CastToFPType - Cast the specified value to the specified type assuming From nadav.rotem at intel.com Wed Mar 30 06:06:15 2011 From: nadav.rotem at intel.com (Rotem, Nadav) Date: Wed, 30 Mar 2011 13:06:15 +0200 Subject: [llvm-commits] [PATCH] Instcombine : extractelement(cast) -> cast(extractelement) Message-ID: <6594DDFF12B03D4E89690887C248699402787296A3@hasmsx504.ger.corp.intel.com> Hi, Please review this patch to the InstCombine pass. In this patch I optimize extractelements which uses the value of cast instructions. I attempt to switch the order of the extract and the cast. I noticed a major performance boost on my workloads. Nadav Index: ../llvm/test/Transforms/InstCombine/ExtractCast.ll =================================================================== --- ../llvm/test/Transforms/InstCombine/ExtractCast.ll (revision 0) +++ ../llvm/test/Transforms/InstCombine/ExtractCast.ll (revision 0) @@ -0,0 +1,27 @@ +; RUN: opt < %s -instcombine -S -o - | FileCheck %s + +; CHECK: @a +define i32 @a(<4 x i64> %I) { +entry: +; CHECK-NOT: trunc <4 x i64> + %J = trunc <4 x i64> %I to <4 x i32> + %K = extractelement <4 x i32> %J, i32 3 +; CHECK: extractelement <4 x i64> +; CHECK: trunc i64 +; CHECK: ret + ret i32 %K +} + + +; CHECK: @b +define i32 @b(<4 x float> %I) { +entry: +; CHECK-NOT: fptosi <4 x float> + %J = fptosi <4 x float> %I to <4 x i32> + %K = extractelement <4 x i32> %J, i32 3 +; CHECK: extractelement <4 x float> +; CHECK: fptosi float +; CHECK: ret + ret i32 %K +} + Index: ../llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp =================================================================== --- ../llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp (revision 128529) +++ ../llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp (working copy) @@ -230,8 +230,17 @@ ConstantInt::get(Int32Ty, SrcIdx, false)); } + } else if (CastInst *CI = dyn_cast(I)) { + // Canonicalize extractelement(cast) -> cast(extractelement) + // Ignore bitcasts, because they change the number of vector elements + if (CI->hasOneUse() && EI.hasOneUse() && + (CI->getOpcode() != Instruction::BitCast)) { + Value *EE = Builder->CreateExtractElement(CI->getOperand(0), + EI.getIndexOperand()); + return CastInst::Create(CI->getOpcode(), cast(EE), + EI.getType()); + } } - // FIXME: Canonicalize extractelement(bitcast) -> bitcast(extractelement) } return 0; } --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110330/c8a1d910/attachment.html From jay.foad at gmail.com Wed Mar 30 06:18:26 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 30 Mar 2011 12:18:26 +0100 Subject: [llvm-commits] [PATCH] don't allocate useless PHI operands Message-ID: PHINode::resizeOperands(0) "grows the number of ops by 1.5 times". This sometimes allocates an odd number of operands, which is wasteful because PHI nodes only ever use an even number of operands. The attached patch fixes this so that we only ever allocate an even number of operands. The savings are pretty tiny. My test case was to compile sqlite3.c from the LLVM testsuite with "clang -cc1 -emit-llvm-bc -O3" on Linux/x86_64. valgrind --tool=massif shows that the peak memory usage is 81.9 MB, of which 1.17 MB is allocated in User::allocHungoffUses(). This patch reduces those figures by 6.49 KB, about 0.008% of the total memory usage or 0.5% of that allocated in User::allocHungoffUses(). Also tested with "make check", LLVM and Clang. OK to apply? Thanks, Jay. -------------- next part -------------- A non-text attachment was scrubbed... Name: phi-operands.diff Type: text/x-patch Size: 581 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110330/9bd6e4e6/attachment.bin From jay.foad at gmail.com Wed Mar 30 06:19:20 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 30 Mar 2011 11:19:20 -0000 Subject: [llvm-commits] [llvm] r128535 - in /llvm/trunk: examples/Kaleidoscope/Chapter5/ examples/Kaleidoscope/Chapter6/ examples/Kaleidoscope/Chapter7/ lib/Analysis/ lib/CodeGen/ lib/Transforms/IPO/ lib/Transforms/InstCombine/ lib/Transforms/Instrumentation/ lib/Transforms/Scalar/ lib/Transforms/Utils/ tools/bugpoint/ unittests/Transforms/Utils/ Message-ID: <20110330111921.3F0FC2A6C12C@llvm.org> Author: foad Date: Wed Mar 30 06:19:20 2011 New Revision: 128535 URL: http://llvm.org/viewvc/llvm-project?rev=128535&view=rev Log: (Almost) always call reserveOperandSpace() on newly created PHINodes. Modified: llvm/trunk/examples/Kaleidoscope/Chapter5/toy.cpp llvm/trunk/examples/Kaleidoscope/Chapter6/toy.cpp llvm/trunk/examples/Kaleidoscope/Chapter7/toy.cpp llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp llvm/trunk/tools/bugpoint/Miscompilation.cpp llvm/trunk/unittests/Transforms/Utils/Local.cpp Modified: llvm/trunk/examples/Kaleidoscope/Chapter5/toy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/Chapter5/toy.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/examples/Kaleidoscope/Chapter5/toy.cpp (original) +++ llvm/trunk/examples/Kaleidoscope/Chapter5/toy.cpp Wed Mar 30 06:19:20 2011 @@ -552,6 +552,7 @@ Builder.SetInsertPoint(MergeBB); PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), "iftmp"); + PN->reserveOperandSpace(2); PN->addIncoming(ThenV, ThenBB); PN->addIncoming(ElseV, ElseBB); @@ -593,6 +594,7 @@ // Start the PHI node with an entry for Start. PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), VarName.c_str()); + Variable->reserveOperandSpace(2); Variable->addIncoming(StartVal, PreheaderBB); // Within the loop, the variable is defined equal to the PHI node. If it Modified: llvm/trunk/examples/Kaleidoscope/Chapter6/toy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/Chapter6/toy.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/examples/Kaleidoscope/Chapter6/toy.cpp (original) +++ llvm/trunk/examples/Kaleidoscope/Chapter6/toy.cpp Wed Mar 30 06:19:20 2011 @@ -656,6 +656,7 @@ Builder.SetInsertPoint(MergeBB); PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), "iftmp"); + PN->reserveOperandSpace(2); PN->addIncoming(ThenV, ThenBB); PN->addIncoming(ElseV, ElseBB); @@ -697,6 +698,7 @@ // Start the PHI node with an entry for Start. PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), VarName.c_str()); + Variable->reserveOperandSpace(2); Variable->addIncoming(StartVal, PreheaderBB); // Within the loop, the variable is defined equal to the PHI node. If it Modified: llvm/trunk/examples/Kaleidoscope/Chapter7/toy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/Chapter7/toy.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/examples/Kaleidoscope/Chapter7/toy.cpp (original) +++ llvm/trunk/examples/Kaleidoscope/Chapter7/toy.cpp Wed Mar 30 06:19:20 2011 @@ -752,6 +752,7 @@ Builder.SetInsertPoint(MergeBB); PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), "iftmp"); + PN->reserveOperandSpace(2); PN->addIncoming(ThenV, ThenBB); PN->addIncoming(ElseV, ElseBB); Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Wed Mar 30 06:19:20 2011 @@ -932,14 +932,15 @@ Value *StepV = expandCodeFor(Step, IntTy, L->getHeader()->begin()); // Create the PHI. - Builder.SetInsertPoint(L->getHeader(), L->getHeader()->begin()); + BasicBlock *Header = L->getHeader(); + Builder.SetInsertPoint(Header, Header->begin()); + pred_iterator HPB = pred_begin(Header), HPE = pred_end(Header); PHINode *PN = Builder.CreatePHI(ExpandTy, "lsr.iv"); + PN->reserveOperandSpace(std::distance(HPB, HPE)); rememberInstruction(PN); // Create the step instructions and populate the PHI. - BasicBlock *Header = L->getHeader(); - for (pred_iterator HPI = pred_begin(Header), HPE = pred_end(Header); - HPI != HPE; ++HPI) { + for (pred_iterator HPI = HPB; HPI != HPE; ++HPI) { BasicBlock *Pred = *HPI; // Add a start value. @@ -1141,12 +1142,13 @@ // Create and insert the PHI node for the induction variable in the // specified loop. BasicBlock *Header = L->getHeader(); + pred_iterator HPB = pred_begin(Header), HPE = pred_end(Header); CanonicalIV = PHINode::Create(Ty, "indvar", Header->begin()); + CanonicalIV->reserveOperandSpace(std::distance(HPB, HPE)); rememberInstruction(CanonicalIV); Constant *One = ConstantInt::get(Ty, 1); - for (pred_iterator HPI = pred_begin(Header), HPE = pred_end(Header); - HPI != HPE; ++HPI) { + for (pred_iterator HPI = HPB; HPI != HPE; ++HPI) { BasicBlock *HP = *HPI; if (L->contains(HP)) { // Insert a unit add instruction right before the terminator Modified: llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp (original) +++ llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp Wed Mar 30 06:19:20 2011 @@ -441,6 +441,7 @@ // in NewBB. PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".unwind", NewBB); + NewPN->reserveOperandSpace(PN->getNumIncomingValues()); // Add an entry for each unwind edge, using the value from the old PHI. for (pred_iterator PI = PB; PI != PE; ++PI) NewPN->addIncoming(PN->getIncomingValueForBlock(*PI), *PI); Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Wed Mar 30 06:19:20 2011 @@ -1193,9 +1193,11 @@ const StructType *ST = cast(cast(PN->getType())->getElementType()); - Result = + PHINode *NewPN = PHINode::Create(PointerType::getUnqual(ST->getElementType(FieldNo)), PN->getName()+".f"+Twine(FieldNo), PN); + NewPN->reserveOperandSpace(PN->getNumIncomingValues()); + Result = NewPN; PHIsToRewrite.push_back(std::make_pair(PN, FieldNo)); } else { llvm_unreachable("Unknown usable value"); Modified: llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp Wed Mar 30 06:19:20 2011 @@ -432,6 +432,7 @@ // splitBasicBlock call. PHINode* PHI = PHINode::Create(Type::getInt32Ty(Inst->getContext()), "SetJmpReturn", Inst); + PHI->reserveOperandSpace(2); // Coming from a call to setjmp, the return is 0. PHI->addIncoming(Constant::getNullValue(Type::getInt32Ty(Inst->getContext())), Modified: llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp Wed Mar 30 06:19:20 2011 @@ -96,6 +96,7 @@ if (!OldPhi) break; PHINode* retPhi = PHINode::Create(OldPhi->getType(), "", Ins); + retPhi->reserveOperandSpace(2); OldPhi->replaceAllUsesWith(retPhi); Ins = newReturnBlock->getFirstNonPHI(); Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Wed Mar 30 06:19:20 2011 @@ -197,6 +197,7 @@ case Instruction::PHI: { PHINode *OPN = cast(I); PHINode *NPN = PHINode::Create(Ty); + NPN->reserveOperandSpace(OPN->getNumIncomingValues()); for (unsigned i = 0, e = OPN->getNumIncomingValues(); i != e; ++i) { Value *V =EvaluateInDifferentType(OPN->getIncomingValue(i), Ty, isSigned); NPN->addIncoming(V, OPN->getIncomingBlock(i)); Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp Wed Mar 30 06:19:20 2011 @@ -700,6 +700,7 @@ // Otherwise, Create the new PHI node for this user. EltPHI = PHINode::Create(Ty, PN->getName()+".off"+Twine(Offset), PN); + EltPHI->reserveOperandSpace(PN->getNumIncomingValues()); assert(EltPHI->getType() != PN->getType() && "Truncate didn't shrink phi?"); Modified: llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp (original) +++ llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp Wed Mar 30 06:19:20 2011 @@ -929,14 +929,16 @@ void PathProfiler::preparePHI(BLInstrumentationNode* node) { BasicBlock* block = node->getBlock(); BasicBlock::iterator insertPoint = block->getFirstNonPHI(); + pred_iterator PB = pred_begin(node->getBlock()), + PE = pred_end(node->getBlock()); PHINode* phi = PHINode::Create(Type::getInt32Ty(*Context), "pathNumber", insertPoint ); + phi->reserveOperandSpace(std::distance(PB, PE)); node->setPathPHI(phi); node->setStartingPathNumber(phi); node->setEndingPathNumber(phi); - for(pred_iterator predIt = pred_begin(node->getBlock()), - end = pred_end(node->getBlock()); predIt != end; predIt++) { + for(pred_iterator predIt = PB; predIt != PE; predIt++) { BasicBlock* pred = (*predIt); if(pred != NULL) Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Mar 30 06:19:20 2011 @@ -1944,11 +1944,12 @@ addToLeaderTable(ValNo, PREInstr, PREPred); // Create a PHI to make the value available in this block. + pred_iterator PB = pred_begin(CurrentBlock), PE = pred_end(CurrentBlock); PHINode* Phi = PHINode::Create(CurInst->getType(), CurInst->getName() + ".pre-phi", CurrentBlock->begin()); - for (pred_iterator PI = pred_begin(CurrentBlock), - PE = pred_end(CurrentBlock); PI != PE; ++PI) { + Phi->reserveOperandSpace(std::distance(PB, PE)); + for (pred_iterator PI = PB; PI != PE; ++PI) { BasicBlock *P = *PI; Phi->addIncoming(predMap[P], P); } Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Wed Mar 30 06:19:20 2011 @@ -1039,6 +1039,7 @@ // Insert new integer induction variable. PHINode *NewPHI = PHINode::Create(Int32Ty, PN->getName()+".int", PN); + NewPHI->reserveOperandSpace(2); NewPHI->addIncoming(ConstantInt::get(Int32Ty, InitValue), PN->getIncomingBlock(IncomingEdge)); Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Wed Mar 30 06:19:20 2011 @@ -928,13 +928,14 @@ array_pod_sort(AvailablePreds.begin(), AvailablePreds.end()); // Create a PHI node at the start of the block for the PRE'd load value. + pred_iterator PB = pred_begin(LoadBB), PE = pred_end(LoadBB); PHINode *PN = PHINode::Create(LI->getType(), "", LoadBB->begin()); + PN->reserveOperandSpace(std::distance(PB, PE)); PN->takeName(LI); // Insert new entries into the PHI for each predecessor. A single block may // have multiple entries here. - for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB); PI != E; - ++PI) { + for (pred_iterator PI = PB; PI != PE; ++PI) { BasicBlock *P = *PI; AvailablePredsTy::iterator I = std::lower_bound(AvailablePreds.begin(), AvailablePreds.end(), Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Wed Mar 30 06:19:20 2011 @@ -1492,6 +1492,7 @@ /* Add new PHINode. */ PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH); + NewPH->reserveOperandSpace(2); /* create new increment. '++d' in above example. */ Constant *CFP = ConstantFP::get(DestTy, C->getZExtValue()); Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Wed Mar 30 06:19:20 2011 @@ -1228,6 +1228,7 @@ const Type *LoadTy = cast(PN->getType())->getElementType(); PHINode *NewPN = PHINode::Create(LoadTy, PN->getName()+".ld", PN); + NewPN->reserveOperandSpace(PN->getNumIncomingValues()); // Get the TBAA tag and alignment to use from one of the loads. It doesn't // matter which one we get and if any differ, it doesn't matter. Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp Wed Mar 30 06:19:20 2011 @@ -259,11 +259,12 @@ PHINode *RetBlockPHI = dyn_cast(RetBlock->begin()); if (RetBlockPHI == 0) { Value *InVal = cast(RetBlock->getTerminator())->getOperand(0); + pred_iterator PB = pred_begin(RetBlock), PE = pred_end(RetBlock); RetBlockPHI = PHINode::Create(Ret->getOperand(0)->getType(), "merge", &RetBlock->front()); + RetBlockPHI->reserveOperandSpace(std::distance(PB, PE)); - for (pred_iterator PI = pred_begin(RetBlock), E = pred_end(RetBlock); - PI != E; ++PI) + for (pred_iterator PI = PB; PI != PE; ++PI) RetBlockPHI->addIncoming(InVal, *PI); RetBlock->getTerminator()->setOperand(0, RetBlockPHI); } Modified: llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp Wed Mar 30 06:19:20 2011 @@ -498,6 +498,7 @@ I != E; ++I) { PHINode *PN = PHINode::Create(I->getType(), I->getName() + ".tr", InsertPos); + PN->reserveOperandSpace(2); I->replaceAllUsesWith(PN); // Everyone use the PHI node now! PN->addIncoming(I, NewEntry); ArgumentPHIs.push_back(PN); @@ -527,9 +528,11 @@ if (AccumulatorRecursionEliminationInitVal) { Instruction *AccRecInstr = AccumulatorRecursionInstr; // Start by inserting a new PHI node for the accumulator. + pred_iterator PB = pred_begin(OldEntry), PE = pred_end(OldEntry); PHINode *AccPN = PHINode::Create(AccumulatorRecursionEliminationInitVal->getType(), "accumulator.tr", OldEntry->begin()); + AccPN->reserveOperandSpace(std::distance(PB, PE) + 1); // Loop over all of the predecessors of the tail recursion block. For the // real entry into the function we seed the PHI with the initial value, @@ -537,8 +540,7 @@ // other tail recursions eliminated) the accumulator is not modified. // Because we haven't added the branch in the current block to OldEntry yet, // it will not show up as a predecessor. - for (pred_iterator PI = pred_begin(OldEntry), PE = pred_end(OldEntry); - PI != PE; ++PI) { + for (pred_iterator PI = PB; PI != PE; ++PI) { BasicBlock *P = *PI; if (P == &F->getEntryBlock()) AccPN->addIncoming(AccumulatorRecursionEliminationInitVal, P); Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Wed Mar 30 06:19:20 2011 @@ -448,6 +448,7 @@ // Create the new PHI node, insert it into NewBB at the end of the block PHINode *NewPHI = PHINode::Create(PN->getType(), PN->getName()+".ph", BI); + NewPHI->reserveOperandSpace(NumPreds); if (AA) AA->copyValue(PN, NewPHI); // Move all of the PHI values for 'Preds' to the new PHI. Modified: llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp Wed Mar 30 06:19:20 2011 @@ -142,6 +142,7 @@ // Otherwise a new PHI is needed. Create one and populate it. PHINode *NewPN = PHINode::Create(PN->getType(), "split", SplitBB->getTerminator()); + NewPN->reserveOperandSpace(Preds.size()); for (unsigned i = 0, e = Preds.size(); i != e; ++i) NewPN->addIncoming(V, Preds[i]); // Update the original PHI. Modified: llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp Wed Mar 30 06:19:20 2011 @@ -104,7 +104,7 @@ /// region, we need to split the entry block of the region so that the PHI node /// is easier to deal with. void CodeExtractor::severSplitPHINodes(BasicBlock *&Header) { - bool HasPredsFromRegion = false; + unsigned NumPredsFromRegion = 0; unsigned NumPredsOutsideRegion = 0; if (Header != &Header->getParent()->getEntryBlock()) { @@ -116,7 +116,7 @@ // header block into two. for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) if (BlocksToExtract.count(PN->getIncomingBlock(i))) - HasPredsFromRegion = true; + ++NumPredsFromRegion; else ++NumPredsOutsideRegion; @@ -147,7 +147,7 @@ // Okay, now we need to adjust the PHI nodes and any branches from within the // region to go to the new header block instead of the old header block. - if (HasPredsFromRegion) { + if (NumPredsFromRegion) { PHINode *PN = cast(OldPred->begin()); // Loop over all of the predecessors of OldPred that are in the region, // changing them to branch to NewBB instead. @@ -165,6 +165,7 @@ // from OldPred of PN. PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".ce", NewBB->begin()); + NewPN->reserveOperandSpace(1+NumPredsFromRegion); NewPN->addIncoming(PN, OldPred); // Loop over all of the incoming value in PN, moving them to NewPN if they Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Wed Mar 30 06:19:20 2011 @@ -626,6 +626,7 @@ if (!TheCall->use_empty()) { PHI = PHINode::Create(RTy, TheCall->getName(), AfterCallBB->begin()); + PHI->reserveOperandSpace(Returns.size()); // Anything that used the result of the function call should now use the // PHI node as their operand. TheCall->replaceAllUsesWith(PHI); Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Wed Mar 30 06:19:20 2011 @@ -1598,13 +1598,15 @@ // in the constant and simplify the block result. Subsequent passes of // simplifycfg will thread the block. if (BlockIsSimpleEnoughToThreadThrough(BB)) { + pred_iterator PB = pred_begin(BB), PE = pred_end(BB); PHINode *NewPN = PHINode::Create(Type::getInt1Ty(BB->getContext()), BI->getCondition()->getName() + ".pr", BB->begin()); + NewPN->reserveOperandSpace(std::distance(PB, PE)); // Okay, we're going to insert the PHI node. Since PBI is not the only // predecessor, compute the PHI'd conditional value for all of the preds. // Any predecessor where the condition is not computable we keep symbolic. - for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { + for (pred_iterator PI = PB; PI != PE; ++PI) { BasicBlock *P = *PI; if ((PBI = dyn_cast(P->getTerminator())) && PBI != BI && PBI->isConditional() && Modified: llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp Wed Mar 30 06:19:20 2011 @@ -117,6 +117,7 @@ } else { // If the function doesn't return void... add a PHI node to the block... PN = PHINode::Create(F.getReturnType(), "UnifiedRetVal"); + PN->reserveOperandSpace(ReturningBlocks.size()); NewRetBlock->getInstList().push_back(PN); ReturnInst::Create(F.getContext(), PN, NewRetBlock); } Modified: llvm/trunk/tools/bugpoint/Miscompilation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/Miscompilation.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/Miscompilation.cpp (original) +++ llvm/trunk/tools/bugpoint/Miscompilation.cpp Wed Mar 30 06:19:20 2011 @@ -887,6 +887,7 @@ PHINode *FuncPtr = PHINode::Create(NullPtr->getType(), "fp", DoCallBB); + FuncPtr->reserveOperandSpace(2); FuncPtr->addIncoming(CastedResolver, LookupBB); FuncPtr->addIncoming(CachedVal, EntryBB); Modified: llvm/trunk/unittests/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/Local.cpp?rev=128535&r1=128534&r2=128535&view=diff ============================================================================== --- llvm/trunk/unittests/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/unittests/Transforms/Utils/Local.cpp Wed Mar 30 06:19:20 2011 @@ -27,6 +27,7 @@ builder.SetInsertPoint(bb0); PHINode *phi = builder.CreatePHI(Type::getInt32Ty(C)); + phi->reserveOperandSpace(2); BranchInst *br0 = builder.CreateCondBr(builder.getTrue(), bb0, bb1); builder.SetInsertPoint(bb1); From jay.foad at gmail.com Wed Mar 30 06:28:46 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 30 Mar 2011 11:28:46 -0000 Subject: [llvm-commits] [llvm] r128537 - in /llvm/trunk: docs/tutorial/ examples/BrainF/ examples/Kaleidoscope/Chapter5/ examples/Kaleidoscope/Chapter6/ examples/Kaleidoscope/Chapter7/ include/llvm/ include/llvm/Support/ lib/Analysis/ lib/AsmParser/ lib/Bitcode/Reader/ lib/CodeGen/ lib/Target/CppBackend/ lib/Transforms/IPO/ lib/Transforms/InstCombine/ lib/Transforms/Instrumentation/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ tools/bugpoint/ unittests/Transforms/Utils/ Message-ID: <20110330112847.390052A6C12C@llvm.org> Author: foad Date: Wed Mar 30 06:28:46 2011 New Revision: 128537 URL: http://llvm.org/viewvc/llvm-project?rev=128537&view=rev Log: Remove PHINode::reserveOperandSpace(). Instead, add a parameter to PHINode::Create() giving the (known or expected) number of operands. Modified: llvm/trunk/docs/tutorial/LangImpl5.html llvm/trunk/docs/tutorial/LangImpl6.html llvm/trunk/docs/tutorial/LangImpl7.html llvm/trunk/examples/BrainF/BrainF.cpp llvm/trunk/examples/Kaleidoscope/Chapter5/toy.cpp llvm/trunk/examples/Kaleidoscope/Chapter6/toy.cpp llvm/trunk/examples/Kaleidoscope/Chapter7/toy.cpp llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/Support/IRBuilder.h llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp llvm/trunk/lib/Transforms/Utils/LCSSA.cpp llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp llvm/trunk/lib/Transforms/Utils/SSAUpdater.cpp llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp llvm/trunk/lib/VMCore/Core.cpp llvm/trunk/tools/bugpoint/Miscompilation.cpp llvm/trunk/unittests/Transforms/Utils/Local.cpp Modified: llvm/trunk/docs/tutorial/LangImpl5.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl5.html?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl5.html (original) +++ llvm/trunk/docs/tutorial/LangImpl5.html Wed Mar 30 06:28:46 2011 @@ -472,7 +472,7 @@ // Emit merge block. TheFunction->getBasicBlockList().push_back(MergeBB); Builder.SetInsertPoint(MergeBB); - PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), + PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); PN->addIncoming(ThenV, ThenBB); @@ -746,7 +746,7 @@ Builder.SetInsertPoint(LoopBB); // Start the PHI node with an entry for Start. - PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), VarName.c_str()); + PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str()); Variable->addIncoming(StartVal, PreheaderBB); @@ -1452,7 +1452,7 @@ // Emit merge block. TheFunction->getBasicBlockList().push_back(MergeBB); Builder.SetInsertPoint(MergeBB); - PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), + PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); PN->addIncoming(ThenV, ThenBB); @@ -1494,7 +1494,7 @@ Builder.SetInsertPoint(LoopBB); // Start the PHI node with an entry for Start. - PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), VarName.c_str()); + PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str()); Variable->addIncoming(StartVal, PreheaderBB); // Within the loop, the variable is defined equal to the PHI node. If it Modified: llvm/trunk/docs/tutorial/LangImpl6.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl6.html?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl6.html (original) +++ llvm/trunk/docs/tutorial/LangImpl6.html Wed Mar 30 06:28:46 2011 @@ -1475,7 +1475,7 @@ // Emit merge block. TheFunction->getBasicBlockList().push_back(MergeBB); Builder.SetInsertPoint(MergeBB); - PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), + PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); PN->addIncoming(ThenV, ThenBB); @@ -1517,7 +1517,7 @@ Builder.SetInsertPoint(LoopBB); // Start the PHI node with an entry for Start. - PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), VarName.c_str()); + PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str()); Variable->addIncoming(StartVal, PreheaderBB); // Within the loop, the variable is defined equal to the PHI node. If it Modified: llvm/trunk/docs/tutorial/LangImpl7.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl7.html?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl7.html (original) +++ llvm/trunk/docs/tutorial/LangImpl7.html Wed Mar 30 06:28:46 2011 @@ -1755,7 +1755,7 @@ // Emit merge block. TheFunction->getBasicBlockList().push_back(MergeBB); Builder.SetInsertPoint(MergeBB); - PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), + PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); PN->addIncoming(ThenV, ThenBB); Modified: llvm/trunk/examples/BrainF/BrainF.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/BrainF/BrainF.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/examples/BrainF/BrainF.cpp (original) +++ llvm/trunk/examples/BrainF/BrainF.cpp Wed Mar 30 06:28:46 2011 @@ -294,8 +294,7 @@ // Make part of PHI instruction now, wait until end of loop to finish PHINode *phi_0 = PHINode::Create(PointerType::getUnqual(IntegerType::getInt8Ty(C)), - headreg, testbb); - phi_0->reserveOperandSpace(2); + 2, headreg, testbb); phi_0->addIncoming(curhead, bb_0); curhead = phi_0; @@ -449,8 +448,8 @@ //%head.%d = phi i8 *[%head.%d, %main.%d] PHINode *phi_1 = builder-> - CreatePHI(PointerType::getUnqual(IntegerType::getInt8Ty(C)), headreg); - phi_1->reserveOperandSpace(1); + CreatePHI(PointerType::getUnqual(IntegerType::getInt8Ty(C)), 1, + headreg); phi_1->addIncoming(head_0, testbb); curhead = phi_1; } Modified: llvm/trunk/examples/Kaleidoscope/Chapter5/toy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/Chapter5/toy.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/examples/Kaleidoscope/Chapter5/toy.cpp (original) +++ llvm/trunk/examples/Kaleidoscope/Chapter5/toy.cpp Wed Mar 30 06:28:46 2011 @@ -550,9 +550,8 @@ // Emit merge block. TheFunction->getBasicBlockList().push_back(MergeBB); Builder.SetInsertPoint(MergeBB); - PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), + PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); - PN->reserveOperandSpace(2); PN->addIncoming(ThenV, ThenBB); PN->addIncoming(ElseV, ElseBB); @@ -593,8 +592,7 @@ Builder.SetInsertPoint(LoopBB); // Start the PHI node with an entry for Start. - PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), VarName.c_str()); - Variable->reserveOperandSpace(2); + PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str()); Variable->addIncoming(StartVal, PreheaderBB); // Within the loop, the variable is defined equal to the PHI node. If it Modified: llvm/trunk/examples/Kaleidoscope/Chapter6/toy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/Chapter6/toy.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/examples/Kaleidoscope/Chapter6/toy.cpp (original) +++ llvm/trunk/examples/Kaleidoscope/Chapter6/toy.cpp Wed Mar 30 06:28:46 2011 @@ -654,9 +654,8 @@ // Emit merge block. TheFunction->getBasicBlockList().push_back(MergeBB); Builder.SetInsertPoint(MergeBB); - PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), + PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); - PN->reserveOperandSpace(2); PN->addIncoming(ThenV, ThenBB); PN->addIncoming(ElseV, ElseBB); @@ -697,8 +696,7 @@ Builder.SetInsertPoint(LoopBB); // Start the PHI node with an entry for Start. - PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), VarName.c_str()); - Variable->reserveOperandSpace(2); + PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str()); Variable->addIncoming(StartVal, PreheaderBB); // Within the loop, the variable is defined equal to the PHI node. If it Modified: llvm/trunk/examples/Kaleidoscope/Chapter7/toy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/Chapter7/toy.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/examples/Kaleidoscope/Chapter7/toy.cpp (original) +++ llvm/trunk/examples/Kaleidoscope/Chapter7/toy.cpp Wed Mar 30 06:28:46 2011 @@ -750,9 +750,8 @@ // Emit merge block. TheFunction->getBasicBlockList().push_back(MergeBB); Builder.SetInsertPoint(MergeBB); - PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), + PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); - PN->reserveOperandSpace(2); PN->addIncoming(ThenV, ThenBB); PN->addIncoming(ElseV, ElseBB); Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Wed Mar 30 06:28:46 2011 @@ -1811,39 +1811,35 @@ void *operator new(size_t s) { return User::operator new(s, 0); } - explicit PHINode(const Type *Ty, const Twine &NameStr = "", - Instruction *InsertBefore = 0) + explicit PHINode(const Type *Ty, unsigned NumReservedValues, + const Twine &NameStr = "", Instruction *InsertBefore = 0) : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), - ReservedSpace(0) { + ReservedSpace(NumReservedValues * 2) { setName(NameStr); + OperandList = allocHungoffUses(ReservedSpace); } - PHINode(const Type *Ty, const Twine &NameStr, BasicBlock *InsertAtEnd) + PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr, + BasicBlock *InsertAtEnd) : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), - ReservedSpace(0) { + ReservedSpace(NumReservedValues * 2) { setName(NameStr); + OperandList = allocHungoffUses(ReservedSpace); } protected: virtual PHINode *clone_impl() const; public: - static PHINode *Create(const Type *Ty, const Twine &NameStr = "", + static PHINode *Create(const Type *Ty, unsigned NumReservedValues, + const Twine &NameStr = "", Instruction *InsertBefore = 0) { - return new PHINode(Ty, NameStr, InsertBefore); + return new PHINode(Ty, NumReservedValues, NameStr, InsertBefore); } - static PHINode *Create(const Type *Ty, const Twine &NameStr, - BasicBlock *InsertAtEnd) { - return new PHINode(Ty, NameStr, InsertAtEnd); + static PHINode *Create(const Type *Ty, unsigned NumReservedValues, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd); } ~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, - /// this method can also be used to trim the operand space. - void reserveOperandSpace(unsigned NumValues) { - resizeOperands(NumValues*2); - } - /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); Modified: llvm/trunk/include/llvm/Support/IRBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IRBuilder.h?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/IRBuilder.h (original) +++ llvm/trunk/include/llvm/Support/IRBuilder.h Wed Mar 30 06:28:46 2011 @@ -1070,8 +1070,9 @@ // Instruction creation methods: Other Instructions //===--------------------------------------------------------------------===// - PHINode *CreatePHI(const Type *Ty, const Twine &Name = "") { - return Insert(PHINode::Create(Ty), Name); + PHINode *CreatePHI(const Type *Ty, unsigned NumReservedValues, + const Twine &Name = "") { + return Insert(PHINode::Create(Ty, NumReservedValues), Name); } CallInst *CreateCall(Value *Callee, const Twine &Name = "") { Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Wed Mar 30 06:28:46 2011 @@ -935,8 +935,7 @@ BasicBlock *Header = L->getHeader(); Builder.SetInsertPoint(Header, Header->begin()); pred_iterator HPB = pred_begin(Header), HPE = pred_end(Header); - PHINode *PN = Builder.CreatePHI(ExpandTy, "lsr.iv"); - PN->reserveOperandSpace(std::distance(HPB, HPE)); + PHINode *PN = Builder.CreatePHI(ExpandTy, std::distance(HPB, HPE), "lsr.iv"); rememberInstruction(PN); // Create the step instructions and populate the PHI. @@ -1143,8 +1142,8 @@ // specified loop. BasicBlock *Header = L->getHeader(); pred_iterator HPB = pred_begin(Header), HPE = pred_end(Header); - CanonicalIV = PHINode::Create(Ty, "indvar", Header->begin()); - CanonicalIV->reserveOperandSpace(std::distance(HPB, HPE)); + CanonicalIV = PHINode::Create(Ty, std::distance(HPB, HPE), "indvar", + Header->begin()); rememberInstruction(CanonicalIV); Constant *One = ConstantInt::get(Ty, 1); Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Wed Mar 30 06:28:46 2011 @@ -3634,8 +3634,7 @@ if (!Ty->isFirstClassType()) return Error(TypeLoc, "phi node must have first class type"); - PHINode *PN = PHINode::Create(Ty); - PN->reserveOperandSpace(PHIVals.size()); + PHINode *PN = PHINode::Create(Ty, PHIVals.size()); for (unsigned i = 0, e = PHIVals.size(); i != e; ++i) PN->addIncoming(PHIVals[i].first, PHIVals[i].second); Inst = PN; Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Wed Mar 30 06:28:46 2011 @@ -2288,9 +2288,8 @@ const Type *Ty = getTypeByID(Record[0]); if (!Ty) return Error("Invalid PHI record"); - PHINode *PN = PHINode::Create(Ty); + PHINode *PN = PHINode::Create(Ty, (Record.size()-1)/2); InstructionList.push_back(PN); - PN->reserveOperandSpace((Record.size()-1)/2); for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) { Value *V = getFnValueByID(Record[1+i], Ty); Modified: llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp (original) +++ llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp Wed Mar 30 06:28:46 2011 @@ -439,9 +439,9 @@ if (InVal == 0) { // Different unwind edges have different values. Create a new PHI node // in NewBB. - PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".unwind", - NewBB); - NewPN->reserveOperandSpace(PN->getNumIncomingValues()); + PHINode *NewPN = PHINode::Create(PN->getType(), + PN->getNumIncomingValues(), + PN->getName()+".unwind", NewBB); // Add an entry for each unwind edge, using the value from the old PHI. for (pred_iterator PI = PB; PI != PE; ++PI) NewPN->addIncoming(PN->getIncomingValueForBlock(*PI), *PI); Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Wed Mar 30 06:28:46 2011 @@ -1348,12 +1348,10 @@ const PHINode* phi = cast(I); Out << "PHINode* " << iName << " = PHINode::Create(" - << getCppName(phi->getType()) << ", \""; + << getCppName(phi->getType()) << ", \"" + << phi->getNumIncomingValues() << ", \""; printEscapedString(phi->getName()); Out << "\", " << bbname << ");"; - nl(Out) << iName << "->reserveOperandSpace(" - << phi->getNumIncomingValues() - << ");"; nl(Out); for (unsigned i = 0; i < phi->getNumOperands(); i+=2) { Out << iName << "->addIncoming(" Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Wed Mar 30 06:28:46 2011 @@ -1195,8 +1195,8 @@ PHINode *NewPN = PHINode::Create(PointerType::getUnqual(ST->getElementType(FieldNo)), + PN->getNumIncomingValues(), PN->getName()+".f"+Twine(FieldNo), PN); - NewPN->reserveOperandSpace(PN->getNumIncomingValues()); Result = NewPN; PHIsToRewrite.push_back(std::make_pair(PN, FieldNo)); } else { Modified: llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/LowerSetJmp.cpp Wed Mar 30 06:28:46 2011 @@ -430,9 +430,8 @@ // This PHI node will be in the new block created from the // splitBasicBlock call. - PHINode* PHI = PHINode::Create(Type::getInt32Ty(Inst->getContext()), + PHINode* PHI = PHINode::Create(Type::getInt32Ty(Inst->getContext()), 2, "SetJmpReturn", Inst); - PHI->reserveOperandSpace(2); // Coming from a call to setjmp, the return is 0. PHI->addIncoming(Constant::getNullValue(Type::getInt32Ty(Inst->getContext())), Modified: llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp Wed Mar 30 06:28:46 2011 @@ -95,8 +95,7 @@ PHINode* OldPhi = dyn_cast(I); if (!OldPhi) break; - PHINode* retPhi = PHINode::Create(OldPhi->getType(), "", Ins); - retPhi->reserveOperandSpace(2); + PHINode* retPhi = PHINode::Create(OldPhi->getType(), 2, "", Ins); OldPhi->replaceAllUsesWith(retPhi); Ins = newReturnBlock->getFirstNonPHI(); Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Wed Mar 30 06:28:46 2011 @@ -196,8 +196,7 @@ } case Instruction::PHI: { PHINode *OPN = cast(I); - PHINode *NPN = PHINode::Create(Ty); - NPN->reserveOperandSpace(OPN->getNumIncomingValues()); + PHINode *NPN = PHINode::Create(Ty, OPN->getNumIncomingValues()); for (unsigned i = 0, e = OPN->getNumIncomingValues(); i != e; ++i) { Value *V =EvaluateInDifferentType(OPN->getIncomingValue(i), Ty, isSigned); NPN->addIncoming(V, OPN->getIncomingBlock(i)); Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp Wed Mar 30 06:28:46 2011 @@ -591,8 +591,7 @@ // Insert a PHI node now if we need it. Value *MergedVal = OtherStore->getOperand(0); if (MergedVal != SI.getOperand(0)) { - PHINode *PN = PHINode::Create(MergedVal->getType(), "storemerge"); - PN->reserveOperandSpace(2); + PHINode *PN = PHINode::Create(MergedVal->getType(), 2, "storemerge"); PN->addIncoming(SI.getOperand(0), SI.getParent()); PN->addIncoming(OtherStore->getOperand(0), OtherBB); MergedVal = InsertNewInstBefore(PN, DestBB->front()); Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp Wed Mar 30 06:28:46 2011 @@ -80,18 +80,16 @@ Value *InRHS = FirstInst->getOperand(1); PHINode *NewLHS = 0, *NewRHS = 0; if (LHSVal == 0) { - NewLHS = PHINode::Create(LHSType, + NewLHS = PHINode::Create(LHSType, PN.getNumIncomingValues(), FirstInst->getOperand(0)->getName() + ".pn"); - NewLHS->reserveOperandSpace(PN.getNumIncomingValues()); NewLHS->addIncoming(InLHS, PN.getIncomingBlock(0)); InsertNewInstBefore(NewLHS, PN); LHSVal = NewLHS; } if (RHSVal == 0) { - NewRHS = PHINode::Create(RHSType, + NewRHS = PHINode::Create(RHSType, PN.getNumIncomingValues(), FirstInst->getOperand(1)->getName() + ".pn"); - NewRHS->reserveOperandSpace(PN.getNumIncomingValues()); NewRHS->addIncoming(InRHS, PN.getIncomingBlock(0)); InsertNewInstBefore(NewRHS, PN); RHSVal = NewRHS; @@ -202,11 +200,10 @@ for (unsigned i = 0, e = FixedOperands.size(); i != e; ++i) { if (FixedOperands[i]) continue; // operand doesn't need a phi. Value *FirstOp = FirstInst->getOperand(i); - PHINode *NewPN = PHINode::Create(FirstOp->getType(), + PHINode *NewPN = PHINode::Create(FirstOp->getType(), e, FirstOp->getName()+".pn"); InsertNewInstBefore(NewPN, PN); - NewPN->reserveOperandSpace(e); NewPN->addIncoming(FirstOp, PN.getIncomingBlock(0)); OperandPhis[i] = NewPN; FixedOperands[i] = NewPN; @@ -340,8 +337,8 @@ // Okay, they are all the same operation. Create a new PHI node of the // correct type, and PHI together all of the LHS's of the instructions. PHINode *NewPN = PHINode::Create(FirstLI->getOperand(0)->getType(), + PN.getNumIncomingValues(), PN.getName()+".in"); - NewPN->reserveOperandSpace(PN.getNumIncomingValues()); Value *InVal = FirstLI->getOperand(0); NewPN->addIncoming(InVal, PN.getIncomingBlock(0)); @@ -446,8 +443,8 @@ // Okay, they are all the same operation. Create a new PHI node of the // correct type, and PHI together all of the LHS's of the instructions. PHINode *NewPN = PHINode::Create(FirstInst->getOperand(0)->getType(), + PN.getNumIncomingValues(), PN.getName()+".in"); - NewPN->reserveOperandSpace(PN.getNumIncomingValues()); Value *InVal = FirstInst->getOperand(0); NewPN->addIncoming(InVal, PN.getIncomingBlock(0)); @@ -699,8 +696,8 @@ if ((EltPHI = ExtractedVals[LoweredPHIRecord(PN, Offset, Ty)]) == 0) { // Otherwise, Create the new PHI node for this user. - EltPHI = PHINode::Create(Ty, PN->getName()+".off"+Twine(Offset), PN); - EltPHI->reserveOperandSpace(PN->getNumIncomingValues()); + EltPHI = PHINode::Create(Ty, PN->getNumIncomingValues(), + PN->getName()+".off"+Twine(Offset), PN); assert(EltPHI->getType() != PN->getType() && "Truncate didn't shrink phi?"); Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Wed Mar 30 06:28:46 2011 @@ -600,8 +600,7 @@ } // Okay, we can do the transformation: create the new PHI node. - PHINode *NewPN = PHINode::Create(I.getType(), ""); - NewPN->reserveOperandSpace(PN->getNumIncomingValues()); + PHINode *NewPN = PHINode::Create(I.getType(), PN->getNumIncomingValues(), ""); InsertNewInstBefore(NewPN, *PN); NewPN->takeName(PN); Modified: llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp (original) +++ llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp Wed Mar 30 06:28:46 2011 @@ -931,9 +931,9 @@ BasicBlock::iterator insertPoint = block->getFirstNonPHI(); pred_iterator PB = pred_begin(node->getBlock()), PE = pred_end(node->getBlock()); - PHINode* phi = PHINode::Create(Type::getInt32Ty(*Context), "pathNumber", + PHINode* phi = PHINode::Create(Type::getInt32Ty(*Context), + std::distance(PB, PE), "pathNumber", insertPoint ); - phi->reserveOperandSpace(std::distance(PB, PE)); node->setPathPHI(phi); node->setStartingPathNumber(phi); node->setEndingPathNumber(phi); Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Mar 30 06:28:46 2011 @@ -1945,10 +1945,9 @@ // Create a PHI to make the value available in this block. pred_iterator PB = pred_begin(CurrentBlock), PE = pred_end(CurrentBlock); - PHINode* Phi = PHINode::Create(CurInst->getType(), + PHINode* Phi = PHINode::Create(CurInst->getType(), std::distance(PB, PE), CurInst->getName() + ".pre-phi", CurrentBlock->begin()); - Phi->reserveOperandSpace(std::distance(PB, PE)); for (pred_iterator PI = PB; PI != PE; ++PI) { BasicBlock *P = *PI; Phi->addIncoming(predMap[P], P); Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Wed Mar 30 06:28:46 2011 @@ -1038,8 +1038,7 @@ const IntegerType *Int32Ty = Type::getInt32Ty(PN->getContext()); // Insert new integer induction variable. - PHINode *NewPHI = PHINode::Create(Int32Ty, PN->getName()+".int", PN); - NewPHI->reserveOperandSpace(2); + PHINode *NewPHI = PHINode::Create(Int32Ty, 2, PN->getName()+".int", PN); NewPHI->addIncoming(ConstantInt::get(Int32Ty, InitValue), PN->getIncomingBlock(IncomingEdge)); Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Wed Mar 30 06:28:46 2011 @@ -929,8 +929,8 @@ // Create a PHI node at the start of the block for the PRE'd load value. pred_iterator PB = pred_begin(LoadBB), PE = pred_end(LoadBB); - PHINode *PN = PHINode::Create(LI->getType(), "", LoadBB->begin()); - PN->reserveOperandSpace(std::distance(PB, PE)); + PHINode *PN = PHINode::Create(LI->getType(), std::distance(PB, PE), "", + LoadBB->begin()); PN->takeName(LI); // Insert new entries into the PHI for each predecessor. A single block may Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Wed Mar 30 06:28:46 2011 @@ -1491,8 +1491,7 @@ if (!C->getValue().isStrictlyPositive()) continue; /* Add new PHINode. */ - PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH); - NewPH->reserveOperandSpace(2); + PHINode *NewPH = PHINode::Create(DestTy, 2, "IV.S.", PH); /* create new increment. '++d' in above example. */ Constant *CFP = ConstantFP::get(DestTy, C->getZExtValue()); Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Wed Mar 30 06:28:46 2011 @@ -1227,8 +1227,8 @@ } const Type *LoadTy = cast(PN->getType())->getElementType(); - PHINode *NewPN = PHINode::Create(LoadTy, PN->getName()+".ld", PN); - NewPN->reserveOperandSpace(PN->getNumIncomingValues()); + PHINode *NewPN = PHINode::Create(LoadTy, PN->getNumIncomingValues(), + PN->getName()+".ld", PN); // Get the TBAA tag and alignment to use from one of the loads. It doesn't // matter which one we get and if any differ, it doesn't matter. Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp Wed Mar 30 06:28:46 2011 @@ -260,9 +260,9 @@ if (RetBlockPHI == 0) { Value *InVal = cast(RetBlock->getTerminator())->getOperand(0); pred_iterator PB = pred_begin(RetBlock), PE = pred_end(RetBlock); - RetBlockPHI = PHINode::Create(Ret->getOperand(0)->getType(), "merge", + RetBlockPHI = PHINode::Create(Ret->getOperand(0)->getType(), + std::distance(PB, PE), "merge", &RetBlock->front()); - RetBlockPHI->reserveOperandSpace(std::distance(PB, PE)); for (pred_iterator PI = PB; PI != PE; ++PI) RetBlockPHI->addIncoming(InVal, *PI); Modified: llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp Wed Mar 30 06:28:46 2011 @@ -496,9 +496,8 @@ Instruction *InsertPos = OldEntry->begin(); for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) { - PHINode *PN = PHINode::Create(I->getType(), + PHINode *PN = PHINode::Create(I->getType(), 2, I->getName() + ".tr", InsertPos); - PN->reserveOperandSpace(2); I->replaceAllUsesWith(PN); // Everyone use the PHI node now! PN->addIncoming(I, NewEntry); ArgumentPHIs.push_back(PN); @@ -531,8 +530,8 @@ pred_iterator PB = pred_begin(OldEntry), PE = pred_end(OldEntry); PHINode *AccPN = PHINode::Create(AccumulatorRecursionEliminationInitVal->getType(), + std::distance(PB, PE) + 1, "accumulator.tr", OldEntry->begin()); - AccPN->reserveOperandSpace(std::distance(PB, PE) + 1); // Loop over all of the predecessors of the tail recursion block. For the // real entry into the function we seed the PHI with the initial value, Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Wed Mar 30 06:28:46 2011 @@ -447,8 +447,7 @@ // If the values coming into the block are not the same, we need a PHI. // Create the new PHI node, insert it into NewBB at the end of the block PHINode *NewPHI = - PHINode::Create(PN->getType(), PN->getName()+".ph", BI); - NewPHI->reserveOperandSpace(NumPreds); + PHINode::Create(PN->getType(), NumPreds, PN->getName()+".ph", BI); if (AA) AA->copyValue(PN, NewPHI); // Move all of the PHI values for 'Preds' to the new PHI. Modified: llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp Wed Mar 30 06:28:46 2011 @@ -140,9 +140,8 @@ if (VP->getParent() == SplitBB) continue; // Otherwise a new PHI is needed. Create one and populate it. - PHINode *NewPN = PHINode::Create(PN->getType(), "split", + PHINode *NewPN = PHINode::Create(PN->getType(), Preds.size(), "split", SplitBB->getTerminator()); - NewPN->reserveOperandSpace(Preds.size()); for (unsigned i = 0, e = Preds.size(); i != e; ++i) NewPN->addIncoming(V, Preds[i]); // Update the original PHI. Modified: llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp Wed Mar 30 06:28:46 2011 @@ -163,9 +163,8 @@ PHINode *PN = cast(AfterPHIs); // Create a new PHI node in the new region, which has an incoming value // from OldPred of PN. - PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".ce", - NewBB->begin()); - NewPN->reserveOperandSpace(1+NumPredsFromRegion); + PHINode *NewPN = PHINode::Create(PN->getType(), 1 + NumPredsFromRegion, + PN->getName()+".ce", NewBB->begin()); NewPN->addIncoming(PN, OldPred); // Loop over all of the incoming value in PN, moving them to NewPN if they Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Wed Mar 30 06:28:46 2011 @@ -624,9 +624,8 @@ // The PHI node should go at the front of the new basic block to merge all // possible incoming values. if (!TheCall->use_empty()) { - PHI = PHINode::Create(RTy, TheCall->getName(), + PHI = PHINode::Create(RTy, Returns.size(), TheCall->getName(), AfterCallBB->begin()); - PHI->reserveOperandSpace(Returns.size()); // Anything that used the result of the function call should now use the // PHI node as their operand. TheCall->replaceAllUsesWith(PHI); Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Wed Mar 30 06:28:46 2011 @@ -222,9 +222,10 @@ // If we already inserted something for this BB, don't reprocess it. if (SSAUpdate.HasValueForBlock(ExitBB)) continue; - PHINode *PN = PHINode::Create(Inst->getType(), Inst->getName()+".lcssa", + PHINode *PN = PHINode::Create(Inst->getType(), + PredCache.GetNumPreds(ExitBB), + Inst->getName()+".lcssa", ExitBB->begin()); - PN->reserveOperandSpace(PredCache.GetNumPreds(ExitBB)); // Add inputs from inside the loop for this PHI. for (BasicBlock **PI = PredCache.GetPreds(ExitBB); *PI; ++PI) { Modified: llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp Wed Mar 30 06:28:46 2011 @@ -648,9 +648,8 @@ // the backedge block which correspond to any PHI nodes in the header block. for (BasicBlock::iterator I = Header->begin(); isa(I); ++I) { PHINode *PN = cast(I); - PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".be", - BETerminator); - NewPN->reserveOperandSpace(BackedgeBlocks.size()); + PHINode *NewPN = PHINode::Create(PN->getType(), BackedgeBlocks.size(), + PN->getName()+".be", BETerminator); if (AA) AA->copyValue(PN, NewPN); // Loop over the PHI node, moving all entries except the one for the Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Wed Mar 30 06:28:46 2011 @@ -961,12 +961,11 @@ // Create a PhiNode using the dereferenced type... and add the phi-node to the // BasicBlock. - PN = PHINode::Create(Allocas[AllocaNo]->getAllocatedType(), + PN = PHINode::Create(Allocas[AllocaNo]->getAllocatedType(), getNumPreds(BB), Allocas[AllocaNo]->getName() + "." + Twine(Version++), BB->begin()); ++NumPHIInsert; PhiToAllocaMap[PN] = AllocaNo; - PN->reserveOperandSpace(getNumPreds(BB)); if (AST && PN->getType()->isPointerTy()) AST->copyValue(PointerAllocaValues[AllocaNo], PN); Modified: llvm/trunk/lib/Transforms/Utils/SSAUpdater.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SSAUpdater.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SSAUpdater.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SSAUpdater.cpp Wed Mar 30 06:28:46 2011 @@ -170,8 +170,8 @@ } // Ok, we have no way out, insert a new one now. - PHINode *InsertedPHI = PHINode::Create(ProtoType, ProtoName, &BB->front()); - InsertedPHI->reserveOperandSpace(PredValues.size()); + PHINode *InsertedPHI = PHINode::Create(ProtoType, PredValues.size(), + ProtoName, &BB->front()); // Fill in all the predecessors of the PHI. for (unsigned i = 0, e = PredValues.size(); i != e; ++i) @@ -289,9 +289,8 @@ /// Reserve space for the operands but do not fill them in yet. static Value *CreateEmptyPHI(BasicBlock *BB, unsigned NumPreds, SSAUpdater *Updater) { - PHINode *PHI = PHINode::Create(Updater->ProtoType, Updater->ProtoName, - &BB->front()); - PHI->reserveOperandSpace(NumPreds); + PHINode *PHI = PHINode::Create(Updater->ProtoType, NumPreds, + Updater->ProtoName, &BB->front()); return PHI; } Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Wed Mar 30 06:28:46 2011 @@ -1600,9 +1600,9 @@ if (BlockIsSimpleEnoughToThreadThrough(BB)) { pred_iterator PB = pred_begin(BB), PE = pred_end(BB); PHINode *NewPN = PHINode::Create(Type::getInt1Ty(BB->getContext()), + std::distance(PB, PE), BI->getCondition()->getName() + ".pr", BB->begin()); - NewPN->reserveOperandSpace(std::distance(PB, PE)); // Okay, we're going to insert the PHI node. Since PBI is not the only // predecessor, compute the PHI'd conditional value for all of the preds. // Any predecessor where the condition is not computable we keep symbolic. Modified: llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp Wed Mar 30 06:28:46 2011 @@ -116,8 +116,8 @@ ReturnInst::Create(F.getContext(), NULL, NewRetBlock); } else { // If the function doesn't return void... add a PHI node to the block... - PN = PHINode::Create(F.getReturnType(), "UnifiedRetVal"); - PN->reserveOperandSpace(ReturningBlocks.size()); + PN = PHINode::Create(F.getReturnType(), ReturningBlocks.size(), + "UnifiedRetVal"); NewRetBlock->getInstList().push_back(PN); ReturnInst::Create(F.getContext(), PN, NewRetBlock); } Modified: llvm/trunk/lib/VMCore/Core.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Core.cpp (original) +++ llvm/trunk/lib/VMCore/Core.cpp Wed Mar 30 06:28:46 2011 @@ -2082,7 +2082,7 @@ /*--.. Miscellaneous instructions ..........................................--*/ LLVMValueRef LLVMBuildPhi(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) { - return wrap(unwrap(B)->CreatePHI(unwrap(Ty), Name)); + return wrap(unwrap(B)->CreatePHI(unwrap(Ty), 0, Name)); } LLVMValueRef LLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, Modified: llvm/trunk/tools/bugpoint/Miscompilation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/Miscompilation.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/Miscompilation.cpp (original) +++ llvm/trunk/tools/bugpoint/Miscompilation.cpp Wed Mar 30 06:28:46 2011 @@ -885,9 +885,8 @@ new StoreInst(CastedResolver, Cache, LookupBB); BranchInst::Create(DoCallBB, LookupBB); - PHINode *FuncPtr = PHINode::Create(NullPtr->getType(), + PHINode *FuncPtr = PHINode::Create(NullPtr->getType(), 2, "fp", DoCallBB); - FuncPtr->reserveOperandSpace(2); FuncPtr->addIncoming(CastedResolver, LookupBB); FuncPtr->addIncoming(CachedVal, EntryBB); Modified: llvm/trunk/unittests/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/Local.cpp?rev=128537&r1=128536&r2=128537&view=diff ============================================================================== --- llvm/trunk/unittests/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/unittests/Transforms/Utils/Local.cpp Wed Mar 30 06:28:46 2011 @@ -26,8 +26,7 @@ BasicBlock *bb1 = BasicBlock::Create(C); builder.SetInsertPoint(bb0); - PHINode *phi = builder.CreatePHI(Type::getInt32Ty(C)); - phi->reserveOperandSpace(2); + PHINode *phi = builder.CreatePHI(Type::getInt32Ty(C), 2); BranchInst *br0 = builder.CreateCondBr(builder.getTrue(), bb0, bb1); builder.SetInsertPoint(bb1); @@ -44,12 +43,12 @@ EXPECT_EQ(&bb1->front(), br1); builder.SetInsertPoint(bb0); - phi = builder.CreatePHI(Type::getInt32Ty(C)); + phi = builder.CreatePHI(Type::getInt32Ty(C), 0); EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi)); builder.SetInsertPoint(bb0); - phi = builder.CreatePHI(Type::getInt32Ty(C)); + phi = builder.CreatePHI(Type::getInt32Ty(C), 0); builder.CreateAdd(phi, phi); EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi)); From jay.foad at gmail.com Wed Mar 30 07:19:17 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 30 Mar 2011 13:19:17 +0100 Subject: [llvm-commits] [PATCH] remove PHINode::reserveOperandSpace() In-Reply-To: <4D92EB47.7010703@free.fr> References: <4D92EB47.7010703@free.fr> Message-ID: On 30 March 2011 09:35, Duncan Sands wrote: > Hi Jay, > >> Tested with "make check", LLVM and Clang. OK to apply? > > this will presumably break dragonegg since it calls reserveOperandSpace > (it converts GCC's SSA form directly into LLVM's, generating phi nodes). > So can you please let me know when you are about to commit and I will > update dragonegg (unless you prefer to do this yourself). Sorry, I committed this a short while ago. I'd appreciate if you'd update dragonegg because I don't even know where it lives -- I only grepped through the llvm, cfe and llvm-gcc-4.2 svn "modules". (Are there more places that I should regularly grep in future?) Thanks, Jay. From baldrick at free.fr Wed Mar 30 07:27:04 2011 From: baldrick at free.fr (Duncan Sands) Date: Wed, 30 Mar 2011 14:27:04 +0200 Subject: [llvm-commits] [llvm] r128537 - in /llvm/trunk: docs/tutorial/ examples/BrainF/ examples/Kaleidoscope/Chapter5/ examples/Kaleidoscope/Chapter6/ examples/Kaleidoscope/Chapter7/ include/llvm/ include/llvm/Support/ lib/Analysis/ lib/AsmParser/ lib/Bitcode/Reader/ lib/CodeGen/ lib/Target/CppBackend/ lib/Transforms/IPO/ lib/Transforms/InstCombine/ lib/Transforms/Instrumentation/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ tools/bugpoint/ unittests/Transforms/Utils/ In-Reply-To: <20110330112847.390052A6C12C@llvm.org> References: <20110330112847.390052A6C12C@llvm.org> Message-ID: <4D932198.4040901@free.fr> Hi Jay, this makes things more awkward for dragonegg. When it sees a GCC phi node it creates an LLVM phi node. But it doesn't know how many operands the phi node will have. It does know how many operands the GCC phi node has, but if a predecessor basic block has (eg) a switch statement at the end with more than one case branching to the phi block then the GCC phi gets one entry for the predecessor while the LLVM phi gets more than one. So dragonegg only has a lower bound for the number of phi operands. It can't just take a look in the LLVM predecessors since they probably haven't been output yet. So instead it creates a phi node with no operands, and once all basic blocks have been turned into LLVM it revisits each phi node, counts how many operands the phi node needs and populates the phi node. I guess one solution is to delete the empty phi node and create an entirely new one. But maybe you have a better idea? Ciao, Duncan. From jay.foad at gmail.com Wed Mar 30 07:27:33 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 30 Mar 2011 13:27:33 +0100 Subject: [llvm-commits] [PATCH] simplify various Instructions' resizeOperands() methods Message-ID: Various Instructions have resizeOperands() methods. Since this patch: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20110328/118717.html ... they are all only called with an argument of 0. Simplify them accordingly. (Maybe resizeOperands() should be renamed now that it always just grows the list of operands by some constant factor, but I couldn't think of a good new name.) Tested with "make check", LLVM and Clang. OK to apply? Thanks, Jay. -------------- next part -------------- A non-text attachment was scrubbed... Name: simplify-resizeoperands.diff Type: text/x-patch Size: 5811 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110330/cc90207d/attachment.bin From baldrick at free.fr Wed Mar 30 07:28:03 2011 From: baldrick at free.fr (Duncan Sands) Date: Wed, 30 Mar 2011 14:28:03 +0200 Subject: [llvm-commits] [PATCH] remove PHINode::reserveOperandSpace() In-Reply-To: References: <4D92EB47.7010703@free.fr> Message-ID: <4D9321D3.1040804@free.fr> Hi Jay, >>> Tested with "make check", LLVM and Clang. OK to apply? >> >> this will presumably break dragonegg since it calls reserveOperandSpace >> (it converts GCC's SSA form directly into LLVM's, generating phi nodes). >> So can you please let me know when you are about to commit and I will >> update dragonegg (unless you prefer to do this yourself). > > Sorry, I committed this a short while ago. I'd appreciate if you'd > update dragonegg because I don't even know where it lives -- I only > grepped through the llvm, cfe and llvm-gcc-4.2 svn "modules". (Are > there more places that I should regularly grep in future?) svn co http://llvm.org/svn/llvm-project/dragonegg/trunk Ciao, Duncan. From jay.foad at gmail.com Wed Mar 30 07:49:47 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 30 Mar 2011 13:49:47 +0100 Subject: [llvm-commits] [llvm] r128537 - in /llvm/trunk: docs/tutorial/ examples/BrainF/ examples/Kaleidoscope/Chapter5/ examples/Kaleidoscope/Chapter6/ examples/Kaleidoscope/Chapter7/ include/llvm/ include/llvm/Support/ lib/Analysis/ lib/AsmParser/ lib/B Message-ID: On 30 March 2011 13:27, Duncan Sands wrote: > Hi Jay, this makes things more awkward for dragonegg. ?When it sees a GCC > phi node it creates an LLVM phi node. ?But it doesn't know how many operands > the phi node will have. ?It does know how many operands the GCC phi node has, > but if a predecessor basic block has (eg) a switch statement at the end with > more than one case branching to the phi block then the GCC phi gets one entry > for the predecessor while the LLVM phi gets more than one. ?So dragonegg only > has a lower bound for the number of phi operands. ?It can't just take a look > in the LLVM predecessors since they probably haven't been output yet. ?So > instead it creates a phi node with no operands, and once all basic blocks have > been turned into LLVM it revisits each phi node, counts how many operands the > phi node needs and populates the phi node. > > I guess one solution is to delete the empty phi node and create an entirely > new one. ?But maybe you have a better idea? (Sorry Duncan, forgot to CC the list first time.) It shouldn't make things more awkward for anyone. If you really don't have any information about how many operands the phi node will have, you can create it with 0. This should be exactly equivalent to how PHINode::Create() method worked before my changes. The NumReservedValues parameter that I've added to PHINode::Create() is just a hint, just like the old reserveOperandSpace() method. It doesn't have to be exactly the right number. Jay. From baldrick at free.fr Wed Mar 30 08:02:14 2011 From: baldrick at free.fr (Duncan Sands) Date: Wed, 30 Mar 2011 13:02:14 -0000 Subject: [llvm-commits] [dragonegg] r128539 - /dragonegg/trunk/Convert.cpp Message-ID: <20110330130214.93A6A2A6C12C@llvm.org> Author: baldrick Date: Wed Mar 30 08:02:14 2011 New Revision: 128539 URL: http://llvm.org/viewvc/llvm-project?rev=128539&view=rev Log: Adjust for removal of PHINode::reserveOperandSpace and change to CreatePHI. Modified: dragonegg/trunk/Convert.cpp Modified: dragonegg/trunk/Convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Convert.cpp?rev=128539&r1=128538&r2=128539&view=diff ============================================================================== --- dragonegg/trunk/Convert.cpp (original) +++ dragonegg/trunk/Convert.cpp Wed Mar 30 08:02:14 2011 @@ -908,7 +908,6 @@ } // Add the operands to the phi node. - P.PHI->reserveOperandSpace(PhiArguments.size()); for (ValueVector::iterator I = PhiArguments.begin(), E = PhiArguments.end(); I != E; ++I) P.PHI->addIncoming(I->second, I->first); @@ -1102,7 +1101,7 @@ // Create the LLVM phi node. const Type *Ty = GetRegType(TREE_TYPE(gimple_phi_result(gcc_phi))); - PHINode *PHI = Builder.CreatePHI(Ty); + PHINode *PHI = Builder.CreatePHI(Ty, gimple_phi_num_args(gcc_phi)); // The phi defines the associated ssa name. tree name = gimple_phi_result(gcc_phi); @@ -1967,8 +1966,8 @@ if (InVal == 0) { // Different unwind edges have different values. Create a new PHI node // in LPad. - PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".lpad", - LPad); + PHINode *NewPN = PHINode::Create(PN->getType(), std::distance(PB, PE), + PN->getName()+".lpad", LPad); // Add an entry for each unwind edge, using the value from the old PHI. for (pred_iterator PI = PB; PI != PE; ++PI) NewPN->addIncoming(PN->getIncomingValueForBlock(*PI), *PI); From baldrick at free.fr Wed Mar 30 08:08:51 2011 From: baldrick at free.fr (Duncan Sands) Date: Wed, 30 Mar 2011 15:08:51 +0200 Subject: [llvm-commits] [llvm] r128537 - in /llvm/trunk: docs/tutorial/ examples/BrainF/ examples/Kaleidoscope/Chapter5/ examples/Kaleidoscope/Chapter6/ examples/Kaleidoscope/Chapter7/ include/llvm/ include/llvm/Support/ lib/Analysis/ lib/AsmParser/ lib/B In-Reply-To: References: Message-ID: <4D932B63.9070004@free.fr> Hi Jay, > It shouldn't make things more awkward for anyone. If you really don't > have any information about how many operands the phi node will have, > you can create it with 0. This should be exactly equivalent to how > PHINode::Create() method worked before my changes. > > The NumReservedValues parameter that I've added to PHINode::Create() > is just a hint, just like the old reserveOperandSpace() method. It > doesn't have to be exactly the right number. in that case there is no problem - I have adjusted dragonegg. By the way you forgot to document the NumReservedValues parameter you added to PHINode::Create. Ciao, Duncan. From jay.foad at gmail.com Wed Mar 30 08:13:34 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 30 Mar 2011 14:13:34 +0100 Subject: [llvm-commits] [llvm] r128537 - in /llvm/trunk: docs/tutorial/ examples/BrainF/ examples/Kaleidoscope/Chapter5/ examples/Kaleidoscope/Chapter6/ examples/Kaleidoscope/Chapter7/ include/llvm/ include/llvm/Support/ lib/Analysis/ lib/AsmParser/ lib/B In-Reply-To: <4D932B63.9070004@free.fr> References: <4D932B63.9070004@free.fr> Message-ID: > in that case there is no problem - I have adjusted dragonegg. Excellent. >?By the > way you forgot to document the NumReservedValues parameter you added > to PHINode::Create. True, but I was following the existing coding style of not documenting *any* of the parameters, or indeed anything at all about the method. I'll try to come up with a comment. Jay. From jay.foad at gmail.com Wed Mar 30 08:29:06 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 30 Mar 2011 13:29:06 -0000 Subject: [llvm-commits] [llvm] r128540 - /llvm/trunk/include/llvm/Instructions.h Message-ID: <20110330132906.320072A6C12C@llvm.org> Author: foad Date: Wed Mar 30 08:29:06 2011 New Revision: 128540 URL: http://llvm.org/viewvc/llvm-project?rev=128540&view=rev Log: Add a comment on PHINode::Create(). Modified: llvm/trunk/include/llvm/Instructions.h Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=128540&r1=128539&r2=128540&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Wed Mar 30 08:29:06 2011 @@ -1829,6 +1829,8 @@ protected: virtual PHINode *clone_impl() const; public: + /// Constructors - NumReservedValues is a hint for the number of incoming + /// edges that this phi node will have (use 0 if you really have no idea). static PHINode *Create(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr = "", Instruction *InsertBefore = 0) { From baldrick at free.fr Wed Mar 30 09:38:25 2011 From: baldrick at free.fr (Duncan Sands) Date: Wed, 30 Mar 2011 14:38:25 -0000 Subject: [llvm-commits] [dragonegg] r128541 - /dragonegg/trunk/Constants.cpp Message-ID: <20110330143825.EB6C92A6C12C@llvm.org> Author: baldrick Date: Wed Mar 30 09:38:25 2011 New Revision: 128541 URL: http://llvm.org/viewvc/llvm-project?rev=128541&view=rev Log: The Java front-end expects array constructor elements to be implicitly cast to the array element type. For example, it may supply i32 values for an array of i16. With this fix dragonegg can compile a Java "hello world" program. Modified: dragonegg/trunk/Constants.cpp Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=128541&r1=128540&r2=128541&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Wed Mar 30 09:38:25 2011 @@ -578,6 +578,10 @@ // If we have a lower bound for the range of the type, get it. tree init_type = TREE_TYPE(exp); + tree elt_type = TREE_TYPE(init_type); + const Type *EltTy = ConvertType(elt_type); + bool EltIsSigned = !TYPE_UNSIGNED(elt_type); + tree min_element = size_zero_node; std::vector ResultElts; @@ -606,6 +610,18 @@ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), ix, elt_index, elt_value) { // Find and decode the constructor's value. Constant *Val = ConvertInitializer(elt_value); + + // If needed, cast the value to the type of the array element. + if (TREE_TYPE(elt_value) != elt_type && !AGGREGATE_TYPE_P(elt_type) && + !AGGREGATE_TYPE_P(TREE_TYPE(elt_value))) { + const Type *ValTy = ConvertType(TREE_TYPE(elt_value)); + Val = InterpretAsType(Val, ValTy, 0); + bool ValIsSigned = !TYPE_UNSIGNED(TREE_TYPE(elt_value)); + Instruction::CastOps opcode = CastInst::getCastOpcode(Val, ValIsSigned, + EltTy, EltIsSigned); + Val = TheFolder->CreateCast(opcode, Val, EltTy); + } + SomeVal = Val; // Get the index position of the element within the array. Note that this From baldrick at free.fr Wed Mar 30 09:47:22 2011 From: baldrick at free.fr (Duncan Sands) Date: Wed, 30 Mar 2011 14:47:22 -0000 Subject: [llvm-commits] [dragonegg] r128542 - /dragonegg/trunk/www/index.html Message-ID: <20110330144722.0E55B2A6C12C@llvm.org> Author: baldrick Date: Wed Mar 30 09:47:21 2011 New Revision: 128542 URL: http://llvm.org/viewvc/llvm-project?rev=128542&view=rev Log: Tell the world that we can compile some Java! (About 85% of the jar files in the GCC libjava testsuite compile successfully). Modified: dragonegg/trunk/www/index.html Modified: dragonegg/trunk/www/index.html URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/www/index.html?rev=128542&r1=128541&r2=128542&view=diff ============================================================================== --- dragonegg/trunk/www/index.html (original) +++ dragonegg/trunk/www/index.html Wed Mar 30 09:47:21 2011 @@ -46,7 +46,7 @@

  • It can compile quite a lot of Ada, and the compiled code mostly seems to work
  • It can compile a small amount of Obj-C and Obj-C++
  • -
  • It fails to compile any Java
  • +
  • It can compile simple Java programs
  • Limited debug info
  • Requires patching gcc
  • Only supports x86-32 and x86-64
  • From jay.foad at gmail.com Wed Mar 30 10:31:03 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 30 Mar 2011 15:31:03 -0000 Subject: [llvm-commits] [llvm] r128543 - /llvm/trunk/include/llvm/ADT/DenseMap.h Message-ID: <20110330153103.0DD392A6C12C@llvm.org> Author: foad Date: Wed Mar 30 10:31:02 2011 New Revision: 128543 URL: http://llvm.org/viewvc/llvm-project?rev=128543&view=rev Log: Fix more zero length memset warnings. Modified: llvm/trunk/include/llvm/ADT/DenseMap.h Modified: llvm/trunk/include/llvm/ADT/DenseMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=128543&r1=128542&r2=128543&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/DenseMap.h (original) +++ llvm/trunk/include/llvm/ADT/DenseMap.h Wed Mar 30 10:31:02 2011 @@ -422,7 +422,8 @@ } #ifndef NDEBUG - memset(OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets); + if (OldNumBuckets) + memset(OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets); #endif // Free the old table. operator delete(OldBuckets); From benny.kra at googlemail.com Wed Mar 30 10:42:27 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 30 Mar 2011 15:42:27 -0000 Subject: [llvm-commits] [llvm] r128545 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp unittests/ADT/APFloatTest.cpp Message-ID: <20110330154227.9AA732A6C12C@llvm.org> Author: d0k Date: Wed Mar 30 10:42:27 2011 New Revision: 128545 URL: http://llvm.org/viewvc/llvm-project?rev=128545&view=rev Log: Add APFloat::getExactInverse. The idea is, that if an ieee 754 float is divided by a power of two, we can turn the division into a cheaper multiplication. This function sees if we can get an exact multiplicative inverse for a divisor and returns it if possible. This is the hard part of PR9587. I tested many inputs against llvm-gcc's frotend implementation of this optimization and didn't find any difference. However, floating point is the land of weird edge cases, so any review would be appreciated. Modified: llvm/trunk/include/llvm/ADT/APFloat.h llvm/trunk/lib/Support/APFloat.cpp llvm/trunk/unittests/ADT/APFloatTest.cpp Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=128545&r1=128544&r2=128545&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Wed Mar 30 10:42:27 2011 @@ -353,6 +353,10 @@ unsigned FormatPrecision = 0, unsigned FormatMaxPadding = 3) const; + /// getExactInverse - If this value has an exact multiplicative inverse, + /// store it in inv and return true. + bool getExactInverse(APFloat *inv) const; + private: /* Trivial queries. */ Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=128545&r1=128544&r2=128545&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Wed Mar 30 10:42:27 2011 @@ -3562,3 +3562,29 @@ for (; I != NDigits; ++I) Str.push_back(buffer[NDigits-I-1]); } + +bool APFloat::getExactInverse(APFloat *inv) const { + // We can only guarantee the existance of an exact inverse for IEEE floats. + if (semantics != &IEEEhalf && semantics != &IEEEsingle && + semantics != &IEEEdouble && semantics != &IEEEquad) + return false; + + // Special floats and denormals have no exact inverse. + if (category != fcNormal) + return false; + + // Check that the number is a power of two by making sure that only the + // integer bit is set in the significand. + if (significandLSB() != semantics->precision - 1) + return false; + + // Get the inverse. + APFloat reciprocal(*semantics, 1ULL); + if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK) + return false; + + if (inv) + *inv = reciprocal; + + return true; +} Modified: llvm/trunk/unittests/ADT/APFloatTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APFloatTest.cpp?rev=128545&r1=128544&r2=128545&view=diff ============================================================================== --- llvm/trunk/unittests/ADT/APFloatTest.cpp (original) +++ llvm/trunk/unittests/ADT/APFloatTest.cpp Wed Mar 30 10:42:27 2011 @@ -576,4 +576,27 @@ #endif #endif +TEST(APFloatTest, exactInverse) { + APFloat inv(0.0f); + + // Trivial operation. + EXPECT_TRUE(APFloat(2.0).getExactInverse(&inv)); + EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5))); + EXPECT_TRUE(APFloat(2.0f).getExactInverse(&inv)); + EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5f))); + + // FLT_MIN + EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv)); + EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f))); + + // Large float + EXPECT_TRUE(APFloat(1.7014118e38f).getExactInverse(&inv)); + EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(5.8774718e-39f))); + + // Zero + EXPECT_FALSE(APFloat(0.0).getExactInverse(0)); + // Denormalized float + EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(0)); +} + } From benny.kra at googlemail.com Wed Mar 30 10:42:35 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 30 Mar 2011 15:42:35 -0000 Subject: [llvm-commits] [llvm] r128546 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp test/Transforms/InstCombine/fdiv.ll Message-ID: <20110330154235.380B42A6C12C@llvm.org> Author: d0k Date: Wed Mar 30 10:42:35 2011 New Revision: 128546 URL: http://llvm.org/viewvc/llvm-project?rev=128546&view=rev Log: InstCombine: If the divisor of an fdiv has an exact inverse, turn it into an fmul. Fixes PR9587. Added: llvm/trunk/test/Transforms/InstCombine/fdiv.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=128546&r1=128545&r2=128546&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Wed Mar 30 10:42:35 2011 @@ -452,6 +452,18 @@ if (Value *V = SimplifyFDivInst(Op0, Op1, TD)) return ReplaceInstUsesWith(I, V); + if (ConstantFP *Op1C = dyn_cast(Op1)) { + const APFloat &Op1F = Op1C->getValueAPF(); + + // If the divisor has an exact multiplicative inverse we can turn the fdiv + // into a cheaper fmul. + APFloat Reciprocal(Op1F.getSemantics()); + if (Op1F.getExactInverse(&Reciprocal)) { + ConstantFP *RFP = ConstantFP::get(Builder->getContext(), Reciprocal); + return BinaryOperator::CreateFMul(Op0, RFP); + } + } + return 0; } Added: llvm/trunk/test/Transforms/InstCombine/fdiv.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fdiv.ll?rev=128546&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/fdiv.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/fdiv.ll Wed Mar 30 10:42:35 2011 @@ -0,0 +1,25 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +define float @test1(float %x) nounwind readnone ssp { + %div = fdiv float %x, 0x3810000000000000 + ret float %div + +; CHECK: @test1 +; CHECK-NEXT: fmul float %x, 0x47D0000000000000 +} + +define float @test2(float %x) nounwind readnone ssp { + %div = fdiv float %x, 0x47E0000000000000 + ret float %div + +; CHECK: @test2 +; CHECK-NEXT: fmul float %x, 0x3800000000000000 +} + +define float @test3(float %x) nounwind readnone ssp { + %div = fdiv float %x, 0x36A0000000000000 + ret float %div + +; CHECK: @test3 +; CHECK-NEXT: fdiv float %x, 0x36A0000000000000 +} From scanon at apple.com Wed Mar 30 11:11:54 2011 From: scanon at apple.com (Stephen Canon) Date: Wed, 30 Mar 2011 09:11:54 -0700 Subject: [llvm-commits] [llvm] r128545 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp unittests/ADT/APFloatTest.cpp In-Reply-To: <20110330154227.9AA732A6C12C@llvm.org> References: <20110330154227.9AA732A6C12C@llvm.org> Message-ID: What will this patch do on a platform where denormals are treated as zero? Specifically, I'm interested in a case like this: float a; float b = a / 0x1.0p127f; If this is converted into the reciprocal multiply by 0x0.8p-126f (a denormal value), on platforms where denormals are treated as zero (the default state on many ARM cores, cell BE, and GPUs), this will become a multiplication by zero, which is incorrect. The "safe" range of divisors that can be optimized into reciprocal multiplies with regard to this issue, for any IEEE-754 type, is +/-[minNormal, 1/minNormal]. - Steve On Mar 30, 2011, at 8:42 AM, Benjamin Kramer wrote: > Author: d0k > Date: Wed Mar 30 10:42:27 2011 > New Revision: 128545 > > URL: http://llvm.org/viewvc/llvm-project?rev=128545&view=rev > Log: > Add APFloat::getExactInverse. > > The idea is, that if an ieee 754 float is divided by a power of two, we can > turn the division into a cheaper multiplication. This function sees if we can > get an exact multiplicative inverse for a divisor and returns it if possible. > > This is the hard part of PR9587. > > I tested many inputs against llvm-gcc's frotend implementation of this > optimization and didn't find any difference. However, floating point is the > land of weird edge cases, so any review would be appreciated. > > Modified: > llvm/trunk/include/llvm/ADT/APFloat.h > llvm/trunk/lib/Support/APFloat.cpp > llvm/trunk/unittests/ADT/APFloatTest.cpp > > Modified: llvm/trunk/include/llvm/ADT/APFloat.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=128545&r1=128544&r2=128545&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/ADT/APFloat.h (original) > +++ llvm/trunk/include/llvm/ADT/APFloat.h Wed Mar 30 10:42:27 2011 > @@ -353,6 +353,10 @@ > unsigned FormatPrecision = 0, > unsigned FormatMaxPadding = 3) const; > > + /// getExactInverse - If this value has an exact multiplicative inverse, > + /// store it in inv and return true. > + bool getExactInverse(APFloat *inv) const; > + > private: > > /* Trivial queries. */ > > Modified: llvm/trunk/lib/Support/APFloat.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=128545&r1=128544&r2=128545&view=diff > ============================================================================== > --- llvm/trunk/lib/Support/APFloat.cpp (original) > +++ llvm/trunk/lib/Support/APFloat.cpp Wed Mar 30 10:42:27 2011 > @@ -3562,3 +3562,29 @@ > for (; I != NDigits; ++I) > Str.push_back(buffer[NDigits-I-1]); > } > + > +bool APFloat::getExactInverse(APFloat *inv) const { > + // We can only guarantee the existance of an exact inverse for IEEE floats. > + if (semantics != &IEEEhalf && semantics != &IEEEsingle && > + semantics != &IEEEdouble && semantics != &IEEEquad) > + return false; > + > + // Special floats and denormals have no exact inverse. > + if (category != fcNormal) > + return false; > + > + // Check that the number is a power of two by making sure that only the > + // integer bit is set in the significand. > + if (significandLSB() != semantics->precision - 1) > + return false; > + > + // Get the inverse. > + APFloat reciprocal(*semantics, 1ULL); > + if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK) > + return false; > + > + if (inv) > + *inv = reciprocal; > + > + return true; > +} > > Modified: llvm/trunk/unittests/ADT/APFloatTest.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APFloatTest.cpp?rev=128545&r1=128544&r2=128545&view=diff > ============================================================================== > --- llvm/trunk/unittests/ADT/APFloatTest.cpp (original) > +++ llvm/trunk/unittests/ADT/APFloatTest.cpp Wed Mar 30 10:42:27 2011 > @@ -576,4 +576,27 @@ > #endif > #endif > > +TEST(APFloatTest, exactInverse) { > + APFloat inv(0.0f); > + > + // Trivial operation. > + EXPECT_TRUE(APFloat(2.0).getExactInverse(&inv)); > + EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5))); > + EXPECT_TRUE(APFloat(2.0f).getExactInverse(&inv)); > + EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5f))); > + > + // FLT_MIN > + EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv)); > + EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f))); > + > + // Large float > + EXPECT_TRUE(APFloat(1.7014118e38f).getExactInverse(&inv)); > + EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(5.8774718e-39f))); > + > + // Zero > + EXPECT_FALSE(APFloat(0.0).getExactInverse(0)); > + // Denormalized float > + EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(0)); > +} > + > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From scanon at apple.com Wed Mar 30 11:14:17 2011 From: scanon at apple.com (Stephen Canon) Date: Wed, 30 Mar 2011 09:14:17 -0700 Subject: [llvm-commits] [llvm] r128545 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp unittests/ADT/APFloatTest.cpp In-Reply-To: References: <20110330154227.9AA732A6C12C@llvm.org> Message-ID: <85BB8261-0BA4-422E-97F0-6FB0D7F100D1@apple.com> Note also that even on many platforms where denormals are supported, multiplication by a denormal can be slower than division by a normal number. - Steve On Mar 30, 2011, at 9:11 AM, Stephen Canon wrote: > What will this patch do on a platform where denormals are treated as zero? > > Specifically, I'm interested in a case like this: > > float a; > float b = a / 0x1.0p127f; > > If this is converted into the reciprocal multiply by 0x0.8p-126f (a denormal value), on platforms where denormals are treated as zero (the default state on many ARM cores, cell BE, and GPUs), this will become a multiplication by zero, which is incorrect. > > The "safe" range of divisors that can be optimized into reciprocal multiplies with regard to this issue, for any IEEE-754 type, is +/-[minNormal, 1/minNormal]. > > - Steve > > On Mar 30, 2011, at 8:42 AM, Benjamin Kramer wrote: > >> Author: d0k >> Date: Wed Mar 30 10:42:27 2011 >> New Revision: 128545 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=128545&view=rev >> Log: >> Add APFloat::getExactInverse. >> >> The idea is, that if an ieee 754 float is divided by a power of two, we can >> turn the division into a cheaper multiplication. This function sees if we can >> get an exact multiplicative inverse for a divisor and returns it if possible. >> >> This is the hard part of PR9587. >> >> I tested many inputs against llvm-gcc's frotend implementation of this >> optimization and didn't find any difference. However, floating point is the >> land of weird edge cases, so any review would be appreciated. >> >> Modified: >> llvm/trunk/include/llvm/ADT/APFloat.h >> llvm/trunk/lib/Support/APFloat.cpp >> llvm/trunk/unittests/ADT/APFloatTest.cpp >> >> Modified: llvm/trunk/include/llvm/ADT/APFloat.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=128545&r1=128544&r2=128545&view=diff >> ============================================================================== >> --- llvm/trunk/include/llvm/ADT/APFloat.h (original) >> +++ llvm/trunk/include/llvm/ADT/APFloat.h Wed Mar 30 10:42:27 2011 >> @@ -353,6 +353,10 @@ >> unsigned FormatPrecision = 0, >> unsigned FormatMaxPadding = 3) const; >> >> + /// getExactInverse - If this value has an exact multiplicative inverse, >> + /// store it in inv and return true. >> + bool getExactInverse(APFloat *inv) const; >> + >> private: >> >> /* Trivial queries. */ >> >> Modified: llvm/trunk/lib/Support/APFloat.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=128545&r1=128544&r2=128545&view=diff >> ============================================================================== >> --- llvm/trunk/lib/Support/APFloat.cpp (original) >> +++ llvm/trunk/lib/Support/APFloat.cpp Wed Mar 30 10:42:27 2011 >> @@ -3562,3 +3562,29 @@ >> for (; I != NDigits; ++I) >> Str.push_back(buffer[NDigits-I-1]); >> } >> + >> +bool APFloat::getExactInverse(APFloat *inv) const { >> + // We can only guarantee the existance of an exact inverse for IEEE floats. >> + if (semantics != &IEEEhalf && semantics != &IEEEsingle && >> + semantics != &IEEEdouble && semantics != &IEEEquad) >> + return false; >> + >> + // Special floats and denormals have no exact inverse. >> + if (category != fcNormal) >> + return false; >> + >> + // Check that the number is a power of two by making sure that only the >> + // integer bit is set in the significand. >> + if (significandLSB() != semantics->precision - 1) >> + return false; >> + >> + // Get the inverse. >> + APFloat reciprocal(*semantics, 1ULL); >> + if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK) >> + return false; >> + >> + if (inv) >> + *inv = reciprocal; >> + >> + return true; >> +} >> >> Modified: llvm/trunk/unittests/ADT/APFloatTest.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APFloatTest.cpp?rev=128545&r1=128544&r2=128545&view=diff >> ============================================================================== >> --- llvm/trunk/unittests/ADT/APFloatTest.cpp (original) >> +++ llvm/trunk/unittests/ADT/APFloatTest.cpp Wed Mar 30 10:42:27 2011 >> @@ -576,4 +576,27 @@ >> #endif >> #endif >> >> +TEST(APFloatTest, exactInverse) { >> + APFloat inv(0.0f); >> + >> + // Trivial operation. >> + EXPECT_TRUE(APFloat(2.0).getExactInverse(&inv)); >> + EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5))); >> + EXPECT_TRUE(APFloat(2.0f).getExactInverse(&inv)); >> + EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5f))); >> + >> + // FLT_MIN >> + EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv)); >> + EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f))); >> + >> + // Large float >> + EXPECT_TRUE(APFloat(1.7014118e38f).getExactInverse(&inv)); >> + EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(5.8774718e-39f))); >> + >> + // Zero >> + EXPECT_FALSE(APFloat(0.0).getExactInverse(0)); >> + // Denormalized float >> + EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(0)); >> +} >> + >> } >> >> >> _______________________________________________ >> 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 benny.kra at googlemail.com Wed Mar 30 12:02:54 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 30 Mar 2011 17:02:54 -0000 Subject: [llvm-commits] [llvm] r128555 - in /llvm/trunk: lib/Support/APFloat.cpp test/Transforms/InstCombine/fdiv.ll unittests/ADT/APFloatTest.cpp Message-ID: <20110330170254.E7C2D2A6C12C@llvm.org> Author: d0k Date: Wed Mar 30 12:02:54 2011 New Revision: 128555 URL: http://llvm.org/viewvc/llvm-project?rev=128555&view=rev Log: Avoid turning a floating point division with a constant power of two into a denormal multiplication. Some platforms may treat denormals as zero, on other platforms multiplication with a subnormal is slower than dividing by a normal. Modified: llvm/trunk/lib/Support/APFloat.cpp llvm/trunk/test/Transforms/InstCombine/fdiv.ll llvm/trunk/unittests/ADT/APFloatTest.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=128555&r1=128554&r2=128555&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Wed Mar 30 12:02:54 2011 @@ -3583,6 +3583,14 @@ if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK) return false; + // Avoid multiplication with a denormal, it is not safe on all platforms and + // may be slower than a normal division. + if (reciprocal.significandMSB() + 1 < reciprocal.semantics->precision) + return false; + + assert(reciprocal.category == fcNormal && + reciprocal.significandLSB() == reciprocal.semantics->precision - 1); + if (inv) *inv = reciprocal; Modified: llvm/trunk/test/Transforms/InstCombine/fdiv.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fdiv.ll?rev=128555&r1=128554&r2=128555&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/fdiv.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/fdiv.ll Wed Mar 30 12:02:54 2011 @@ -13,7 +13,7 @@ ret float %div ; CHECK: @test2 -; CHECK-NEXT: fmul float %x, 0x3800000000000000 +; CHECK-NEXT: fdiv float %x, 0x47E0000000000000 } define float @test3(float %x) nounwind readnone ssp { Modified: llvm/trunk/unittests/ADT/APFloatTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APFloatTest.cpp?rev=128555&r1=128554&r2=128555&view=diff ============================================================================== --- llvm/trunk/unittests/ADT/APFloatTest.cpp (original) +++ llvm/trunk/unittests/ADT/APFloatTest.cpp Wed Mar 30 12:02:54 2011 @@ -589,10 +589,8 @@ EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv)); EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f))); - // Large float - EXPECT_TRUE(APFloat(1.7014118e38f).getExactInverse(&inv)); - EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(5.8774718e-39f))); - + // Large float, inverse is a denormal. + EXPECT_FALSE(APFloat(1.7014118e38f).getExactInverse(0)); // Zero EXPECT_FALSE(APFloat(0.0).getExactInverse(0)); // Denormalized float From benny.kra at googlemail.com Wed Mar 30 12:08:38 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 30 Mar 2011 19:08:38 +0200 Subject: [llvm-commits] [llvm] r128545 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp unittests/ADT/APFloatTest.cpp In-Reply-To: References: <20110330154227.9AA732A6C12C@llvm.org> Message-ID: <3852C42B-B3C4-47AC-B0E4-EAEA5377524F@googlemail.com> On 30.03.2011, at 18:11, Stephen Canon wrote: > What will this patch do on a platform where denormals are treated as zero? > > Specifically, I'm interested in a case like this: > > float a; > float b = a / 0x1.0p127f; > > If this is converted into the reciprocal multiply by 0x0.8p-126f (a denormal value), on platforms where denormals are treated as zero (the default state on many ARM cores, cell BE, and GPUs), this will become a multiplication by zero, which is incorrect. > > The "safe" range of divisors that can be optimized into reciprocal multiplies with regard to this issue, for any IEEE-754 type, is +/-[minNormal, 1/minNormal]. Hi Steve, Thanks for the quick review. I changed the code to avoid denormal multiplications in r128555. I wonder how (llvm-)gcc deals with this, on x86 it turns divisions into subnormal multiplications, is there some target specific setting that disables it on ARM and other "odd" platforms? From stoklund at 2pi.dk Wed Mar 30 13:14:04 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 30 Mar 2011 18:14:04 -0000 Subject: [llvm-commits] [llvm] r128561 - /llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Message-ID: <20110330181404.D7E0E2A6C12C@llvm.org> Author: stoklund Date: Wed Mar 30 13:14:04 2011 New Revision: 128561 URL: http://llvm.org/viewvc/llvm-project?rev=128561&view=rev Log: Teach VirtRegRewriter about the new virtual register numbers. No functional change. Modified: llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Modified: llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp?rev=128561&r1=128560&r2=128561&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Wed Mar 30 13:14:04 2011 @@ -1791,8 +1791,8 @@ else DEBUG(dbgs() << "Reusing SS#" << SSorRMId); DEBUG(dbgs() << " from physreg " - << TRI->getName(InReg) << " for vreg" - << VirtReg <<" instead of reloading into physreg " + << TRI->getName(InReg) << " for " << PrintReg(VirtReg) + <<" instead of reloading into physreg " << TRI->getName(Phys) << '\n'); // Reusing a physreg may resurrect it. But we expect ProcessUses to update @@ -1807,8 +1807,8 @@ else DEBUG(dbgs() << "Reusing SS#" << SSorRMId); DEBUG(dbgs() << " from physreg " - << TRI->getName(InReg) << " for vreg" - << VirtReg <<" by copying it into physreg " + << TRI->getName(InReg) << " for " << PrintReg(VirtReg) + <<" by copying it into physreg " << TRI->getName(Phys) << '\n'); // If the reloaded / remat value is available in another register, @@ -2025,7 +2025,8 @@ TRI->regsOverlap(MOk.getReg(), PhysReg)) { CanReuse = false; DEBUG(dbgs() << "Not reusing physreg " << TRI->getName(PhysReg) - << " for vreg" << VirtReg << ": " << MOk << '\n'); + << " for " << PrintReg(VirtReg) << ": " << MOk + << '\n'); break; } } @@ -2039,9 +2040,9 @@ else DEBUG(dbgs() << "Reusing SS#" << ReuseSlot); DEBUG(dbgs() << " from physreg " - << TRI->getName(PhysReg) << " for vreg" - << VirtReg <<" instead of reloading into physreg " - << TRI->getName(VRM->getPhys(VirtReg)) << '\n'); + << TRI->getName(PhysReg) << " for " << PrintReg(VirtReg) + << " instead of reloading into " + << PrintReg(VRM->getPhys(VirtReg), TRI) << '\n'); unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg; MI.getOperand(i).setReg(RReg); MI.getOperand(i).setSubReg(0); @@ -2126,7 +2127,7 @@ else DEBUG(dbgs() << "Reusing SS#" << ReuseSlot); DEBUG(dbgs() << " from physreg " << TRI->getName(PhysReg) - << " for vreg" << VirtReg + << " for " << PrintReg(VirtReg) << " instead of reloading into same physreg.\n"); unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg; MI.getOperand(i).setReg(RReg); @@ -2315,7 +2316,7 @@ for (unsigned FVI = 0, FVE = FoldedVirts.size(); FVI != FVE; ++FVI) { unsigned VirtReg = FoldedVirts[FVI].first; VirtRegMap::ModRef MR = FoldedVirts[FVI].second; - DEBUG(dbgs() << "Folded vreg: " << VirtReg << " MR: " << MR); + DEBUG(dbgs() << "Folded " << PrintReg(VirtReg) << " MR: " << MR); int SS = VRM->getStackSlot(VirtReg); if (SS == VirtRegMap::NO_STACK_SLOT) From stoklund at 2pi.dk Wed Mar 30 13:14:07 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 30 Mar 2011 18:14:07 -0000 Subject: [llvm-commits] [llvm] r128562 - /llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Message-ID: <20110330181407.383D22A6C12D@llvm.org> Author: stoklund Date: Wed Mar 30 13:14:07 2011 New Revision: 128562 URL: http://llvm.org/viewvc/llvm-project?rev=128562&view=rev Log: Fix evil VirtRegRewriter bug. The rewriter can keep track of multiple stack slots in the same register if they happen to have the same value. When an instruction modifies a stack slot by defining a register that is mapped to a stack slot, other stack slots in that register are no longer valid. This is a very rare problem, and I don't have a simple test case. I get the impression that VirtRegRewriter knows it is about to be deleted, inventing a last opaque problem. Modified: llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Modified: llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp?rev=128562&r1=128561&r2=128562&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Wed Mar 30 13:14:07 2011 @@ -261,6 +261,10 @@ /// now). void ModifyStackSlotOrReMat(int SlotOrReMat); + /// ClobberSharingStackSlots - When a register mapped to a stack slot changes, + /// other stack slots sharing the same register are no longer valid. + void ClobberSharingStackSlots(int StackSlot); + /// AddAvailableRegsToLiveIn - Availability information is being kept coming /// into the specified MBB. Add available physical registers as potential /// live-in's. If they are reused in the MBB, they will be added to the @@ -831,6 +835,26 @@ PhysRegsAvailable.erase(I); } +void AvailableSpills::ClobberSharingStackSlots(int StackSlot) { + std::map::iterator It = + SpillSlotsOrReMatsAvailable.find(StackSlot); + if (It == SpillSlotsOrReMatsAvailable.end()) return; + unsigned Reg = It->second >> 1; + + // Erase entries in PhysRegsAvailable for other stack slots. + std::multimap::iterator I = PhysRegsAvailable.lower_bound(Reg); + while (I != PhysRegsAvailable.end() && I->first == Reg) { + std::multimap::iterator NextI = llvm::next(I); + if (I->second != StackSlot) { + DEBUG(dbgs() << "Clobbered sharing SS#" << I->second << " in " + << PrintReg(Reg, TRI) << '\n'); + SpillSlotsOrReMatsAvailable.erase(I->second); + PhysRegsAvailable.erase(I); + } + I = NextI; + } +} + // ************************** // // Reuse Info Implementation // // ************************** // @@ -2550,6 +2574,10 @@ } } + // If StackSlot is available in a register that also holds other stack + // slots, clobber those stack slots now. + Spills.ClobberSharingStackSlots(StackSlot); + assert(PhysReg && "VR not assigned a physical register?"); MRI->setPhysRegUsed(PhysReg); unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg; From evan.cheng at apple.com Wed Mar 30 13:34:43 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 30 Mar 2011 11:34:43 -0700 Subject: [llvm-commits] [llvm] r128562 - /llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp In-Reply-To: <20110330181407.383D22A6C12D@llvm.org> References: <20110330181407.383D22A6C12D@llvm.org> Message-ID: On Mar 30, 2011, at 11:14 AM, Jakob Stoklund Olesen wrote: > Author: stoklund > Date: Wed Mar 30 13:14:07 2011 > New Revision: 128562 > > URL: http://llvm.org/viewvc/llvm-project?rev=128562&view=rev > Log: > Fix evil VirtRegRewriter bug. > > The rewriter can keep track of multiple stack slots in the same register if they > happen to have the same value. When an instruction modifies a stack slot by > defining a register that is mapped to a stack slot, other stack slots in that > register are no longer valid. > > This is a very rare problem, and I don't have a simple test case. I get the > impression that VirtRegRewriter knows it is about to be deleted, inventing a > last opaque problem. I've heard VirtRegRewriter is implementing a new register allocator that is completely dependent on it. Evan > > > > Modified: > llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp > > Modified: llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp?rev=128562&r1=128561&r2=128562&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp (original) > +++ llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Wed Mar 30 13:14:07 2011 > @@ -261,6 +261,10 @@ > /// now). > void ModifyStackSlotOrReMat(int SlotOrReMat); > > + /// ClobberSharingStackSlots - When a register mapped to a stack slot changes, > + /// other stack slots sharing the same register are no longer valid. > + void ClobberSharingStackSlots(int StackSlot); > + > /// AddAvailableRegsToLiveIn - Availability information is being kept coming > /// into the specified MBB. Add available physical registers as potential > /// live-in's. If they are reused in the MBB, they will be added to the > @@ -831,6 +835,26 @@ > PhysRegsAvailable.erase(I); > } > > +void AvailableSpills::ClobberSharingStackSlots(int StackSlot) { > + std::map::iterator It = > + SpillSlotsOrReMatsAvailable.find(StackSlot); > + if (It == SpillSlotsOrReMatsAvailable.end()) return; > + unsigned Reg = It->second >> 1; > + > + // Erase entries in PhysRegsAvailable for other stack slots. > + std::multimap::iterator I = PhysRegsAvailable.lower_bound(Reg); > + while (I != PhysRegsAvailable.end() && I->first == Reg) { > + std::multimap::iterator NextI = llvm::next(I); > + if (I->second != StackSlot) { > + DEBUG(dbgs() << "Clobbered sharing SS#" << I->second << " in " > + << PrintReg(Reg, TRI) << '\n'); > + SpillSlotsOrReMatsAvailable.erase(I->second); > + PhysRegsAvailable.erase(I); > + } > + I = NextI; > + } > +} > + > // ************************** // > // Reuse Info Implementation // > // ************************** // > @@ -2550,6 +2574,10 @@ > } > } > > + // If StackSlot is available in a register that also holds other stack > + // slots, clobber those stack slots now. > + Spills.ClobberSharingStackSlots(StackSlot); > + > assert(PhysReg && "VR not assigned a physical register?"); > MRI->setPhysRegUsed(PhysReg); > unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From stoklund at 2pi.dk Wed Mar 30 13:32:42 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 30 Mar 2011 18:32:42 -0000 Subject: [llvm-commits] [llvm] r128564 - /llvm/trunk/include/llvm/ADT/DenseMap.h Message-ID: <20110330183242.1C6AD2A6C12C@llvm.org> Author: stoklund Date: Wed Mar 30 13:32:41 2011 New Revision: 128564 URL: http://llvm.org/viewvc/llvm-project?rev=128564&view=rev Log: Prevent infinite growth of the DenseMap. When the hash function uses object pointers all free entries eventually become tombstones as they are used at least once, regardless of the size. DenseMap cannot function with zero empty keys, so it double size to get get ridof the tombstones. However DenseMap never shrinks automatically unless it is cleared, so the net result is that certain tables grow infinitely. The solution is to make a fresh copy of the table without tombstones instead of doubling size, by simply calling grow with the current size. Patch by Jos? Fonseca! Modified: llvm/trunk/include/llvm/ADT/DenseMap.h Modified: llvm/trunk/include/llvm/ADT/DenseMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=128564&r1=128563&r2=128564&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/DenseMap.h (original) +++ llvm/trunk/include/llvm/ADT/DenseMap.h Wed Mar 30 13:32:41 2011 @@ -289,11 +289,14 @@ // table completely filled with tombstones, no lookup would ever succeed, // causing infinite loops in lookup. ++NumEntries; - if (NumEntries*4 >= NumBuckets*3 || - NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) { + if (NumEntries*4 >= NumBuckets*3) { this->grow(NumBuckets * 2); LookupBucketFor(Key, TheBucket); } + if (NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) { + this->grow(NumBuckets); + LookupBucketFor(Key, TheBucket); + } // If we are writing over a tombstone, remember this. if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey())) From stoklund at 2pi.dk Wed Mar 30 13:32:45 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 30 Mar 2011 18:32:45 -0000 Subject: [llvm-commits] [llvm] r128565 - in /llvm/trunk: include/llvm/ADT/StringMap.h lib/Support/StringMap.cpp Message-ID: <20110330183245.228BF2A6C12D@llvm.org> Author: stoklund Date: Wed Mar 30 13:32:44 2011 New Revision: 128565 URL: http://llvm.org/viewvc/llvm-project?rev=128565&view=rev Log: Prevent infinite growth of SmallMap instances. Rehash but don't grow when full of tombstones. Patch by Jos? Fonseca! Modified: llvm/trunk/include/llvm/ADT/StringMap.h llvm/trunk/lib/Support/StringMap.cpp Modified: llvm/trunk/include/llvm/ADT/StringMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringMap.h?rev=128565&r1=128564&r2=128565&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringMap.h (original) +++ llvm/trunk/include/llvm/ADT/StringMap.h Wed Mar 30 13:32:44 2011 @@ -81,16 +81,6 @@ StringMapImpl(unsigned InitSize, unsigned ItemSize); void RehashTable(); - /// ShouldRehash - Return true if the table should be rehashed after a new - /// element was recently inserted. - bool ShouldRehash() const { - // If the hash table is now more than 3/4 full, or if fewer than 1/8 of - // the buckets are empty (meaning that many are filled with tombstones), - // grow the table. - return NumItems*4 > NumBuckets*3 || - NumBuckets-(NumItems+NumTombstones) < NumBuckets/8; - } - /// LookupBucketFor - Look up the bucket that the specified string should end /// up in. If it already exists as a key in the map, the Item pointer for the /// specified bucket will be non-null. Otherwise, it will be null. In either @@ -340,8 +330,7 @@ Bucket.Item = KeyValue; ++NumItems; - if (ShouldRehash()) - RehashTable(); + RehashTable(); return true; } @@ -383,8 +372,7 @@ // filled in by LookupBucketFor. Bucket.Item = NewItem; - if (ShouldRehash()) - RehashTable(); + RehashTable(); return *NewItem; } Modified: llvm/trunk/lib/Support/StringMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StringMap.cpp?rev=128565&r1=128564&r2=128565&view=diff ============================================================================== --- llvm/trunk/lib/Support/StringMap.cpp (original) +++ llvm/trunk/lib/Support/StringMap.cpp Wed Mar 30 13:32:44 2011 @@ -177,7 +177,19 @@ /// RehashTable - Grow the table, redistributing values into the buckets with /// the appropriate mod-of-hashtable-size. void StringMapImpl::RehashTable() { - unsigned NewSize = NumBuckets*2; + unsigned NewSize; + + // If the hash table is now more than 3/4 full, or if fewer than 1/8 of + // the buckets are empty (meaning that many are filled with tombstones), + // grow/rehash the table. + if (NumItems*4 > NumBuckets*3) { + NewSize = NumBuckets*2; + } else if (NumBuckets-(NumItems+NumTombstones) < NumBuckets/8) { + NewSize = NumBuckets; + } else { + return; + } + // Allocate one extra bucket which will always be non-empty. This allows the // iterators to stop at end. ItemBucket *NewTableArray =(ItemBucket*)calloc(NewSize+1, sizeof(ItemBucket)); From stoklund at 2pi.dk Wed Mar 30 13:32:48 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 30 Mar 2011 18:32:48 -0000 Subject: [llvm-commits] [llvm] r128566 - in /llvm/trunk: include/llvm/ADT/SmallPtrSet.h lib/Support/SmallPtrSet.cpp Message-ID: <20110330183248.38AA82A6C12E@llvm.org> Author: stoklund Date: Wed Mar 30 13:32:48 2011 New Revision: 128566 URL: http://llvm.org/viewvc/llvm-project?rev=128566&view=rev Log: Prevent infinite growth of SmallPtrSet instances. Rehash but don't grow when full of tombstones. Patch by Jos? Fonseca! Modified: llvm/trunk/include/llvm/ADT/SmallPtrSet.h llvm/trunk/lib/Support/SmallPtrSet.cpp Modified: llvm/trunk/include/llvm/ADT/SmallPtrSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SmallPtrSet.h?rev=128566&r1=128565&r2=128566&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/SmallPtrSet.h (original) +++ llvm/trunk/include/llvm/ADT/SmallPtrSet.h Wed Mar 30 13:32:48 2011 @@ -133,7 +133,7 @@ void shrink_and_clear(); /// Grow - Allocate a larger backing store for the buckets and move it over. - void Grow(); + void Grow(unsigned NewSize); void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT. protected: Modified: llvm/trunk/lib/Support/SmallPtrSet.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/SmallPtrSet.cpp?rev=128566&r1=128565&r2=128566&view=diff ============================================================================== --- llvm/trunk/lib/Support/SmallPtrSet.cpp (original) +++ llvm/trunk/lib/Support/SmallPtrSet.cpp Wed Mar 30 13:32:48 2011 @@ -52,10 +52,14 @@ // Otherwise, hit the big set case, which will call grow. } - // If more than 3/4 of the array is full, grow. - if (NumElements*4 >= CurArraySize*3 || - CurArraySize-(NumElements+NumTombstones) < CurArraySize/8) - Grow(); + if (NumElements*4 >= CurArraySize*3) { + // If more than 3/4 of the array is full, grow. + Grow(CurArraySize < 64 ? 128 : CurArraySize*2); + } else if (CurArraySize-(NumElements+NumTombstones) < CurArraySize/8) { + // If fewer of 1/8 of the array is empty (meaning that many are filled with + // tombstones), rehash. + Grow(CurArraySize); + } // Okay, we know we have space. Find a hash bucket. const void **Bucket = const_cast(FindBucketFor(Ptr)); @@ -125,10 +129,9 @@ /// Grow - Allocate a larger backing store for the buckets and move it over. /// -void SmallPtrSetImpl::Grow() { +void SmallPtrSetImpl::Grow(unsigned NewSize) { // Allocate at twice as many buckets, but at least 128. unsigned OldSize = CurArraySize; - unsigned NewSize = OldSize < 64 ? 128 : OldSize*2; const void **OldBuckets = CurArray; bool WasSmall = isSmall(); From stoklund at 2pi.dk Wed Mar 30 13:32:51 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 30 Mar 2011 18:32:51 -0000 Subject: [llvm-commits] [llvm] r128567 - in /llvm/trunk: include/llvm/ADT/StringMap.h lib/Support/StringMap.cpp Message-ID: <20110330183251.832FD2A6C12C@llvm.org> Author: stoklund Date: Wed Mar 30 13:32:51 2011 New Revision: 128567 URL: http://llvm.org/viewvc/llvm-project?rev=128567&view=rev Log: Reset StringMap's NumTombstones on clears and rehashes. StringMap was not properly updating NumTombstones after a clear or rehash. This was not fatal until now because the table was growing faster than NumTombstones could, but with the previous change of preventing infinite growth of the table the invariant (NumItems + NumTombstones <= NumBuckets) stopped being observed, causing infinite loops in certain situations. Patch by Jos? Fonseca! Modified: llvm/trunk/include/llvm/ADT/StringMap.h llvm/trunk/lib/Support/StringMap.cpp Modified: llvm/trunk/include/llvm/ADT/StringMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringMap.h?rev=128567&r1=128566&r2=128567&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringMap.h (original) +++ llvm/trunk/include/llvm/ADT/StringMap.h Wed Mar 30 13:32:51 2011 @@ -329,6 +329,7 @@ --NumTombstones; Bucket.Item = KeyValue; ++NumItems; + assert(NumItems + NumTombstones <= NumBuckets); RehashTable(); return true; @@ -348,6 +349,7 @@ } NumItems = 0; + NumTombstones = 0; } /// GetOrCreateValue - Look up the specified key in the table. If a value @@ -367,6 +369,7 @@ if (Bucket.Item == getTombstoneVal()) --NumTombstones; ++NumItems; + assert(NumItems + NumTombstones <= NumBuckets); // Fill in the bucket for the hash table. The FullHashValue was already // filled in by LookupBucketFor. Modified: llvm/trunk/lib/Support/StringMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StringMap.cpp?rev=128567&r1=128566&r2=128567&view=diff ============================================================================== --- llvm/trunk/lib/Support/StringMap.cpp (original) +++ llvm/trunk/lib/Support/StringMap.cpp Wed Mar 30 13:32:51 2011 @@ -169,6 +169,8 @@ TheTable[Bucket].Item = getTombstoneVal(); --NumItems; ++NumTombstones; + assert(NumItems + NumTombstones <= NumBuckets); + return Result; } @@ -224,4 +226,5 @@ TheTable = NewTableArray; NumBuckets = NewSize; + NumTombstones = 0; } From stoklund at 2pi.dk Wed Mar 30 13:32:53 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 30 Mar 2011 18:32:53 -0000 Subject: [llvm-commits] [llvm] r128568 - /llvm/trunk/include/llvm/PassAnalysisSupport.h Message-ID: <20110330183253.CBDD52A6C12D@llvm.org> Author: stoklund Date: Wed Mar 30 13:32:53 2011 New Revision: 128568 URL: http://llvm.org/viewvc/llvm-project?rev=128568&view=rev Log: Don't add the same analysis implementation pair twice. Prevent infinite growth of the list. Patch by Jos? Fonseca! Modified: llvm/trunk/include/llvm/PassAnalysisSupport.h Modified: llvm/trunk/include/llvm/PassAnalysisSupport.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/PassAnalysisSupport.h?rev=128568&r1=128567&r2=128568&view=diff ============================================================================== --- llvm/trunk/include/llvm/PassAnalysisSupport.h (original) +++ llvm/trunk/include/llvm/PassAnalysisSupport.h Wed Mar 30 13:32:53 2011 @@ -142,6 +142,8 @@ Pass *findImplPass(Pass *P, AnalysisID PI, Function &F); void addAnalysisImplsPair(AnalysisID PI, Pass *P) { + if (findImplPass(PI) == P) + return; std::pair pir = std::make_pair(PI,P); AnalysisImpls.push_back(pir); } From criswell at uiuc.edu Wed Mar 30 15:35:54 2011 From: criswell at uiuc.edu (John Criswell) Date: Wed, 30 Mar 2011 20:35:54 -0000 Subject: [llvm-commits] [poolalloc] r128571 - /poolalloc/trunk/lib/AssistDS/TestGEP.cpp Message-ID: <20110330203555.03F8A2A6C12C@llvm.org> Author: criswell Date: Wed Mar 30 15:35:54 2011 New Revision: 128571 URL: http://llvm.org/viewvc/llvm-project?rev=128571&view=rev Log: Fixed compilation warning. Modified: poolalloc/trunk/lib/AssistDS/TestGEP.cpp Modified: poolalloc/trunk/lib/AssistDS/TestGEP.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TestGEP.cpp?rev=128571&r1=128570&r2=128571&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TestGEP.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TestGEP.cpp Wed Mar 30 15:35:54 2011 @@ -120,7 +120,7 @@ NI = NewF->arg_begin(); SmallVector Ops(CI->op_begin()+1, CI->op_end()); Instruction *InsertPoint; - for (BasicBlock::iterator insrt = NewF->front().begin(); isa(InsertPoint = insrt); ++insrt); + for (BasicBlock::iterator insrt = NewF->front().begin(); isa(InsertPoint = insrt); ++insrt) {;} SmallVector Indices; Indices.append(GEP->op_begin()+1, GEP->op_end()); From ahatanak at gmail.com Wed Mar 30 16:15:36 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Wed, 30 Mar 2011 21:15:36 -0000 Subject: [llvm-commits] [llvm] r128574 - /llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Message-ID: <20110330211536.25CB42A6C12D@llvm.org> Author: ahatanak Date: Wed Mar 30 16:15:35 2011 New Revision: 128574 URL: http://llvm.org/viewvc/llvm-project?rev=128574&view=rev Log: fixed typo Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=128574&r1=128573&r2=128574&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Wed Mar 30 16:15:35 2011 @@ -197,7 +197,7 @@ // multHi/Lo: product of multiplication // Lo0: initial value of Lo register // Hi0: initial value of Hi register -// Return true if mattern matching was successful. +// Return true if pattern matching was successful. static bool SelectMadd(SDNode* ADDENode, SelectionDAG* CurDAG) { // ADDENode's second operand must be a flag output of an ADDC node in order // for the matching to be successful. @@ -271,7 +271,7 @@ // multHi/Lo: product of multiplication // Lo0: initial value of Lo register // Hi0: initial value of Hi register -// Return true if mattern matching was successful. +// Return true if pattern matching was successful. static bool SelectMsub(SDNode* SUBENode, SelectionDAG* CurDAG) { // SUBENode's second operand must be a flag output of an SUBC node in order // for the matching to be successful. From isanbard at gmail.com Wed Mar 30 16:37:19 2011 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 30 Mar 2011 21:37:19 -0000 Subject: [llvm-commits] [llvm] r128577 - in /llvm/trunk: lib/Transforms/Scalar/DeadStoreElimination.cpp test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll Message-ID: <20110330213719.495122A6C12C@llvm.org> Author: void Date: Wed Mar 30 16:37:19 2011 New Revision: 128577 URL: http://llvm.org/viewvc/llvm-project?rev=128577&view=rev Log: * The DSE code that tested for overlapping needed to take into account the fact that one of the numbers is signed while the other is unsigned. This could lead to a wrong result when the signed was promoted to an unsigned int. * Add the data layout line to the testcase so that it will test the appropriate thing. Patch by David Terei! Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/trunk/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=128577&r1=128576&r2=128577&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Wed Mar 30 16:37:19 2011 @@ -361,8 +361,10 @@ // // |--earlier--| // |----- later ------| + // + // We have to be careful here as *Off is signed while *.Size is unsigned. if (EarlierOff >= LaterOff && - EarlierOff + Earlier.Size <= LaterOff + Later.Size) + uint64_t(EarlierOff - LaterOff) + Earlier.Size <= Later.Size) return true; // Otherwise, they don't completely overlap. Modified: llvm/trunk/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll?rev=128577&r1=128576&r2=128577&view=diff ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll (original) +++ llvm/trunk/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll Wed Mar 30 16:37:19 2011 @@ -1,5 +1,6 @@ ; RUN: opt < %s -basicaa -dse -S | FileCheck %s ; PR9561 +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-n8:16:32" target triple = "i386-apple-darwin9.8" @A = external global [0 x i32] From dpatel at apple.com Wed Mar 30 17:32:46 2011 From: dpatel at apple.com (Devang Patel) Date: Wed, 30 Mar 2011 22:32:46 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r128582 - /llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Message-ID: <20110330223246.900372A6C12C@llvm.org> Author: dpatel Date: Wed Mar 30 17:32:46 2011 New Revision: 128582 URL: http://llvm.org/viewvc/llvm-project?rev=128582&view=rev Log: Use full path as AT_name in TAG_compile_unit. The debugger may not be able to construct full path using AT_comp_dir due to one or other reason. Radar 8884898. Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=128582&r1=128581&r2=128582&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Wed Mar 30 17:32:46 2011 @@ -1389,18 +1389,20 @@ /// create a new one if necessary. DICompileUnit DebugInfo::getOrCreateCompileUnit(const char *FullPath, bool isMain) { + // Get source file information. + std::string Directory = get_src_pwd(); + std::string FileName; if (!FullPath) { if (!strcmp (main_input_filename, "")) - FullPath = ""; + FileName = ""; else - FullPath = main_input_filename; - } - - // Get source file information. - std::string Directory; - std::string FileName; - DirectoryAndFile(FullPath, Directory, FileName); + FileName = main_input_filename; + } else + FileName = FullPath; + if (FileName[0] != '/' && FullPath) + FileName = std::string(get_src_pwd()) + "/" + FileName; + // Set up Language number. unsigned LangTag; const std::string LanguageName(lang_hooks.name); From grosbach at apple.com Wed Mar 30 17:38:14 2011 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 30 Mar 2011 22:38:14 -0000 Subject: [llvm-commits] [llvm] r128583 - in /llvm/trunk/include/llvm/ExecutionEngine: ExecutionEngine.h JITMemoryManager.h Message-ID: <20110330223814.2669C2A6C12C@llvm.org> Author: grosbach Date: Wed Mar 30 17:38:13 2011 New Revision: 128583 URL: http://llvm.org/viewvc/llvm-project?rev=128583&view=rev Log: Tidy up. Whitespace and 80-columns. Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=128583&r1=128582&r2=128583&view=diff ============================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h (original) +++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Wed Mar 30 17:38:13 2011 @@ -118,11 +118,11 @@ /// The list of Modules that we are JIT'ing from. We use a SmallVector to /// optimize for the case where there is only one module. SmallVector Modules; - + void setTargetData(const TargetData *td) { TD = td; } - + /// getMemoryforGV - Allocate memory for a global variable. virtual char *getMemoryForGV(const GlobalVariable *GV); @@ -156,7 +156,7 @@ /// pointer is invoked to create it. If this returns null, the JIT will /// abort. void *(*LazyFunctionCreator)(const std::string &); - + /// ExceptionTableRegister - If Exception Handling is set, the JIT will /// register dwarf tables with this function. typedef void (*EERegisterFn)(void*); @@ -216,7 +216,7 @@ virtual void addModule(Module *M) { Modules.push_back(M); } - + //===--------------------------------------------------------------------===// const TargetData *getTargetData() const { return TD; } @@ -229,7 +229,7 @@ /// defines FnName. This is very slow operation and shouldn't be used for /// general code. Function *FindFunctionNamed(const char *FnName); - + /// runFunction - Execute the specified function with the specified arguments, /// and return the result. virtual GenericValue runFunction(Function *F, @@ -246,8 +246,8 @@ /// /// \param isDtors - Run the destructors instead of constructors. void runStaticConstructorsDestructors(Module *module, bool isDtors); - - + + /// runFunctionAsMain - This is a helper function which wraps runFunction to /// handle the common task of starting up main with the specified argc, argv, /// and envp parameters. @@ -262,21 +262,21 @@ /// existing data in memory. Mappings are automatically removed when their /// GlobalValue is destroyed. void addGlobalMapping(const GlobalValue *GV, void *Addr); - + /// clearAllGlobalMappings - Clear all global mappings and start over again, /// for use in dynamic compilation scenarios to move globals. void clearAllGlobalMappings(); - + /// clearGlobalMappingsFromModule - Clear all global mappings that came from a /// particular module, because it has been removed from the JIT. void clearGlobalMappingsFromModule(Module *M); - + /// updateGlobalMapping - Replace an existing mapping for GV with a new /// address. This updates both maps as required. If "Addr" is null, the /// entry for the global is removed from the mappings. This returns the old /// value of the pointer, or null if it was not in the map. void *updateGlobalMapping(const GlobalValue *GV, void *Addr); - + /// getPointerToGlobalIfAvailable - This returns the address of the specified /// global value if it is has already been codegen'd, otherwise it returns /// null. @@ -297,7 +297,7 @@ /// different ways. Return the representation for a blockaddress of the /// specified block. virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0; - + /// getPointerToFunctionOrStub - If the specified function has been /// code-gen'd, return a pointer to the function. If not, compile it, or use /// a stub to implement lazy compilation if available. See @@ -401,7 +401,7 @@ void InstallLazyFunctionCreator(void* (*P)(const std::string &)) { LazyFunctionCreator = P; } - + /// InstallExceptionTableRegister - The JIT will use the given function /// to register the exception tables it generates. void InstallExceptionTableRegister(EERegisterFn F) { @@ -410,7 +410,7 @@ void InstallExceptionTableDeregister(EERegisterFn F) { ExceptionTableDeregister = F; } - + /// RegisterTable - Registers the given pointer as an exception table. It /// uses the ExceptionTableRegister function. void RegisterTable(const Function *fn, void* res) { @@ -420,10 +420,12 @@ } } - /// DeregisterTable - Deregisters the exception frame previously registered for the given function. + /// DeregisterTable - Deregisters the exception frame previously registered + /// for the given function. void DeregisterTable(const Function *Fn) { if (ExceptionTableDeregister) { - DenseMap::iterator frame = AllExceptionTables.find(Fn); + DenseMap::iterator frame = + AllExceptionTables.find(Fn); if(frame != AllExceptionTables.end()) { ExceptionTableDeregister(frame->second); AllExceptionTables.erase(frame); @@ -443,7 +445,7 @@ void EmitGlobalVariable(const GlobalVariable *GV); GenericValue getConstantValue(const Constant *C); - void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, + void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, const Type *Ty); }; Modified: llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h?rev=128583&r1=128582&r2=128583&view=diff ============================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h (original) +++ llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h Wed Mar 30 17:38:13 2011 @@ -29,11 +29,11 @@ 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(); - + /// setMemoryWritable - When code generation is in progress, /// the code pages may need permissions changed. virtual void setMemoryWritable() = 0; @@ -55,16 +55,16 @@ /// 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 uint8_t *getGOTBase() const = 0; - + //===--------------------------------------------------------------------===// // Main Allocation Functions //===--------------------------------------------------------------------===// @@ -91,11 +91,11 @@ /// startFunctionBody. virtual uint8_t *allocateStub(const GlobalValue* F, 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 + /// 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, uint8_t *FunctionStart, @@ -113,12 +113,12 @@ /// been deallocated yet. This is never called when the JIT is currently /// emitting a function. virtual void deallocateFunctionBody(void *Body) = 0; - + /// startExceptionTable - When we finished JITing the function, if exception /// handling is set, we emit the exception table. virtual uint8_t* startExceptionTable(const Function* F, uintptr_t &ActualSize) = 0; - + /// endExceptionTable - This method is called when the JIT is done emitting /// the exception table. virtual void endExceptionTable(const Function *F, uint8_t *TableStart, From zwarich at apple.com Wed Mar 30 18:01:21 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 30 Mar 2011 23:01:21 -0000 Subject: [llvm-commits] [llvm] r128584 - in /llvm/trunk: lib/Target/ARM/ARMFastISel.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/ARM/ARMInstrNEON.td test/CodeGen/ARM/vbsl-constant.ll Message-ID: <20110330230122.25A292A6C12C@llvm.org> Author: zwarich Date: Wed Mar 30 18:01:21 2011 New Revision: 128584 URL: http://llvm.org/viewvc/llvm-project?rev=128584&view=rev Log: Add a ARM-specific SD node for VBSL so that forms with a constant first operand can be recognized. This fixes . Added: llvm/trunk/test/CodeGen/ARM/vbsl-constant.ll Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=128584&r1=128583&r2=128584&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Wed Mar 30 18:01:21 2011 @@ -115,6 +115,11 @@ const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill); + virtual unsigned FastEmitInst_rrr(unsigned MachineInstOpcode, + const TargetRegisterClass *RC, + unsigned Op0, bool Op0IsKill, + unsigned Op1, bool Op1IsKill, + unsigned Op2, bool Op2IsKill); virtual unsigned FastEmitInst_ri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, @@ -315,6 +320,31 @@ return ResultReg; } +unsigned ARMFastISel::FastEmitInst_rrr(unsigned MachineInstOpcode, + const TargetRegisterClass *RC, + unsigned Op0, bool Op0IsKill, + unsigned Op1, bool Op1IsKill, + unsigned Op2, bool Op2IsKill) { + unsigned ResultReg = createResultReg(RC); + const TargetInstrDesc &II = TII.get(MachineInstOpcode); + + if (II.getNumDefs() >= 1) + AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) + .addReg(Op0, Op0IsKill * RegState::Kill) + .addReg(Op1, Op1IsKill * RegState::Kill) + .addReg(Op2, Op2IsKill * RegState::Kill)); + else { + AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) + .addReg(Op0, Op0IsKill * RegState::Kill) + .addReg(Op1, Op1IsKill * RegState::Kill) + .addReg(Op2, Op2IsKill * RegState::Kill)); + AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(TargetOpcode::COPY), ResultReg) + .addReg(II.ImplicitDefs[0])); + } + return ResultReg; +} + unsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=128584&r1=128583&r2=128584&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Mar 30 18:01:21 2011 @@ -866,6 +866,7 @@ case ARMISD::BFI: return "ARMISD::BFI"; case ARMISD::VORRIMM: return "ARMISD::VORRIMM"; case ARMISD::VBICIMM: return "ARMISD::VBICIMM"; + case ARMISD::VBSL: return "ARMISD::VBSL"; case ARMISD::VLD2DUP: return "ARMISD::VLD2DUP"; case ARMISD::VLD3DUP: return "ARMISD::VLD3DUP"; case ARMISD::VLD4DUP: return "ARMISD::VLD4DUP"; @@ -5336,6 +5337,37 @@ } } + SDValue N0 = N->getOperand(0); + if (N0.getOpcode() != ISD::AND) + return SDValue(); + SDValue N1 = N->getOperand(1); + + // (or (and B, A), (and C, ~A)) => (VBSL A, B, C) when A is a constant. + if (Subtarget->hasNEON() && N1.getOpcode() == ISD::AND && VT.isVector() && + DAG.getTargetLoweringInfo().isTypeLegal(VT)) { + APInt SplatUndef; + unsigned SplatBitSize; + bool HasAnyUndefs; + + BuildVectorSDNode *BVN0 = dyn_cast(N0->getOperand(1)); + APInt SplatBits0; + if (BVN0 && BVN0->isConstantSplat(SplatBits0, SplatUndef, SplatBitSize, + HasAnyUndefs) && !HasAnyUndefs) { + BuildVectorSDNode *BVN1 = dyn_cast(N1->getOperand(1)); + APInt SplatBits1; + if (BVN1 && BVN1->isConstantSplat(SplatBits1, SplatUndef, SplatBitSize, + HasAnyUndefs) && !HasAnyUndefs && + SplatBits0 == ~SplatBits1) { + // Canonicalize the vector type to make instruction selection simpler. + EVT CanonicalVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32; + SDValue Result = DAG.getNode(ARMISD::VBSL, dl, CanonicalVT, + N0->getOperand(1), N0->getOperand(0), + N1->getOperand(1)); + return DAG.getNode(ISD::BITCAST, dl, VT, Result); + } + } + } + // Try to use the ARM/Thumb2 BFI (bitfield insert) instruction when // reasonable. @@ -5343,7 +5375,6 @@ if (Subtarget->isThumb1Only() || !Subtarget->hasV6T2Ops()) return SDValue(); - SDValue N0 = N->getOperand(0), N1 = N->getOperand(1); DebugLoc DL = N->getDebugLoc(); // 1) or (and A, mask), val => ARMbfi A, val, mask // iff (val & mask) == val @@ -5354,8 +5385,6 @@ // 2b) iff isBitFieldInvertedMask(~mask) && isBitFieldInvertedMask(mask2) // && ~mask == mask2 // (i.e., copy a bitfield value into another bitfield of the same width) - if (N0.getOpcode() != ISD::AND) - return SDValue(); if (VT != MVT::i32) return SDValue(); Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=128584&r1=128583&r2=128584&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Wed Mar 30 18:01:21 2011 @@ -179,6 +179,9 @@ // Vector AND with NOT of immediate VBICIMM, + // Vector bitwise select + VBSL, + // Vector load N-element structure to all lanes: VLD2DUP = ISD::FIRST_TARGET_MEMORY_OPCODE, VLD3DUP, Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=128584&r1=128583&r2=128584&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Wed Mar 30 18:01:21 2011 @@ -80,6 +80,12 @@ def NEONvorrImm : SDNode<"ARMISD::VORRIMM", SDTARMVORRIMM>; def NEONvbicImm : SDNode<"ARMISD::VBICIMM", SDTARMVORRIMM>; +def NEONvbsl : SDNode<"ARMISD::VBSL", + SDTypeProfile<1, 3, [SDTCisVec<0>, + SDTCisSameAs<0, 1>, + SDTCisSameAs<0, 2>, + SDTCisSameAs<0, 3>]>>; + def NEONvdup : SDNode<"ARMISD::VDUP", SDTypeProfile<1, 1, [SDTCisVec<0>]>>; // VDUPLANE can produce a quad-register result from a double-register source, @@ -3767,16 +3773,21 @@ (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VCNTiD, "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd", - [(set DPR:$Vd, - (v2i32 (or (and DPR:$Vn, DPR:$src1), - (and DPR:$Vm, (vnotd DPR:$src1)))))]>; + [(set DPR:$Vd, (v2i32 (NEONvbsl DPR:$src1, DPR:$Vn, DPR:$Vm)))]>; + +def : Pat<(v2i32 (or (and DPR:$Vn, DPR:$Vd), + (and DPR:$Vm, (vnotd DPR:$Vd)))), + (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm)>; + def VBSLq : N3VX<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VCNTiQ, "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd", - [(set QPR:$Vd, - (v4i32 (or (and QPR:$Vn, QPR:$src1), - (and QPR:$Vm, (vnotq QPR:$src1)))))]>; + [(set QPR:$Vd, (v4i32 (NEONvbsl QPR:$src1, QPR:$Vn, QPR:$Vm)))]>; + +def : Pat<(v4i32 (or (and QPR:$Vn, QPR:$Vd), + (and QPR:$Vm, (vnotq QPR:$Vd)))), + (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm)>; // VBIF : Vector Bitwise Insert if False // like VBSL but with: "vbif $dst, $src3, $src1", "$src2 = $dst", Added: llvm/trunk/test/CodeGen/ARM/vbsl-constant.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vbsl-constant.ll?rev=128584&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vbsl-constant.ll (added) +++ llvm/trunk/test/CodeGen/ARM/vbsl-constant.ll Wed Mar 30 18:01:21 2011 @@ -0,0 +1,97 @@ +; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s + +define <8 x i8> @v_bsli8(<8 x i8>* %A, <8 x i8>* %B, <8 x i8>* %C) nounwind { +;CHECK: v_bsli8: +;CHECK: vbsl + %tmp1 = load <8 x i8>* %A + %tmp2 = load <8 x i8>* %B + %tmp3 = load <8 x i8>* %C + %tmp4 = and <8 x i8> %tmp1, + %tmp6 = and <8 x i8> %tmp3, + %tmp7 = or <8 x i8> %tmp4, %tmp6 + ret <8 x i8> %tmp7 +} + +define <4 x i16> @v_bsli16(<4 x i16>* %A, <4 x i16>* %B, <4 x i16>* %C) nounwind { +;CHECK: v_bsli16: +;CHECK: vbsl + %tmp1 = load <4 x i16>* %A + %tmp2 = load <4 x i16>* %B + %tmp3 = load <4 x i16>* %C + %tmp4 = and <4 x i16> %tmp1, + %tmp6 = and <4 x i16> %tmp3, + %tmp7 = or <4 x i16> %tmp4, %tmp6 + ret <4 x i16> %tmp7 +} + +define <2 x i32> @v_bsli32(<2 x i32>* %A, <2 x i32>* %B, <2 x i32>* %C) nounwind { +;CHECK: v_bsli32: +;CHECK: vbsl + %tmp1 = load <2 x i32>* %A + %tmp2 = load <2 x i32>* %B + %tmp3 = load <2 x i32>* %C + %tmp4 = and <2 x i32> %tmp1, + %tmp6 = and <2 x i32> %tmp3, + %tmp7 = or <2 x i32> %tmp4, %tmp6 + ret <2 x i32> %tmp7 +} + +define <1 x i64> @v_bsli64(<1 x i64>* %A, <1 x i64>* %B, <1 x i64>* %C) nounwind { +;CHECK: v_bsli64: +;CHECK: vbsl + %tmp1 = load <1 x i64>* %A + %tmp2 = load <1 x i64>* %B + %tmp3 = load <1 x i64>* %C + %tmp4 = and <1 x i64> %tmp1, + %tmp6 = and <1 x i64> %tmp3, + %tmp7 = or <1 x i64> %tmp4, %tmp6 + ret <1 x i64> %tmp7 +} + +define <16 x i8> @v_bslQi8(<16 x i8>* %A, <16 x i8>* %B, <16 x i8>* %C) nounwind { +;CHECK: v_bslQi8: +;CHECK: vbsl + %tmp1 = load <16 x i8>* %A + %tmp2 = load <16 x i8>* %B + %tmp3 = load <16 x i8>* %C + %tmp4 = and <16 x i8> %tmp1, + %tmp6 = and <16 x i8> %tmp3, + %tmp7 = or <16 x i8> %tmp4, %tmp6 + ret <16 x i8> %tmp7 +} + +define <8 x i16> @v_bslQi16(<8 x i16>* %A, <8 x i16>* %B, <8 x i16>* %C) nounwind { +;CHECK: v_bslQi16: +;CHECK: vbsl + %tmp1 = load <8 x i16>* %A + %tmp2 = load <8 x i16>* %B + %tmp3 = load <8 x i16>* %C + %tmp4 = and <8 x i16> %tmp1, + %tmp6 = and <8 x i16> %tmp3, + %tmp7 = or <8 x i16> %tmp4, %tmp6 + ret <8 x i16> %tmp7 +} + +define <4 x i32> @v_bslQi32(<4 x i32>* %A, <4 x i32>* %B, <4 x i32>* %C) nounwind { +;CHECK: v_bslQi32: +;CHECK: vbsl + %tmp1 = load <4 x i32>* %A + %tmp2 = load <4 x i32>* %B + %tmp3 = load <4 x i32>* %C + %tmp4 = and <4 x i32> %tmp1, + %tmp6 = and <4 x i32> %tmp3, + %tmp7 = or <4 x i32> %tmp4, %tmp6 + ret <4 x i32> %tmp7 +} + +define <2 x i64> @v_bslQi64(<2 x i64>* %A, <2 x i64>* %B, <2 x i64>* %C) nounwind { +;CHECK: v_bslQi64: +;CHECK: vbsl + %tmp1 = load <2 x i64>* %A + %tmp2 = load <2 x i64>* %B + %tmp3 = load <2 x i64>* %C + %tmp4 = and <2 x i64> %tmp1, + %tmp6 = and <2 x i64> %tmp3, + %tmp7 = or <2 x i64> %tmp4, %tmp6 + ret <2 x i64> %tmp7 +} From bruno.cardoso at gmail.com Wed Mar 30 18:32:32 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Wed, 30 Mar 2011 23:32:32 -0000 Subject: [llvm-commits] [llvm] r128585 - in /llvm/trunk: lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.h test/MC/ARM/arm_addrmode2.s Message-ID: <20110330233232.BB4612A6C12C@llvm.org> Author: bruno Date: Wed Mar 30 18:32:32 2011 New Revision: 128585 URL: http://llvm.org/viewvc/llvm-project?rev=128585&view=rev Log: - Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and {STR,LDC}{2}_PRE. - Fixed the encoding in some places. - Some of those instructions were using am2offset and now use addrmode2. Codegen isn't affected, instructions which use SelectAddrMode2Offset were not touched. - Teach printAddrMode2Operand to check by the addressing mode which index mode to print. - This is a work in progress, more work to come. The idea is to change places which use am2offset to use addrmode2 instead, as to unify assembly parser. - Add testcases for assembly parser Added: llvm/trunk/test/MC/ARM/arm_addrmode2.s Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h llvm/trunk/lib/Target/ARM/ARMInstrFormats.td llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=128585&r1=128584&r2=128585&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Wed Mar 30 18:32:32 2011 @@ -200,6 +200,51 @@ } namespace ARMII { + + /// ARM Addressing Modes + enum AddrMode { + AddrModeNone = 0, + AddrMode1 = 1, + AddrMode2 = 2, + AddrMode3 = 3, + AddrMode4 = 4, + AddrMode5 = 5, + AddrMode6 = 6, + AddrModeT1_1 = 7, + AddrModeT1_2 = 8, + AddrModeT1_4 = 9, + AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data + AddrModeT2_i12 = 11, + AddrModeT2_i8 = 12, + AddrModeT2_so = 13, + AddrModeT2_pc = 14, // +/- i12 for pc relative data + AddrModeT2_i8s4 = 15, // i8 * 4 + AddrMode_i12 = 16 + }; + + inline static const char *AddrModeToString(AddrMode addrmode) { + switch (addrmode) { + default: llvm_unreachable("Unknown memory operation"); + case AddrModeNone: return "AddrModeNone"; + case AddrMode1: return "AddrMode1"; + case AddrMode2: return "AddrMode2"; + case AddrMode3: return "AddrMode3"; + case AddrMode4: return "AddrMode4"; + case AddrMode5: return "AddrMode5"; + case AddrMode6: return "AddrMode6"; + case AddrModeT1_1: return "AddrModeT1_1"; + case AddrModeT1_2: return "AddrModeT1_2"; + case AddrModeT1_4: return "AddrModeT1_4"; + case AddrModeT1_s: return "AddrModeT1_s"; + case AddrModeT2_i12: return "AddrModeT2_i12"; + case AddrModeT2_i8: return "AddrModeT2_i8"; + case AddrModeT2_so: return "AddrModeT2_so"; + case AddrModeT2_pc: return "AddrModeT2_pc"; + case AddrModeT2_i8s4: return "AddrModeT2_i8s4"; + case AddrMode_i12: return "AddrMode_i12"; + } + } + /// Target Operand Flag enum. enum TOF { //===------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=128585&r1=128584&r2=128585&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Wed Mar 30 18:32:32 2011 @@ -34,25 +34,7 @@ //===------------------------------------------------------------------===// // This four-bit field describes the addressing mode used. - - AddrModeMask = 0x1f, - AddrModeNone = 0, - AddrMode1 = 1, - AddrMode2 = 2, - AddrMode3 = 3, - AddrMode4 = 4, - AddrMode5 = 5, - AddrMode6 = 6, - AddrModeT1_1 = 7, - AddrModeT1_2 = 8, - AddrModeT1_4 = 9, - AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data - AddrModeT2_i12 = 11, - AddrModeT2_i8 = 12, - AddrModeT2_so = 13, - AddrModeT2_pc = 14, // +/- i12 for pc relative data - AddrModeT2_i8s4 = 15, // i8 * 4 - AddrMode_i12 = 16, + AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h // Size* - Flags to keep track of the size of an instruction. SizeShift = 5, Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128585&r1=128584&r2=128585&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Wed Mar 30 18:32:32 2011 @@ -515,15 +515,15 @@ : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, pattern> { // AM2 store w/ two operands: (GPR, am2offset) + // {17-14} Rn // {13} 1 == Rm, 0 == imm12 // {12} isAdd // {11-0} imm12/Rm - bits<14> offset; - bits<4> Rn; - let Inst{25} = offset{13}; - let Inst{23} = offset{12}; - let Inst{19-16} = Rn; - let Inst{11-0} = offset{11-0}; + bits<18> addr; + let Inst{25} = addr{13}; + let Inst{23} = addr{12}; + let Inst{19-16} = addr{17-14}; + let Inst{11-0} = addr{11-0}; } // addrmode3 instructions Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128585&r1=128584&r2=128585&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed Mar 30 18:32:32 2011 @@ -498,6 +498,12 @@ let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } +def MemMode2AsmOperand : AsmOperandClass { + let Name = "MemMode2"; + let SuperClasses = []; + let ParserMethod = "tryParseMemMode2Operand"; +} + // addrmode2 := reg +/- imm12 // := reg +/- reg shop imm // @@ -505,6 +511,7 @@ ComplexPattern { let EncoderMethod = "getAddrMode2OpValue"; let PrintMethod = "printAddrMode2Operand"; + let ParserMatchClass = MemMode2AsmOperand; let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } @@ -1656,6 +1663,7 @@ let Inst{23} = addr{12}; let Inst{19-16} = addr{17-14}; let Inst{11-0} = addr{11-0}; + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; } def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), (ins GPR:$Rn, am2offset:$offset), @@ -1714,17 +1722,35 @@ // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. let mayLoad = 1, neverHasSideEffects = 1 in { -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb), - (ins GPR:$base, am2offset:$offset), IndexModePost, - LdFrm, IIC_iLoad_ru, - "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { +def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb), + (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru, + "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { + // {17-14} Rn + // {13} 1 == Rm, 0 == imm12 + // {12} isAdd + // {11-0} imm12/Rm + bits<18> addr; + let Inst{25} = addr{13}; + let Inst{23} = addr{12}; let Inst{21} = 1; // overwrite -} -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb), - (ins GPR:$base, am2offset:$offset), IndexModePost, - LdFrm, IIC_iLoad_bh_ru, - "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { + let Inst{19-16} = addr{17-14}; + let Inst{11-0} = addr{11-0}; + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; +} +def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), + (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru, + "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { + // {17-14} Rn + // {13} 1 == Rm, 0 == imm12 + // {12} isAdd + // {11-0} imm12/Rm + bits<18> addr; + let Inst{25} = addr{13}; + let Inst{23} = addr{12}; let Inst{21} = 1; // overwrite + let Inst{19-16} = addr{17-14}; + let Inst{11-0} = addr{11-0}; + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; } def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb), (ins GPR:$base, am3offset:$offset), IndexModePost, @@ -1818,20 +1844,20 @@ // STRT, STRBT, and STRHT are for disassembly only. -def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn,am2offset:$offset), +def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), IndexModePost, StFrm, IIC_iStore_ru, - "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", + "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb", [/* For disassembly only; pattern left blank */]> { let Inst{21} = 1; // overwrite + let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; } -def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), +def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), IndexModePost, StFrm, IIC_iStore_bh_ru, - "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", + "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb", [/* For disassembly only; pattern left blank */]> { let Inst{21} = 1; // overwrite + let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; } def STRHT: AI3sthpo<(outs GPR:$base_wb), @@ -3391,8 +3417,9 @@ let Inst{23-20} = opc1; } -class ACI - : I + : I { let Inst{27-25} = 0b110; } @@ -3411,7 +3438,7 @@ def _PRE : ACI<(outs), (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - opc, "\tp$cop, cr$CRd, $addr!"> { + opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> { let Inst{31-28} = op31_28; let Inst{24} = 1; // P = 1 let Inst{21} = 1; // W = 1 @@ -3452,7 +3479,7 @@ def L_PRE : ACI<(outs), (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> { let Inst{31-28} = op31_28; let Inst{24} = 1; // P = 1 let Inst{21} = 1; // W = 1 Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128585&r1=128584&r2=128585&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Wed Mar 30 18:32:32 2011 @@ -48,7 +48,8 @@ bool TryParseRegisterWithWriteBack(SmallVectorImpl &); bool TryParseShiftRegister(SmallVectorImpl &); bool ParseRegisterList(SmallVectorImpl &); - bool ParseMemory(SmallVectorImpl &); + bool ParseMemory(SmallVectorImpl &, + ARMII::AddrMode AddrMode); bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic); bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); const MCExpr *ApplyPrefixToExpr(const MCExpr *E, @@ -95,6 +96,14 @@ SmallVectorImpl&); OperandMatchResultTy tryParseMSRMaskOperand( SmallVectorImpl&); + OperandMatchResultTy tryParseMemMode2Operand( + SmallVectorImpl&); + + // Asm Match Converter Methods + bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &); + bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &); public: ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) @@ -172,6 +181,7 @@ /// Combined record for all forms of ARM address expressions. struct { + ARMII::AddrMode AddrMode; unsigned BaseRegNum; union { unsigned RegNum; ///< Offset register num, when OffsetIsReg. @@ -293,7 +303,9 @@ /// @name Memory Operand Accessors /// @{ - + ARMII::AddrMode getMemAddrMode() const { + return Mem.AddrMode; + } unsigned getMemBaseRegNum() const { return Mem.BaseRegNum; } @@ -338,6 +350,27 @@ bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } bool isMemory() const { return Kind == Memory; } bool isShifter() const { return Kind == Shifter; } + bool isMemMode2() const { + if (getMemAddrMode() != ARMII::AddrMode2) + return false; + + if (getMemOffsetIsReg()) + return true; + + if (getMemNegative() && + !(getMemPostindexed() || getMemPreindexed())) + return false; + + const MCConstantExpr *CE = dyn_cast(getMemOffset()); + if (!CE) return false; + int64_t Value = CE->getValue(); + + // The offset must be in the range 0-4095 (imm12). + if (Value > 4095 || Value < -4095) + return false; + + return true; + } bool isMemMode5() const { if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || getMemNegative()) @@ -465,6 +498,46 @@ "No offset operand support in mode 7"); } + void addMemMode2Operands(MCInst &Inst, unsigned N) const { + assert(isMemMode2() && "Invalid mode or number of operands!"); + Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); + + if (getMemOffsetIsReg()) { + Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); + + ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; + ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; + int64_t ShiftAmount = 0; + + if (getMemOffsetRegShifted()) { + ShOpc = getMemShiftType(); + const MCConstantExpr *CE = + dyn_cast(getMemShiftAmount()); + ShiftAmount = CE->getValue(); + } + + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, + ShOpc))); + return; + } + + // Create a operand placeholder to always yield the same number of operands. + Inst.addOperand(MCOperand::CreateReg(0)); + + // FIXME: #-0 is encoded differently than #0. Does the parser preserve + // the difference? + const MCConstantExpr *CE = dyn_cast(getMemOffset()); + assert(CE && "Non-constant mode 2 offset operand!"); + int64_t Offset = CE->getValue(); + + if (Offset >= 0) + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, + Offset, ARM_AM::no_shift))); + else + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, + -Offset, ARM_AM::no_shift))); + } + void addMemMode5Operands(MCInst &Inst, unsigned N) const { assert(N == 2 && isMemMode5() && "Invalid number of operands!"); @@ -599,9 +672,9 @@ return Op; } - static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, - const MCExpr *Offset, int OffsetRegNum, - bool OffsetRegShifted, + static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, + bool OffsetIsReg, const MCExpr *Offset, + int OffsetRegNum, bool OffsetRegShifted, enum ARM_AM::ShiftOpc ShiftType, const MCExpr *ShiftAmount, bool Preindexed, bool Postindexed, bool Negative, bool Writeback, @@ -618,6 +691,7 @@ "Cannot have expression offset and register offset!"); ARMOperand *Op = new ARMOperand(Memory); + Op->Mem.AddrMode = AddrMode; Op->Mem.BaseRegNum = BaseRegNum; Op->Mem.OffsetIsReg = OffsetIsReg; if (OffsetIsReg) @@ -689,7 +763,8 @@ break; case Memory: OS << " &Operands) { + SMLoc S = Parser.getTok().getLoc(); + const AsmToken &Tok = Parser.getTok(); + assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\""); + + if (ParseMemory(Operands, ARMII::AddrMode2)) + return MatchOperand_NoMatch; + + return MatchOperand_Success; +} + +/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. +/// Needed here because the Asm Gen Matcher can't handle properly tied operands +/// when they refer multiple MIOperands inside a single one. +bool ARMAsmParser:: +CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &Operands) { + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); + + // Create a writeback register dummy placeholder. + Inst.addOperand(MCOperand::CreateImm(0)); + + ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); + return true; +} + +/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. +/// Needed here because the Asm Gen Matcher can't handle properly tied operands +/// when they refer multiple MIOperands inside a single one. +bool ARMAsmParser:: +CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &Operands) { + // Create a writeback register dummy placeholder. + Inst.addOperand(MCOperand::CreateImm(0)); + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); + ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); + return true; +} + /// Parse an ARM memory expression, return false if successful else return true /// or an error. The first token must be a '[' when called. /// /// TODO Only preindexing and postindexing addressing are started, unindexed /// with option, etc are still to do. bool ARMAsmParser:: -ParseMemory(SmallVectorImpl &Operands) { +ParseMemory(SmallVectorImpl &Operands, + ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { SMLoc S, E; assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a Left Bracket"); @@ -1231,11 +1350,10 @@ Offset = MCConstantExpr::Create(0, getContext()); } - Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, - OffsetRegNum, OffsetRegShifted, - ShiftType, ShiftAmount, Preindexed, - Postindexed, Negative, Writeback, - S, E)); + Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, + Offset, OffsetRegNum, OffsetRegShifted, + ShiftType, ShiftAmount, Preindexed, + Postindexed, Negative, Writeback, S, E)); if (WBOp) Operands.push_back(WBOp); Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=128585&r1=128584&r2=128585&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Wed Mar 30 18:32:32 2011 @@ -14,6 +14,7 @@ #define DEBUG_TYPE "asm-printer" #include "ARMBaseInfo.h" #include "ARMInstPrinter.h" +#include "ARMInstrInfo.h" #include "ARMAddressingModes.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCAsmInfo.h" @@ -181,18 +182,12 @@ } } - -void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, - raw_ostream &O) { +void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, + raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(Op); const MCOperand &MO2 = MI->getOperand(Op+1); const MCOperand &MO3 = MI->getOperand(Op+2); - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. - printOperand(MI, Op, O); - return; - } - O << "[" << getRegisterName(MO1.getReg()); if (!MO2.getReg()) { @@ -215,6 +210,52 @@ O << "]"; } +void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, + raw_ostream &O) { + const MCOperand &MO1 = MI->getOperand(Op); + const MCOperand &MO2 = MI->getOperand(Op+1); + const MCOperand &MO3 = MI->getOperand(Op+2); + + O << "[" << getRegisterName(MO1.getReg()) << "], "; + + if (!MO2.getReg()) { + unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); + O << '#' + << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) + << ImmOffs; + return; + } + + O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) + << getRegisterName(MO2.getReg()); + + if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) + O << ", " + << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) + << " #" << ShImm; +} + +void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, + raw_ostream &O) { + const MCOperand &MO1 = MI->getOperand(Op); + + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. + printOperand(MI, Op, O); + return; + } + + unsigned Opcode = MI->getOpcode(); + const TargetInstrDesc &Desc = TM.getInstrInfo()->get(Opcode); + uint64_t TSFlags = Desc.TSFlags; + unsigned IdxMode = (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; + + if (IdxMode == ARMII::IndexModePost) { + printAM2PostIndexOp(MI, Op, O); + return; + } + printAM2PreOrOffsetIndexOp(MI, Op, O); +} + void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) { Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=128585&r1=128584&r2=128585&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Wed Mar 30 18:32:32 2011 @@ -22,9 +22,11 @@ class TargetMachine; class ARMInstPrinter : public MCInstPrinter { +private: + TargetMachine &TM; public: - ARMInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI) - : MCInstPrinter(MAI) {} + ARMInstPrinter(TargetMachine &_TM, const MCAsmInfo &MAI) + : MCInstPrinter(MAI), TM(_TM) {} virtual void printInst(const MCInst *MI, raw_ostream &O); virtual StringRef getOpcodeName(unsigned Opcode) const; @@ -42,7 +44,11 @@ void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, + raw_ostream &O); void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); Added: llvm/trunk/test/MC/ARM/arm_addrmode2.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128585&view=auto ============================================================================== --- llvm/trunk/test/MC/ARM/arm_addrmode2.s (added) +++ llvm/trunk/test/MC/ARM/arm_addrmode2.s Wed Mar 30 18:32:32 2011 @@ -0,0 +1,34 @@ +@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | FileCheck %s + +@ Post-indexed +@ CHECK: ldrt r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6] +@ CHECK: ldrt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6] +@ CHECK: ldrt r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4] +@ CHECK: ldrbt r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6] +@ CHECK: ldrbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6] +@ CHECK: ldrbt r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4] +@ CHECK: strt r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6] +@ CHECK: strt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6] +@ CHECK: strt r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4] +@ CHECK: strbt r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6] +@ CHECK: strbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6] +@ CHECK: strbt r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4] + ldrt r1, [r0], r2 + ldrt r1, [r0], r2, lsr #3 + ldrt r1, [r0], #4 + ldrbt r1, [r0], r2 + ldrbt r1, [r0], r2, lsr #3 + ldrbt r1, [r0], #4 + strt r1, [r0], r2 + strt r1, [r0], r2, lsr #3 + strt r1, [r0], #4 + strbt r1, [r0], r2 + strbt r1, [r0], r2, lsr #3 + strbt r1, [r0], #4 + +@ Pre-indexed +@ CHECK: ldr r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7] +@ CHECK: ldrb r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7] + ldr r1, [r0, r2, lsr #3]! + ldrb r1, [r0, r2, lsr #3]! + From evan.cheng at apple.com Wed Mar 30 18:44:13 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 30 Mar 2011 23:44:13 -0000 Subject: [llvm-commits] [llvm] r128586 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/2011-03-30-CreateFixedObjCrash.ll Message-ID: <20110330234414.36AFC2A6C12C@llvm.org> Author: evancheng Date: Wed Mar 30 18:44:13 2011 New Revision: 128586 URL: http://llvm.org/viewvc/llvm-project?rev=128586&view=rev Log: Don't try to create zero-sized stack objects. Added: llvm/trunk/test/CodeGen/X86/2011-03-30-CreateFixedObjCrash.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=128586&r1=128585&r2=128586&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Mar 30 18:44:13 2011 @@ -2391,8 +2391,9 @@ // In case of tail call optimization mark all arguments mutable. Since they // could be overwritten by lowering of arguments in case of a tail call. if (Flags.isByVal()) { - int FI = MFI->CreateFixedObject(Flags.getByValSize(), - VA.getLocMemOffset(), false); + unsigned Bytes = Flags.getByValSize(); + if (Bytes == 0) Bytes = 1; // Don't create zero-sized stack objects. + int FI = MFI->CreateFixedObject(Bytes, VA.getLocMemOffset(), false); InVals.push_back(DAG.getFrameIndex(FI, getPointerTy())); } else { int FI = MFI->CreateFixedObject(VA.getLocVT().getSizeInBits()/8, Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=128586&r1=128585&r2=128586&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Mar 30 18:44:13 2011 @@ -1639,8 +1639,9 @@ // In case of tail call optimization mark all arguments mutable. Since they // could be overwritten by lowering of arguments in case of a tail call. if (Flags.isByVal()) { - int FI = MFI->CreateFixedObject(Flags.getByValSize(), - VA.getLocMemOffset(), isImmutable); + unsigned Bytes = Flags.getByValSize(); + if (Bytes == 0) Bytes = 1; // Don't create zero-sized stack objects. + int FI = MFI->CreateFixedObject(Bytes, VA.getLocMemOffset(), isImmutable); return DAG.getFrameIndex(FI, getPointerTy()); } else { int FI = MFI->CreateFixedObject(ValVT.getSizeInBits()/8, Added: llvm/trunk/test/CodeGen/X86/2011-03-30-CreateFixedObjCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2011-03-30-CreateFixedObjCrash.ll?rev=128586&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2011-03-30-CreateFixedObjCrash.ll (added) +++ llvm/trunk/test/CodeGen/X86/2011-03-30-CreateFixedObjCrash.ll Wed Mar 30 18:44:13 2011 @@ -0,0 +1,10 @@ +; RUN: llc < %s -march=x86 + +; rdar://7983260 + +%struct.T0 = type {} + +define void @fn4(%struct.T0* byval %arg0) nounwind ssp { +entry: + ret void +} From resistor at mac.com Wed Mar 30 18:45:29 2011 From: resistor at mac.com (Owen Anderson) Date: Wed, 30 Mar 2011 23:45:29 -0000 Subject: [llvm-commits] [llvm] r128587 - in /llvm/trunk/lib/Target/ARM: ARMInstrFormats.td ARMInstrNEON.td Message-ID: <20110330234529.81DCE2A6C12C@llvm.org> Author: resistor Date: Wed Mar 30 18:45:29 2011 New Revision: 128587 URL: http://llvm.org/viewvc/llvm-project?rev=128587&view=rev Log: Somehow we managed to forget to encode the lane index for a large swathe of NEON instructions. With this fix, the entire test-suite passes with the Thumb integrated assembler. Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128587&r1=128586&r2=128587&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Wed Mar 30 18:45:29 2011 @@ -1682,7 +1682,8 @@ } // NEON 3 vector register format. -class N3V op21_20, bits<4> op11_8, bit op6, bit op4, + +class N3VCommon op21_20, bits<4> op11_8, bit op6, bit op4, dag oops, dag iops, Format f, InstrItinClass itin, string opc, string dt, string asm, string cstr, list pattern> : NDataI { @@ -1692,6 +1693,13 @@ let Inst{11-8} = op11_8; let Inst{6} = op6; let Inst{4} = op4; +} + +class N3V op21_20, bits<4> op11_8, bit op6, bit op4, + dag oops, dag iops, Format f, InstrItinClass itin, + string opc, string dt, string asm, string cstr, list pattern> + : N3VCommon { // Instruction operands. bits<5> Vd; @@ -1706,6 +1714,47 @@ let Inst{5} = Vm{4}; } +class N3VLane32 op21_20, bits<4> op11_8, bit op6, bit op4, + dag oops, dag iops, Format f, InstrItinClass itin, + string opc, string dt, string asm, string cstr, list pattern> + : N3VCommon { + + // Instruction operands. + bits<5> Vd; + bits<5> Vn; + bits<5> Vm; + bit lane; + + let Inst{15-12} = Vd{3-0}; + let Inst{22} = Vd{4}; + let Inst{19-16} = Vn{3-0}; + let Inst{7} = Vn{4}; + let Inst{3-0} = Vm{3-0}; + let Inst{5} = lane; +} + +class N3VLane16 op21_20, bits<4> op11_8, bit op6, bit op4, + dag oops, dag iops, Format f, InstrItinClass itin, + string opc, string dt, string asm, string cstr, list pattern> + : N3VCommon { + + // Instruction operands. + bits<5> Vd; + bits<5> Vn; + bits<5> Vm; + bits<2> lane; + + let Inst{15-12} = Vd{3-0}; + let Inst{22} = Vd{4}; + let Inst{19-16} = Vn{3-0}; + let Inst{7} = Vn{4}; + let Inst{2-0} = Vm{2-0}; + let Inst{5} = lane{1}; + let Inst{3} = lane{0}; +} + // Same as N3V except it doesn't have a data type suffix. class N3VX op21_20, bits<4> op11_8, bit op6, bit op4, Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=128587&r1=128586&r2=128587&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Wed Mar 30 18:45:29 2011 @@ -1799,7 +1799,7 @@ class N3VDSL op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp> - : N3V<0, 1, op21_20, op11_8, 1, 0, + : N3VLane32<0, 1, op21_20, op11_8, 1, 0, (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", [(set (Ty DPR:$Vd), @@ -1809,7 +1809,7 @@ } class N3VDSL16 op21_20, bits<4> op11_8, string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp> - : N3V<0, 1, op21_20, op11_8, 1, 0, + : N3VLane16<0, 1, op21_20, op11_8, 1, 0, (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), NVMulSLFrm, IIC_VMULi16D, OpcodeStr, Dt,"$Vd, $Vn, $Vm[$lane]","", [(set (Ty DPR:$Vd), @@ -1839,7 +1839,7 @@ class N3VQSL op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, SDNode ShOp> - : N3V<1, 1, op21_20, op11_8, 1, 0, + : N3VLane32<1, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", [(set (ResTy QPR:$Vd), @@ -1850,7 +1850,7 @@ } class N3VQSL16 op21_20, bits<4> op11_8, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, SDNode ShOp> - : N3V<1, 1, op21_20, op11_8, 1, 0, + : N3VLane16<1, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), NVMulSLFrm, IIC_VMULi16Q, OpcodeStr, Dt,"$Vd, $Vn, $Vm[$lane]","", [(set (ResTy QPR:$Vd), @@ -1872,7 +1872,7 @@ } class N3VDIntSL op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty, Intrinsic IntOp> - : N3V<0, 1, op21_20, op11_8, 1, 0, + : N3VLane32<0, 1, op21_20, op11_8, 1, 0, (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", [(set (Ty DPR:$Vd), @@ -1883,7 +1883,7 @@ } class N3VDIntSL16 op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty, Intrinsic IntOp> - : N3V<0, 1, op21_20, op11_8, 1, 0, + : N3VLane16<0, 1, op21_20, op11_8, 1, 0, (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", [(set (Ty DPR:$Vd), @@ -1913,7 +1913,7 @@ class N3VQIntSL op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, Intrinsic IntOp> - : N3V<1, 1, op21_20, op11_8, 1, 0, + : N3VLane32<1, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", [(set (ResTy QPR:$Vd), @@ -1925,7 +1925,7 @@ class N3VQIntSL16 op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, Intrinsic IntOp> - : N3V<1, 1, op21_20, op11_8, 1, 0, + : N3VLane16<1, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", [(set (ResTy QPR:$Vd), @@ -1957,7 +1957,7 @@ class N3VDMulOpSL op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp> - : N3V<0, 1, op21_20, op11_8, 1, 0, + : N3VLane32<0, 1, op21_20, op11_8, 1, 0, (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), NVMulSLFrm, itin, @@ -1970,7 +1970,7 @@ class N3VDMulOpSL16 op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty, SDNode MulOp, SDNode ShOp> - : N3V<0, 1, op21_20, op11_8, 1, 0, + : N3VLane16<0, 1, op21_20, op11_8, 1, 0, (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), NVMulSLFrm, itin, @@ -1992,7 +1992,7 @@ class N3VQMulOpSL op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, SDPatternOperator MulOp, SDPatternOperator ShOp> - : N3V<1, 1, op21_20, op11_8, 1, 0, + : N3VLane32<1, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), NVMulSLFrm, itin, @@ -2006,7 +2006,7 @@ string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, SDNode MulOp, SDNode ShOp> - : N3V<1, 1, op21_20, op11_8, 1, 0, + : N3VLane16<1, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), NVMulSLFrm, itin, @@ -2067,7 +2067,7 @@ class N3VLMulOpSL op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode> - : N3V op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode> - : N3V op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, Intrinsic IntOp> - : N3V op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, Intrinsic IntOp> - : N3V op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType TyQ, ValueType TyD, SDNode OpNode> - : N3V op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType TyQ, ValueType TyD, SDNode OpNode> - : N3V op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, Intrinsic IntOp> - : N3V op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, Intrinsic IntOp> - : N3V Author: bwilson Date: Wed Mar 30 19:09:35 2011 New Revision: 128591 URL: http://llvm.org/viewvc/llvm-project?rev=128591&view=rev Log: Use intrinsics for Neon vmull operations. Radar 9208957. Modified: llvm/trunk/utils/TableGen/NeonEmitter.cpp llvm/trunk/utils/TableGen/NeonEmitter.h Modified: llvm/trunk/utils/TableGen/NeonEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/NeonEmitter.cpp?rev=128591&r1=128590&r2=128591&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/NeonEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/NeonEmitter.cpp Wed Mar 30 19:09:35 2011 @@ -608,16 +608,9 @@ case OpMul: s += "__a * __b;"; break; - case OpMullN: - s += Extend(typestr, "__a") + " * " + - Extend(typestr, Duplicate(nElts << (int)quad, typestr, "__b")) + ";"; - break; case OpMullLane: - s += Extend(typestr, "__a") + " * " + - Extend(typestr, SplatLane(nElts, "__b", "__c")) + ";"; - break; - case OpMull: - s += Extend(typestr, "__a") + " * " + Extend(typestr, "__b") + ";"; + s += MangleName("vmull", typestr, ClassS) + "(__a, " + + SplatLane(nElts, "__b", "__c") + ");"; break; case OpMlaN: s += "__a + (__b * " + Duplicate(nElts, typestr, "__c") + ");"; @@ -629,16 +622,15 @@ s += "__a + (__b * __c);"; break; case OpMlalN: - s += "__a + (" + Extend(typestr, "__b") + " * " + - Extend(typestr, Duplicate(nElts, typestr, "__c")) + ");"; + s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " + + Duplicate(nElts, typestr, "__c") + ");"; break; case OpMlalLane: - s += "__a + (" + Extend(typestr, "__b") + " * " + - Extend(typestr, SplatLane(nElts, "__c", "__d")) + ");"; + s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " + + SplatLane(nElts, "__c", "__d") + ");"; break; case OpMlal: - s += "__a + (" + Extend(typestr, "__b") + " * " + - Extend(typestr, "__c") + ");"; + s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, __c);"; break; case OpMlsN: s += "__a - (__b * " + Duplicate(nElts, typestr, "__c") + ");"; @@ -650,16 +642,15 @@ s += "__a - (__b * __c);"; break; case OpMlslN: - s += "__a - (" + Extend(typestr, "__b") + " * " + - Extend(typestr, Duplicate(nElts, typestr, "__c")) + ");"; + s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " + + Duplicate(nElts, typestr, "__c") + ");"; break; case OpMlslLane: - s += "__a - (" + Extend(typestr, "__b") + " * " + - Extend(typestr, SplatLane(nElts, "__c", "__d")) + ");"; + s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " + + SplatLane(nElts, "__c", "__d") + ");"; break; case OpMlsl: - s += "__a - (" + Extend(typestr, "__b") + " * " + - Extend(typestr, "__c") + ");"; + s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, __c);"; break; case OpQDMullLane: s += MangleName("vqdmull", typestr, ClassS) + "(__a, " + @@ -1148,17 +1139,20 @@ std::vector RV = Records.getAllDerivedDefinitions("Inst"); - // Emit vmovl and vabd intrinsics first so they can be used by other + // Emit vmovl, vmull and vabd intrinsics first so they can be used by other // intrinsics. (Some of the saturating multiply instructions are also // used to implement the corresponding "_lane" variants, but tablegen // sorts the records into alphabetical order so that the "_lane" variants // come after the intrinsics they use.) emitIntrinsic(OS, Records.getDef("VMOVL")); + emitIntrinsic(OS, Records.getDef("VMULL")); emitIntrinsic(OS, Records.getDef("VABD")); for (unsigned i = 0, e = RV.size(); i != e; ++i) { Record *R = RV[i]; - if (R->getName() != "VMOVL" && R->getName() != "VABD") + if (R->getName() != "VMOVL" && + R->getName() != "VMULL" && + R->getName() != "VABD") emitIntrinsic(OS, R); } Modified: llvm/trunk/utils/TableGen/NeonEmitter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/NeonEmitter.h?rev=128591&r1=128590&r2=128591&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/NeonEmitter.h (original) +++ llvm/trunk/utils/TableGen/NeonEmitter.h Wed Mar 30 19:09:35 2011 @@ -30,13 +30,11 @@ OpSubl, OpSubw, OpMul, - OpMull, OpMla, OpMlal, OpMls, OpMlsl, OpMulN, - OpMullN, OpMlaN, OpMlsN, OpMlalN, @@ -105,13 +103,11 @@ OpMap["OP_SUBL"] = OpSubl; OpMap["OP_SUBW"] = OpSubw; OpMap["OP_MUL"] = OpMul; - OpMap["OP_MULL"] = OpMull; OpMap["OP_MLA"] = OpMla; OpMap["OP_MLAL"] = OpMlal; OpMap["OP_MLS"] = OpMls; OpMap["OP_MLSL"] = OpMlsl; OpMap["OP_MUL_N"] = OpMulN; - OpMap["OP_MULL_N"]= OpMullN; OpMap["OP_MLA_N"] = OpMlaN; OpMap["OP_MLS_N"] = OpMlsN; OpMap["OP_MLAL_N"] = OpMlalN; From evan.cheng at apple.com Wed Mar 30 19:20:31 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 30 Mar 2011 17:20:31 -0700 Subject: [llvm-commits] [llvm] r128587 - in /llvm/trunk/lib/Target/ARM: ARMInstrFormats.td ARMInstrNEON.td In-Reply-To: <20110330234529.81DCE2A6C12C@llvm.org> References: <20110330234529.81DCE2A6C12C@llvm.org> Message-ID: <3B2D9067-C38C-43F5-8663-5AE222912797@apple.com> On Mar 30, 2011, at 4:45 PM, Owen Anderson wrote: > Author: resistor > Date: Wed Mar 30 18:45:29 2011 > New Revision: 128587 > > URL: http://llvm.org/viewvc/llvm-project?rev=128587&view=rev > Log: > Somehow we managed to forget to encode the lane index for a large swathe of NEON instructions. With this fix, the entire test-suite passes with the Thumb integrated assembler. Very nice! Evan > > Modified: > llvm/trunk/lib/Target/ARM/ARMInstrFormats.td > llvm/trunk/lib/Target/ARM/ARMInstrNEON.td > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128587&r1=128586&r2=128587&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Wed Mar 30 18:45:29 2011 > @@ -1682,7 +1682,8 @@ > } > > // NEON 3 vector register format. > -class N3V op21_20, bits<4> op11_8, bit op6, bit op4, > + > +class N3VCommon op21_20, bits<4> op11_8, bit op6, bit op4, > dag oops, dag iops, Format f, InstrItinClass itin, > string opc, string dt, string asm, string cstr, list pattern> > : NDataI { > @@ -1692,6 +1693,13 @@ > let Inst{11-8} = op11_8; > let Inst{6} = op6; > let Inst{4} = op4; > +} > + > +class N3V op21_20, bits<4> op11_8, bit op6, bit op4, > + dag oops, dag iops, Format f, InstrItinClass itin, > + string opc, string dt, string asm, string cstr, list pattern> > + : N3VCommon + oops, iops, f, itin, opc, dt, asm, cstr, pattern> { > > // Instruction operands. > bits<5> Vd; > @@ -1706,6 +1714,47 @@ > let Inst{5} = Vm{4}; > } > > +class N3VLane32 op21_20, bits<4> op11_8, bit op6, bit op4, > + dag oops, dag iops, Format f, InstrItinClass itin, > + string opc, string dt, string asm, string cstr, list pattern> > + : N3VCommon + oops, iops, f, itin, opc, dt, asm, cstr, pattern> { > + > + // Instruction operands. > + bits<5> Vd; > + bits<5> Vn; > + bits<5> Vm; > + bit lane; > + > + let Inst{15-12} = Vd{3-0}; > + let Inst{22} = Vd{4}; > + let Inst{19-16} = Vn{3-0}; > + let Inst{7} = Vn{4}; > + let Inst{3-0} = Vm{3-0}; > + let Inst{5} = lane; > +} > + > +class N3VLane16 op21_20, bits<4> op11_8, bit op6, bit op4, > + dag oops, dag iops, Format f, InstrItinClass itin, > + string opc, string dt, string asm, string cstr, list pattern> > + : N3VCommon + oops, iops, f, itin, opc, dt, asm, cstr, pattern> { > + > + // Instruction operands. > + bits<5> Vd; > + bits<5> Vn; > + bits<5> Vm; > + bits<2> lane; > + > + let Inst{15-12} = Vd{3-0}; > + let Inst{22} = Vd{4}; > + let Inst{19-16} = Vn{3-0}; > + let Inst{7} = Vn{4}; > + let Inst{2-0} = Vm{2-0}; > + let Inst{5} = lane{1}; > + let Inst{3} = lane{0}; > +} > + > // Same as N3V except it doesn't have a data type suffix. > class N3VX op21_20, bits<4> op11_8, bit op6, > bit op4, > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=128587&r1=128586&r2=128587&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Wed Mar 30 18:45:29 2011 > @@ -1799,7 +1799,7 @@ > class N3VDSL op21_20, bits<4> op11_8, > InstrItinClass itin, string OpcodeStr, string Dt, > ValueType Ty, SDNode ShOp> > - : N3V<0, 1, op21_20, op11_8, 1, 0, > + : N3VLane32<0, 1, op21_20, op11_8, 1, 0, > (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", > [(set (Ty DPR:$Vd), > @@ -1809,7 +1809,7 @@ > } > class N3VDSL16 op21_20, bits<4> op11_8, > string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp> > - : N3V<0, 1, op21_20, op11_8, 1, 0, > + : N3VLane16<0, 1, op21_20, op11_8, 1, 0, > (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), > NVMulSLFrm, IIC_VMULi16D, OpcodeStr, Dt,"$Vd, $Vn, $Vm[$lane]","", > [(set (Ty DPR:$Vd), > @@ -1839,7 +1839,7 @@ > class N3VQSL op21_20, bits<4> op11_8, > InstrItinClass itin, string OpcodeStr, string Dt, > ValueType ResTy, ValueType OpTy, SDNode ShOp> > - : N3V<1, 1, op21_20, op11_8, 1, 0, > + : N3VLane32<1, 1, op21_20, op11_8, 1, 0, > (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", > [(set (ResTy QPR:$Vd), > @@ -1850,7 +1850,7 @@ > } > class N3VQSL16 op21_20, bits<4> op11_8, string OpcodeStr, string Dt, > ValueType ResTy, ValueType OpTy, SDNode ShOp> > - : N3V<1, 1, op21_20, op11_8, 1, 0, > + : N3VLane16<1, 1, op21_20, op11_8, 1, 0, > (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), > NVMulSLFrm, IIC_VMULi16Q, OpcodeStr, Dt,"$Vd, $Vn, $Vm[$lane]","", > [(set (ResTy QPR:$Vd), > @@ -1872,7 +1872,7 @@ > } > class N3VDIntSL op21_20, bits<4> op11_8, InstrItinClass itin, > string OpcodeStr, string Dt, ValueType Ty, Intrinsic IntOp> > - : N3V<0, 1, op21_20, op11_8, 1, 0, > + : N3VLane32<0, 1, op21_20, op11_8, 1, 0, > (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", > [(set (Ty DPR:$Vd), > @@ -1883,7 +1883,7 @@ > } > class N3VDIntSL16 op21_20, bits<4> op11_8, InstrItinClass itin, > string OpcodeStr, string Dt, ValueType Ty, Intrinsic IntOp> > - : N3V<0, 1, op21_20, op11_8, 1, 0, > + : N3VLane16<0, 1, op21_20, op11_8, 1, 0, > (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", > [(set (Ty DPR:$Vd), > @@ -1913,7 +1913,7 @@ > class N3VQIntSL op21_20, bits<4> op11_8, InstrItinClass itin, > string OpcodeStr, string Dt, > ValueType ResTy, ValueType OpTy, Intrinsic IntOp> > - : N3V<1, 1, op21_20, op11_8, 1, 0, > + : N3VLane32<1, 1, op21_20, op11_8, 1, 0, > (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", > [(set (ResTy QPR:$Vd), > @@ -1925,7 +1925,7 @@ > class N3VQIntSL16 op21_20, bits<4> op11_8, InstrItinClass itin, > string OpcodeStr, string Dt, > ValueType ResTy, ValueType OpTy, Intrinsic IntOp> > - : N3V<1, 1, op21_20, op11_8, 1, 0, > + : N3VLane16<1, 1, op21_20, op11_8, 1, 0, > (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", > [(set (ResTy QPR:$Vd), > @@ -1957,7 +1957,7 @@ > class N3VDMulOpSL op21_20, bits<4> op11_8, InstrItinClass itin, > string OpcodeStr, string Dt, > ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp> > - : N3V<0, 1, op21_20, op11_8, 1, 0, > + : N3VLane32<0, 1, op21_20, op11_8, 1, 0, > (outs DPR:$Vd), > (ins DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, > @@ -1970,7 +1970,7 @@ > class N3VDMulOpSL16 op21_20, bits<4> op11_8, InstrItinClass itin, > string OpcodeStr, string Dt, > ValueType Ty, SDNode MulOp, SDNode ShOp> > - : N3V<0, 1, op21_20, op11_8, 1, 0, > + : N3VLane16<0, 1, op21_20, op11_8, 1, 0, > (outs DPR:$Vd), > (ins DPR:$src1, DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, > @@ -1992,7 +1992,7 @@ > class N3VQMulOpSL op21_20, bits<4> op11_8, InstrItinClass itin, > string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, > SDPatternOperator MulOp, SDPatternOperator ShOp> > - : N3V<1, 1, op21_20, op11_8, 1, 0, > + : N3VLane32<1, 1, op21_20, op11_8, 1, 0, > (outs QPR:$Vd), > (ins QPR:$src1, QPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, > @@ -2006,7 +2006,7 @@ > string OpcodeStr, string Dt, > ValueType ResTy, ValueType OpTy, > SDNode MulOp, SDNode ShOp> > - : N3V<1, 1, op21_20, op11_8, 1, 0, > + : N3VLane16<1, 1, op21_20, op11_8, 1, 0, > (outs QPR:$Vd), > (ins QPR:$src1, QPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, > @@ -2067,7 +2067,7 @@ > class N3VLMulOpSL op21_20, bits<4> op11_8, > InstrItinClass itin, string OpcodeStr, string Dt, > ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode> > - : N3V + : N3VLane32 (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, > OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "$src1 = $Vd", > @@ -2079,7 +2079,7 @@ > class N3VLMulOpSL16 op21_20, bits<4> op11_8, > InstrItinClass itin, string OpcodeStr, string Dt, > ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode> > - : N3V + : N3VLane16 (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, > OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "$src1 = $Vd", > @@ -2114,7 +2114,7 @@ > class N3VLInt3SL op21_20, bits<4> op11_8, InstrItinClass itin, > string OpcodeStr, string Dt, > ValueType ResTy, ValueType OpTy, Intrinsic IntOp> > - : N3V + : N3VLane32 (outs QPR:$Vd), > (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, > @@ -2127,7 +2127,7 @@ > class N3VLInt3SL16 op21_20, bits<4> op11_8, > InstrItinClass itin, string OpcodeStr, string Dt, > ValueType ResTy, ValueType OpTy, Intrinsic IntOp> > - : N3V + : N3VLane16 (outs QPR:$Vd), > (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, > @@ -2162,7 +2162,7 @@ > class N3VLSL op21_20, bits<4> op11_8, > InstrItinClass itin, string OpcodeStr, string Dt, > ValueType TyQ, ValueType TyD, SDNode OpNode> > - : N3V + : N3VLane32 (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", > [(set QPR:$Vd, > @@ -2171,7 +2171,7 @@ > class N3VLSL16 op21_20, bits<4> op11_8, > InstrItinClass itin, string OpcodeStr, string Dt, > ValueType TyQ, ValueType TyD, SDNode OpNode> > - : N3V + : N3VLane16 (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", > [(set QPR:$Vd, > @@ -2217,7 +2217,7 @@ > class N3VLIntSL op21_20, bits<4> op11_8, InstrItinClass itin, > string OpcodeStr, string Dt, > ValueType ResTy, ValueType OpTy, Intrinsic IntOp> > - : N3V + : N3VLane32 (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", > [(set (ResTy QPR:$Vd), > @@ -2227,7 +2227,7 @@ > class N3VLIntSL16 op21_20, bits<4> op11_8, > InstrItinClass itin, string OpcodeStr, string Dt, > ValueType ResTy, ValueType OpTy, Intrinsic IntOp> > - : N3V + : N3VLane16 (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane), > NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "", > [(set (ResTy QPR:$Vd), > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From nicholas at mxc.ca Wed Mar 30 19:23:57 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 31 Mar 2011 00:23:57 -0000 Subject: [llvm-commits] [llvm] r128594 - /llvm/trunk/utils/GenLibDeps.pl Message-ID: <20110331002357.A99252A6C12C@llvm.org> Author: nicholas Date: Wed Mar 30 19:23:57 2011 New Revision: 128594 URL: http://llvm.org/viewvc/llvm-project?rev=128594&view=rev Log: Fix typo in generated HTML. Modified: llvm/trunk/utils/GenLibDeps.pl Modified: llvm/trunk/utils/GenLibDeps.pl URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/GenLibDeps.pl?rev=128594&r1=128593&r2=128594&view=diff ============================================================================== --- llvm/trunk/utils/GenLibDeps.pl (original) +++ llvm/trunk/utils/GenLibDeps.pl Wed Mar 30 19:23:57 2011 @@ -202,7 +202,7 @@ print "$lib:"; if ($WHY) { print "\n"; } } else { - print "
    $lib
      \n"; + print "
      $lib
        \n"; } open UNDEFS, "$nmPath -u $Directory/$lib | sed -e 's/^[ 0]* U //' | sort | uniq |"; From nlewycky at google.com Wed Mar 30 19:38:29 2011 From: nlewycky at google.com (Nick Lewycky) Date: Wed, 30 Mar 2011 17:38:29 -0700 Subject: [llvm-commits] [llvm] r128585 - in /llvm/trunk: lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/InstPrinter/A Message-ID: On 30 March 2011 16:32, Bruno Cardoso Lopes wrote: > Author: bruno > Date: Wed Mar 30 18:32:32 2011 > New Revision: 128585 > > URL: http://llvm.org/viewvc/llvm-project?rev=128585&view=rev > Log: > - Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and > {STR,LDC}{2}_PRE. > - Fixed the encoding in some places. > - Some of those instructions were using am2offset and now use addrmode2. > Codegen isn't affected, instructions which use SelectAddrMode2Offset were > not > touched. > - Teach printAddrMode2Operand to check by the addressing mode which index > mode to print. > - This is a work in progress, more work to come. The idea is to change > places > which use am2offset to use addrmode2 instead, as to unify assembly parser. > - Add testcases for assembly parser > > Added: > llvm/trunk/test/MC/ARM/arm_addrmode2.s > Modified: > llvm/trunk/lib/Target/ARM/ARMBaseInfo.h > llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h > llvm/trunk/lib/Target/ARM/ARMInstrFormats.td > llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp > llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp > llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=128585&r1=128584&r2=128585&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Wed Mar 30 18:32:32 2011 > @@ -200,6 +200,51 @@ > } > > namespace ARMII { > + > + /// ARM Addressing Modes > + enum AddrMode { > + AddrModeNone = 0, > + AddrMode1 = 1, > + AddrMode2 = 2, > + AddrMode3 = 3, > + AddrMode4 = 4, > + AddrMode5 = 5, > + AddrMode6 = 6, > + AddrModeT1_1 = 7, > + AddrModeT1_2 = 8, > + AddrModeT1_4 = 9, > + AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data > + AddrModeT2_i12 = 11, > + AddrModeT2_i8 = 12, > + AddrModeT2_so = 13, > + AddrModeT2_pc = 14, // +/- i12 for pc relative data > + AddrModeT2_i8s4 = 15, // i8 * 4 > + AddrMode_i12 = 16 > + }; > + > + inline static const char *AddrModeToString(AddrMode addrmode) { > + switch (addrmode) { > + default: llvm_unreachable("Unknown memory operation"); > + case AddrModeNone: return "AddrModeNone"; > + case AddrMode1: return "AddrMode1"; > + case AddrMode2: return "AddrMode2"; > + case AddrMode3: return "AddrMode3"; > + case AddrMode4: return "AddrMode4"; > + case AddrMode5: return "AddrMode5"; > + case AddrMode6: return "AddrMode6"; > + case AddrModeT1_1: return "AddrModeT1_1"; > + case AddrModeT1_2: return "AddrModeT1_2"; > + case AddrModeT1_4: return "AddrModeT1_4"; > + case AddrModeT1_s: return "AddrModeT1_s"; > + case AddrModeT2_i12: return "AddrModeT2_i12"; > + case AddrModeT2_i8: return "AddrModeT2_i8"; > + case AddrModeT2_so: return "AddrModeT2_so"; > + case AddrModeT2_pc: return "AddrModeT2_pc"; > + case AddrModeT2_i8s4: return "AddrModeT2_i8s4"; > + case AddrMode_i12: return "AddrMode_i12"; > + } > + } > + > /// Target Operand Flag enum. > enum TOF { > > //===------------------------------------------------------------------===// > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=128585&r1=128584&r2=128585&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Wed Mar 30 18:32:32 2011 > @@ -34,25 +34,7 @@ > > > //===------------------------------------------------------------------===// > // This four-bit field describes the addressing mode used. > - > - AddrModeMask = 0x1f, > - AddrModeNone = 0, > - AddrMode1 = 1, > - AddrMode2 = 2, > - AddrMode3 = 3, > - AddrMode4 = 4, > - AddrMode5 = 5, > - AddrMode6 = 6, > - AddrModeT1_1 = 7, > - AddrModeT1_2 = 8, > - AddrModeT1_4 = 9, > - AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data > - AddrModeT2_i12 = 11, > - AddrModeT2_i8 = 12, > - AddrModeT2_so = 13, > - AddrModeT2_pc = 14, // +/- i12 for pc relative data > - AddrModeT2_i8s4 = 15, // i8 * 4 > - AddrMode_i12 = 16, > + AddrModeMask = 0x1f, // The AddrMode enums are declared in > ARMBaseInfo.h > > // Size* - Flags to keep track of the size of an instruction. > SizeShift = 5, > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128585&r1=128584&r2=128585&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Wed Mar 30 18:32:32 2011 > @@ -515,15 +515,15 @@ > : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, > pattern> { > // AM2 store w/ two operands: (GPR, am2offset) > + // {17-14} Rn > // {13} 1 == Rm, 0 == imm12 > // {12} isAdd > // {11-0} imm12/Rm > - bits<14> offset; > - bits<4> Rn; > - let Inst{25} = offset{13}; > - let Inst{23} = offset{12}; > - let Inst{19-16} = Rn; > - let Inst{11-0} = offset{11-0}; > + bits<18> addr; > + let Inst{25} = addr{13}; > + let Inst{23} = addr{12}; > + let Inst{19-16} = addr{17-14}; > + let Inst{11-0} = addr{11-0}; > } > > // addrmode3 instructions > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128585&r1=128584&r2=128585&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed Mar 30 18:32:32 2011 > @@ -498,6 +498,12 @@ > let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); > } > > +def MemMode2AsmOperand : AsmOperandClass { > + let Name = "MemMode2"; > + let SuperClasses = []; > + let ParserMethod = "tryParseMemMode2Operand"; > +} > + > // addrmode2 := reg +/- imm12 > // := reg +/- reg shop imm > // > @@ -505,6 +511,7 @@ > ComplexPattern { > let EncoderMethod = "getAddrMode2OpValue"; > let PrintMethod = "printAddrMode2Operand"; > + let ParserMatchClass = MemMode2AsmOperand; > let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); > } > > @@ -1656,6 +1663,7 @@ > let Inst{23} = addr{12}; > let Inst{19-16} = addr{17-14}; > let Inst{11-0} = addr{11-0}; > + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > } > def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), > (ins GPR:$Rn, am2offset:$offset), > @@ -1714,17 +1722,35 @@ > > // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. > let mayLoad = 1, neverHasSideEffects = 1 in { > -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb), > - (ins GPR:$base, am2offset:$offset), IndexModePost, > - LdFrm, IIC_iLoad_ru, > - "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", > []> { > +def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb), > + (ins addrmode2:$addr), IndexModePost, LdFrm, > IIC_iLoad_ru, > + "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { > + // {17-14} Rn > + // {13} 1 == Rm, 0 == imm12 > + // {12} isAdd > + // {11-0} imm12/Rm > + bits<18> addr; > + let Inst{25} = addr{13}; > + let Inst{23} = addr{12}; > let Inst{21} = 1; // overwrite > -} > -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb), > - (ins GPR:$base, am2offset:$offset), IndexModePost, > - LdFrm, IIC_iLoad_bh_ru, > - "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", > []> { > + let Inst{19-16} = addr{17-14}; > + let Inst{11-0} = addr{11-0}; > + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > +} > +def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), > + (ins addrmode2:$addr), IndexModePost, LdFrm, > IIC_iLoad_bh_ru, > + "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { > + // {17-14} Rn > + // {13} 1 == Rm, 0 == imm12 > + // {12} isAdd > + // {11-0} imm12/Rm > + bits<18> addr; > + let Inst{25} = addr{13}; > + let Inst{23} = addr{12}; > let Inst{21} = 1; // overwrite > + let Inst{19-16} = addr{17-14}; > + let Inst{11-0} = addr{11-0}; > + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > } > def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb), > (ins GPR:$base, am3offset:$offset), IndexModePost, > @@ -1818,20 +1844,20 @@ > > // STRT, STRBT, and STRHT are for disassembly only. > > -def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), > - (ins GPR:$Rt, GPR:$Rn,am2offset:$offset), > +def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, > addrmode2:$addr), > IndexModePost, StFrm, IIC_iStore_ru, > - "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", > + "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb", > [/* For disassembly only; pattern left blank */]> { > let Inst{21} = 1; // overwrite > + let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; > } > > -def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), > - (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), > +def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, > addrmode2:$addr), > IndexModePost, StFrm, IIC_iStore_bh_ru, > - "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", > + "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb", > [/* For disassembly only; pattern left blank */]> { > let Inst{21} = 1; // overwrite > + let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; > } > > def STRHT: AI3sthpo<(outs GPR:$base_wb), > @@ -3391,8 +3417,9 @@ > let Inst{23-20} = opc1; > } > > -class ACI > - : I NoItinerary, > +class ACI + IndexMode im = IndexModeNone> > + : I opc, asm, "", [/* For disassembly only; pattern left blank */]> { > let Inst{27-25} = 0b110; > } > @@ -3411,7 +3438,7 @@ > > def _PRE : ACI<(outs), > (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - opc, "\tp$cop, cr$CRd, $addr!"> { > + opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> { > let Inst{31-28} = op31_28; > let Inst{24} = 1; // P = 1 > let Inst{21} = 1; // W = 1 > @@ -3452,7 +3479,7 @@ > > def L_PRE : ACI<(outs), > (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { > + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> { > let Inst{31-28} = op31_28; > let Inst{24} = 1; // P = 1 > let Inst{21} = 1; // W = 1 > > Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128585&r1=128584&r2=128585&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) > +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Wed Mar 30 > 18:32:32 2011 > @@ -48,7 +48,8 @@ > bool TryParseRegisterWithWriteBack(SmallVectorImpl > &); > bool TryParseShiftRegister(SmallVectorImpl &); > bool ParseRegisterList(SmallVectorImpl &); > - bool ParseMemory(SmallVectorImpl &); > + bool ParseMemory(SmallVectorImpl &, > + ARMII::AddrMode AddrMode); > bool ParseOperand(SmallVectorImpl &, StringRef > Mnemonic); > bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); > const MCExpr *ApplyPrefixToExpr(const MCExpr *E, > @@ -95,6 +96,14 @@ > SmallVectorImpl&); > OperandMatchResultTy tryParseMSRMaskOperand( > SmallVectorImpl&); > + OperandMatchResultTy tryParseMemMode2Operand( > + SmallVectorImpl&); > + > + // Asm Match Converter Methods > + bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > + const > SmallVectorImpl &); > + bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > + const > SmallVectorImpl &); > > public: > ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) > @@ -172,6 +181,7 @@ > > /// Combined record for all forms of ARM address expressions. > struct { > + ARMII::AddrMode AddrMode; > unsigned BaseRegNum; > union { > unsigned RegNum; ///< Offset register num, when OffsetIsReg. > @@ -293,7 +303,9 @@ > > /// @name Memory Operand Accessors > /// @{ > - > + ARMII::AddrMode getMemAddrMode() const { > + return Mem.AddrMode; > + } > unsigned getMemBaseRegNum() const { > return Mem.BaseRegNum; > } > @@ -338,6 +350,27 @@ > bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } > bool isMemory() const { return Kind == Memory; } > bool isShifter() const { return Kind == Shifter; } > + bool isMemMode2() const { > + if (getMemAddrMode() != ARMII::AddrMode2) > + return false; > + > + if (getMemOffsetIsReg()) > + return true; > + > + if (getMemNegative() && > + !(getMemPostindexed() || getMemPreindexed())) > + return false; > + > + const MCConstantExpr *CE = dyn_cast(getMemOffset()); > + if (!CE) return false; > + int64_t Value = CE->getValue(); > + > + // The offset must be in the range 0-4095 (imm12). > + if (Value > 4095 || Value < -4095) > + return false; > + > + return true; > + } > bool isMemMode5() const { > if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || > getMemNegative()) > @@ -465,6 +498,46 @@ > "No offset operand support in mode 7"); > } > > + void addMemMode2Operands(MCInst &Inst, unsigned N) const { > + assert(isMemMode2() && "Invalid mode or number of operands!"); > + Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); > + > + if (getMemOffsetIsReg()) { > + Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); > + > + ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : > ARM_AM::add; > + ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; > + int64_t ShiftAmount = 0; > + > + if (getMemOffsetRegShifted()) { > + ShOpc = getMemShiftType(); > + const MCConstantExpr *CE = > + dyn_cast(getMemShiftAmount()); > + ShiftAmount = CE->getValue(); > + } > + > + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, > ShiftAmount, > + ShOpc))); > + return; > + } > + > + // Create a operand placeholder to always yield the same number of > operands. > + Inst.addOperand(MCOperand::CreateReg(0)); > + > + // FIXME: #-0 is encoded differently than #0. Does the parser preserve > + // the difference? > + const MCConstantExpr *CE = dyn_cast(getMemOffset()); > + assert(CE && "Non-constant mode 2 offset operand!"); > + int64_t Offset = CE->getValue(); > + > + if (Offset >= 0) > + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, > + Offset, ARM_AM::no_shift))); > + else > + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, > + -Offset, ARM_AM::no_shift))); > + } > + > void addMemMode5Operands(MCInst &Inst, unsigned N) const { > assert(N == 2 && isMemMode5() && "Invalid number of operands!"); > > @@ -599,9 +672,9 @@ > return Op; > } > > - static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, > - const MCExpr *Offset, int OffsetRegNum, > - bool OffsetRegShifted, > + static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned > BaseRegNum, > + bool OffsetIsReg, const MCExpr *Offset, > + int OffsetRegNum, bool OffsetRegShifted, > enum ARM_AM::ShiftOpc ShiftType, > const MCExpr *ShiftAmount, bool Preindexed, > bool Postindexed, bool Negative, bool > Writeback, > @@ -618,6 +691,7 @@ > "Cannot have expression offset and register offset!"); > > ARMOperand *Op = new ARMOperand(Memory); > + Op->Mem.AddrMode = AddrMode; > Op->Mem.BaseRegNum = BaseRegNum; > Op->Mem.OffsetIsReg = OffsetIsReg; > if (OffsetIsReg) > @@ -689,7 +763,8 @@ > break; > case Memory: > OS << " - << "base:" << getMemBaseRegNum(); > + << "am:" << ARMII::AddrModeToString(getMemAddrMode()) > + << " base:" << getMemBaseRegNum(); > if (getMemOffsetIsReg()) { > OS << " offset: if (getMemOffsetRegShifted()) { > @@ -1132,13 +1207,57 @@ > return MatchOperand_Success; > } > > +/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 > operand. > +ARMAsmParser::OperandMatchResultTy ARMAsmParser:: > +tryParseMemMode2Operand(SmallVectorImpl &Operands) { > + SMLoc S = Parser.getTok().getLoc(); > + const AsmToken &Tok = Parser.getTok(); > + assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\""); > + > + if (ParseMemory(Operands, ARMII::AddrMode2)) > + return MatchOperand_NoMatch; > + > + return MatchOperand_Success; > +} > + > +/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. > +/// Needed here because the Asm Gen Matcher can't handle properly tied > operands > +/// when they refer multiple MIOperands inside a single one. > +bool ARMAsmParser:: > +CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > + const SmallVectorImpl > &Operands) { > + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); > + > + // Create a writeback register dummy placeholder. > + Inst.addOperand(MCOperand::CreateImm(0)); > + > + ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); > + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); > + return true; > +} > + > +/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. > +/// Needed here because the Asm Gen Matcher can't handle properly tied > operands > +/// when they refer multiple MIOperands inside a single one. > +bool ARMAsmParser:: > +CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > + const SmallVectorImpl > &Operands) { > + // Create a writeback register dummy placeholder. > + Inst.addOperand(MCOperand::CreateImm(0)); > + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); > + ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); > + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); > + return true; > +} > + > /// Parse an ARM memory expression, return false if successful else return > true > /// or an error. The first token must be a '[' when called. > /// > /// TODO Only preindexing and postindexing addressing are started, > unindexed > /// with option, etc are still to do. > bool ARMAsmParser:: > -ParseMemory(SmallVectorImpl &Operands) { > +ParseMemory(SmallVectorImpl &Operands, > + ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { > SMLoc S, E; > assert(Parser.getTok().is(AsmToken::LBrac) && > "Token is not a Left Bracket"); > @@ -1231,11 +1350,10 @@ > Offset = MCConstantExpr::Create(0, getContext()); > } > > - Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, > Offset, > - OffsetRegNum, OffsetRegShifted, > - ShiftType, ShiftAmount, > Preindexed, > - Postindexed, Negative, > Writeback, > - S, E)); > + Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, > OffsetIsReg, > + Offset, OffsetRegNum, > OffsetRegShifted, > + ShiftType, ShiftAmount, Preindexed, > + Postindexed, Negative, Writeback, S, > E)); > if (WBOp) > Operands.push_back(WBOp); > > > Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=128585&r1=128584&r2=128585&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original) > +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Wed Mar 30 > 18:32:32 2011 > @@ -14,6 +14,7 @@ > #define DEBUG_TYPE "asm-printer" > #include "ARMBaseInfo.h" > #include "ARMInstPrinter.h" > +#include "ARMInstrInfo.h" > No, you can not do this. This will transitively #include ARMGenRegisterInfo.h.inc which declares "extern QQQQPRClass QQQQPRRegClass;". That causes ARMInstPrinter to have a dependency on ARMCodeGen, causing a cycle. We'll probably revert this patch shortly. Please re-commit once you fix this! Nick > #include "ARMAddressingModes.h" > #include "llvm/MC/MCInst.h" > #include "llvm/MC/MCAsmInfo.h" > @@ -181,18 +182,12 @@ > } > } > > - > -void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, > - raw_ostream &O) { > +void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned > Op, > + raw_ostream &O) { > const MCOperand &MO1 = MI->getOperand(Op); > const MCOperand &MO2 = MI->getOperand(Op+1); > const MCOperand &MO3 = MI->getOperand(Op+2); > > - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. > - printOperand(MI, Op, O); > - return; > - } > - > O << "[" << getRegisterName(MO1.getReg()); > > if (!MO2.getReg()) { > @@ -215,6 +210,52 @@ > O << "]"; > } > > +void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, > + raw_ostream &O) { > + const MCOperand &MO1 = MI->getOperand(Op); > + const MCOperand &MO2 = MI->getOperand(Op+1); > + const MCOperand &MO3 = MI->getOperand(Op+2); > + > + O << "[" << getRegisterName(MO1.getReg()) << "], "; > + > + if (!MO2.getReg()) { > + unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); > + O << '#' > + << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) > + << ImmOffs; > + return; > + } > + > + O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) > + << getRegisterName(MO2.getReg()); > + > + if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) > + O << ", " > + << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) > + << " #" << ShImm; > +} > + > +void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, > + raw_ostream &O) { > + const MCOperand &MO1 = MI->getOperand(Op); > + > + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. > + printOperand(MI, Op, O); > + return; > + } > + > + unsigned Opcode = MI->getOpcode(); > + const TargetInstrDesc &Desc = TM.getInstrInfo()->get(Opcode); > + uint64_t TSFlags = Desc.TSFlags; > + unsigned IdxMode = (TSFlags & ARMII::IndexModeMask) >> > ARMII::IndexModeShift; > + > + if (IdxMode == ARMII::IndexModePost) { > + printAM2PostIndexOp(MI, Op, O); > + return; > + } > + printAM2PreOrOffsetIndexOp(MI, Op, O); > +} > + > void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, > unsigned OpNum, > raw_ostream &O) { > > Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=128585&r1=128584&r2=128585&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original) > +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Wed Mar 30 > 18:32:32 2011 > @@ -22,9 +22,11 @@ > class TargetMachine; > > class ARMInstPrinter : public MCInstPrinter { > +private: > + TargetMachine &TM; > public: > - ARMInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI) > - : MCInstPrinter(MAI) {} > + ARMInstPrinter(TargetMachine &_TM, const MCAsmInfo &MAI) > + : MCInstPrinter(MAI), TM(_TM) {} > > virtual void printInst(const MCInst *MI, raw_ostream &O); > virtual StringRef getOpcodeName(unsigned Opcode) const; > @@ -42,7 +44,11 @@ > void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > > void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > + > void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream > &O); > + void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream > &O); > + void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, > + raw_ostream &O); > void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, > raw_ostream &O); > void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream > &O); > > Added: llvm/trunk/test/MC/ARM/arm_addrmode2.s > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128585&view=auto > > ============================================================================== > --- llvm/trunk/test/MC/ARM/arm_addrmode2.s (added) > +++ llvm/trunk/test/MC/ARM/arm_addrmode2.s Wed Mar 30 18:32:32 2011 > @@ -0,0 +1,34 @@ > +@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding > %s | FileCheck %s > + > +@ Post-indexed > +@ CHECK: ldrt r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6] > +@ CHECK: ldrt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6] > +@ CHECK: ldrt r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4] > +@ CHECK: ldrbt r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6] > +@ CHECK: ldrbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6] > +@ CHECK: ldrbt r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4] > +@ CHECK: strt r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6] > +@ CHECK: strt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6] > +@ CHECK: strt r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4] > +@ CHECK: strbt r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6] > +@ CHECK: strbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6] > +@ CHECK: strbt r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4] > + ldrt r1, [r0], r2 > + ldrt r1, [r0], r2, lsr #3 > + ldrt r1, [r0], #4 > + ldrbt r1, [r0], r2 > + ldrbt r1, [r0], r2, lsr #3 > + ldrbt r1, [r0], #4 > + strt r1, [r0], r2 > + strt r1, [r0], r2, lsr #3 > + strt r1, [r0], #4 > + strbt r1, [r0], r2 > + strbt r1, [r0], r2, lsr #3 > + strbt r1, [r0], #4 > + > +@ Pre-indexed > +@ CHECK: ldr r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7] > +@ CHECK: ldrb r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7] > + ldr r1, [r0, r2, lsr #3]! > + ldrb r1, [r0, r2, lsr #3]! > + > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110330/832248a2/attachment-0001.html From matthewbg at google.com Wed Mar 30 19:39:16 2011 From: matthewbg at google.com (Matt Beaumont-Gay) Date: Thu, 31 Mar 2011 00:39:16 -0000 Subject: [llvm-commits] [llvm] r128597 - in /llvm/trunk: lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.h test/MC/ARM/arm_addrmode2.s Message-ID: <20110331003916.F02C22A6C12C@llvm.org> Author: matthewbg Date: Wed Mar 30 19:39:16 2011 New Revision: 128597 URL: http://llvm.org/viewvc/llvm-project?rev=128597&view=rev Log: Revert "- Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and" This revision introduced a dependency cycle, as nlewycky mentioned by email. Removed: llvm/trunk/test/MC/ARM/arm_addrmode2.s Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h llvm/trunk/lib/Target/ARM/ARMInstrFormats.td llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=128597&r1=128596&r2=128597&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Wed Mar 30 19:39:16 2011 @@ -200,51 +200,6 @@ } namespace ARMII { - - /// ARM Addressing Modes - enum AddrMode { - AddrModeNone = 0, - AddrMode1 = 1, - AddrMode2 = 2, - AddrMode3 = 3, - AddrMode4 = 4, - AddrMode5 = 5, - AddrMode6 = 6, - AddrModeT1_1 = 7, - AddrModeT1_2 = 8, - AddrModeT1_4 = 9, - AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data - AddrModeT2_i12 = 11, - AddrModeT2_i8 = 12, - AddrModeT2_so = 13, - AddrModeT2_pc = 14, // +/- i12 for pc relative data - AddrModeT2_i8s4 = 15, // i8 * 4 - AddrMode_i12 = 16 - }; - - inline static const char *AddrModeToString(AddrMode addrmode) { - switch (addrmode) { - default: llvm_unreachable("Unknown memory operation"); - case AddrModeNone: return "AddrModeNone"; - case AddrMode1: return "AddrMode1"; - case AddrMode2: return "AddrMode2"; - case AddrMode3: return "AddrMode3"; - case AddrMode4: return "AddrMode4"; - case AddrMode5: return "AddrMode5"; - case AddrMode6: return "AddrMode6"; - case AddrModeT1_1: return "AddrModeT1_1"; - case AddrModeT1_2: return "AddrModeT1_2"; - case AddrModeT1_4: return "AddrModeT1_4"; - case AddrModeT1_s: return "AddrModeT1_s"; - case AddrModeT2_i12: return "AddrModeT2_i12"; - case AddrModeT2_i8: return "AddrModeT2_i8"; - case AddrModeT2_so: return "AddrModeT2_so"; - case AddrModeT2_pc: return "AddrModeT2_pc"; - case AddrModeT2_i8s4: return "AddrModeT2_i8s4"; - case AddrMode_i12: return "AddrMode_i12"; - } - } - /// Target Operand Flag enum. enum TOF { //===------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=128597&r1=128596&r2=128597&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Wed Mar 30 19:39:16 2011 @@ -34,7 +34,25 @@ //===------------------------------------------------------------------===// // This four-bit field describes the addressing mode used. - AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h + + AddrModeMask = 0x1f, + AddrModeNone = 0, + AddrMode1 = 1, + AddrMode2 = 2, + AddrMode3 = 3, + AddrMode4 = 4, + AddrMode5 = 5, + AddrMode6 = 6, + AddrModeT1_1 = 7, + AddrModeT1_2 = 8, + AddrModeT1_4 = 9, + AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data + AddrModeT2_i12 = 11, + AddrModeT2_i8 = 12, + AddrModeT2_so = 13, + AddrModeT2_pc = 14, // +/- i12 for pc relative data + AddrModeT2_i8s4 = 15, // i8 * 4 + AddrMode_i12 = 16, // Size* - Flags to keep track of the size of an instruction. SizeShift = 5, Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128597&r1=128596&r2=128597&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Wed Mar 30 19:39:16 2011 @@ -515,15 +515,15 @@ : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, pattern> { // AM2 store w/ two operands: (GPR, am2offset) - // {17-14} Rn // {13} 1 == Rm, 0 == imm12 // {12} isAdd // {11-0} imm12/Rm - bits<18> addr; - let Inst{25} = addr{13}; - let Inst{23} = addr{12}; - let Inst{19-16} = addr{17-14}; - let Inst{11-0} = addr{11-0}; + bits<14> offset; + bits<4> Rn; + let Inst{25} = offset{13}; + let Inst{23} = offset{12}; + let Inst{19-16} = Rn; + let Inst{11-0} = offset{11-0}; } // addrmode3 instructions Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128597&r1=128596&r2=128597&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed Mar 30 19:39:16 2011 @@ -498,12 +498,6 @@ let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } -def MemMode2AsmOperand : AsmOperandClass { - let Name = "MemMode2"; - let SuperClasses = []; - let ParserMethod = "tryParseMemMode2Operand"; -} - // addrmode2 := reg +/- imm12 // := reg +/- reg shop imm // @@ -511,7 +505,6 @@ ComplexPattern { let EncoderMethod = "getAddrMode2OpValue"; let PrintMethod = "printAddrMode2Operand"; - let ParserMatchClass = MemMode2AsmOperand; let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } @@ -1663,7 +1656,6 @@ let Inst{23} = addr{12}; let Inst{19-16} = addr{17-14}; let Inst{11-0} = addr{11-0}; - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; } def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), (ins GPR:$Rn, am2offset:$offset), @@ -1722,35 +1714,17 @@ // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. let mayLoad = 1, neverHasSideEffects = 1 in { -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb), - (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru, - "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { - // {17-14} Rn - // {13} 1 == Rm, 0 == imm12 - // {12} isAdd - // {11-0} imm12/Rm - bits<18> addr; - let Inst{25} = addr{13}; - let Inst{23} = addr{12}; +def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb), + (ins GPR:$base, am2offset:$offset), IndexModePost, + LdFrm, IIC_iLoad_ru, + "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { let Inst{21} = 1; // overwrite - let Inst{19-16} = addr{17-14}; - let Inst{11-0} = addr{11-0}; - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; -} -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), - (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru, - "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { - // {17-14} Rn - // {13} 1 == Rm, 0 == imm12 - // {12} isAdd - // {11-0} imm12/Rm - bits<18> addr; - let Inst{25} = addr{13}; - let Inst{23} = addr{12}; +} +def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb), + (ins GPR:$base, am2offset:$offset), IndexModePost, + LdFrm, IIC_iLoad_bh_ru, + "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { let Inst{21} = 1; // overwrite - let Inst{19-16} = addr{17-14}; - let Inst{11-0} = addr{11-0}; - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; } def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb), (ins GPR:$base, am3offset:$offset), IndexModePost, @@ -1844,20 +1818,20 @@ // STRT, STRBT, and STRHT are for disassembly only. -def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), +def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, GPR:$Rn,am2offset:$offset), IndexModePost, StFrm, IIC_iStore_ru, - "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb", + "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", [/* For disassembly only; pattern left blank */]> { let Inst{21} = 1; // overwrite - let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; } -def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), +def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), IndexModePost, StFrm, IIC_iStore_bh_ru, - "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb", + "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", [/* For disassembly only; pattern left blank */]> { let Inst{21} = 1; // overwrite - let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; } def STRHT: AI3sthpo<(outs GPR:$base_wb), @@ -3417,9 +3391,8 @@ let Inst{23-20} = opc1; } -class ACI - : I + : I { let Inst{27-25} = 0b110; } @@ -3438,7 +3411,7 @@ def _PRE : ACI<(outs), (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> { + opc, "\tp$cop, cr$CRd, $addr!"> { let Inst{31-28} = op31_28; let Inst{24} = 1; // P = 1 let Inst{21} = 1; // W = 1 @@ -3479,7 +3452,7 @@ def L_PRE : ACI<(outs), (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> { + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { let Inst{31-28} = op31_28; let Inst{24} = 1; // P = 1 let Inst{21} = 1; // W = 1 Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128597&r1=128596&r2=128597&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Wed Mar 30 19:39:16 2011 @@ -48,8 +48,7 @@ bool TryParseRegisterWithWriteBack(SmallVectorImpl &); bool TryParseShiftRegister(SmallVectorImpl &); bool ParseRegisterList(SmallVectorImpl &); - bool ParseMemory(SmallVectorImpl &, - ARMII::AddrMode AddrMode); + bool ParseMemory(SmallVectorImpl &); bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic); bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); const MCExpr *ApplyPrefixToExpr(const MCExpr *E, @@ -96,14 +95,6 @@ SmallVectorImpl&); OperandMatchResultTy tryParseMSRMaskOperand( SmallVectorImpl&); - OperandMatchResultTy tryParseMemMode2Operand( - SmallVectorImpl&); - - // Asm Match Converter Methods - bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, - const SmallVectorImpl &); - bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, - const SmallVectorImpl &); public: ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) @@ -181,7 +172,6 @@ /// Combined record for all forms of ARM address expressions. struct { - ARMII::AddrMode AddrMode; unsigned BaseRegNum; union { unsigned RegNum; ///< Offset register num, when OffsetIsReg. @@ -303,9 +293,7 @@ /// @name Memory Operand Accessors /// @{ - ARMII::AddrMode getMemAddrMode() const { - return Mem.AddrMode; - } + unsigned getMemBaseRegNum() const { return Mem.BaseRegNum; } @@ -350,27 +338,6 @@ bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } bool isMemory() const { return Kind == Memory; } bool isShifter() const { return Kind == Shifter; } - bool isMemMode2() const { - if (getMemAddrMode() != ARMII::AddrMode2) - return false; - - if (getMemOffsetIsReg()) - return true; - - if (getMemNegative() && - !(getMemPostindexed() || getMemPreindexed())) - return false; - - const MCConstantExpr *CE = dyn_cast(getMemOffset()); - if (!CE) return false; - int64_t Value = CE->getValue(); - - // The offset must be in the range 0-4095 (imm12). - if (Value > 4095 || Value < -4095) - return false; - - return true; - } bool isMemMode5() const { if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || getMemNegative()) @@ -498,46 +465,6 @@ "No offset operand support in mode 7"); } - void addMemMode2Operands(MCInst &Inst, unsigned N) const { - assert(isMemMode2() && "Invalid mode or number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); - - if (getMemOffsetIsReg()) { - Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); - - ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; - ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; - int64_t ShiftAmount = 0; - - if (getMemOffsetRegShifted()) { - ShOpc = getMemShiftType(); - const MCConstantExpr *CE = - dyn_cast(getMemShiftAmount()); - ShiftAmount = CE->getValue(); - } - - Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, - ShOpc))); - return; - } - - // Create a operand placeholder to always yield the same number of operands. - Inst.addOperand(MCOperand::CreateReg(0)); - - // FIXME: #-0 is encoded differently than #0. Does the parser preserve - // the difference? - const MCConstantExpr *CE = dyn_cast(getMemOffset()); - assert(CE && "Non-constant mode 2 offset operand!"); - int64_t Offset = CE->getValue(); - - if (Offset >= 0) - Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, - Offset, ARM_AM::no_shift))); - else - Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, - -Offset, ARM_AM::no_shift))); - } - void addMemMode5Operands(MCInst &Inst, unsigned N) const { assert(N == 2 && isMemMode5() && "Invalid number of operands!"); @@ -672,9 +599,9 @@ return Op; } - static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, - bool OffsetIsReg, const MCExpr *Offset, - int OffsetRegNum, bool OffsetRegShifted, + static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, + const MCExpr *Offset, int OffsetRegNum, + bool OffsetRegShifted, enum ARM_AM::ShiftOpc ShiftType, const MCExpr *ShiftAmount, bool Preindexed, bool Postindexed, bool Negative, bool Writeback, @@ -691,7 +618,6 @@ "Cannot have expression offset and register offset!"); ARMOperand *Op = new ARMOperand(Memory); - Op->Mem.AddrMode = AddrMode; Op->Mem.BaseRegNum = BaseRegNum; Op->Mem.OffsetIsReg = OffsetIsReg; if (OffsetIsReg) @@ -763,8 +689,7 @@ break; case Memory: OS << " &Operands) { - SMLoc S = Parser.getTok().getLoc(); - const AsmToken &Tok = Parser.getTok(); - assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\""); - - if (ParseMemory(Operands, ARMII::AddrMode2)) - return MatchOperand_NoMatch; - - return MatchOperand_Success; -} - -/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. -/// Needed here because the Asm Gen Matcher can't handle properly tied operands -/// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: -CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, - const SmallVectorImpl &Operands) { - ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); - - // Create a writeback register dummy placeholder. - Inst.addOperand(MCOperand::CreateImm(0)); - - ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); - ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; -} - -/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. -/// Needed here because the Asm Gen Matcher can't handle properly tied operands -/// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: -CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, - const SmallVectorImpl &Operands) { - // Create a writeback register dummy placeholder. - Inst.addOperand(MCOperand::CreateImm(0)); - ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); - ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); - ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; -} - /// Parse an ARM memory expression, return false if successful else return true /// or an error. The first token must be a '[' when called. /// /// TODO Only preindexing and postindexing addressing are started, unindexed /// with option, etc are still to do. bool ARMAsmParser:: -ParseMemory(SmallVectorImpl &Operands, - ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { +ParseMemory(SmallVectorImpl &Operands) { SMLoc S, E; assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a Left Bracket"); @@ -1350,10 +1231,11 @@ Offset = MCConstantExpr::Create(0, getContext()); } - Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, - Offset, OffsetRegNum, OffsetRegShifted, - ShiftType, ShiftAmount, Preindexed, - Postindexed, Negative, Writeback, S, E)); + Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, + OffsetRegNum, OffsetRegShifted, + ShiftType, ShiftAmount, Preindexed, + Postindexed, Negative, Writeback, + S, E)); if (WBOp) Operands.push_back(WBOp); Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=128597&r1=128596&r2=128597&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Wed Mar 30 19:39:16 2011 @@ -14,7 +14,6 @@ #define DEBUG_TYPE "asm-printer" #include "ARMBaseInfo.h" #include "ARMInstPrinter.h" -#include "ARMInstrInfo.h" #include "ARMAddressingModes.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCAsmInfo.h" @@ -182,12 +181,18 @@ } } -void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, - raw_ostream &O) { + +void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, + raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(Op); const MCOperand &MO2 = MI->getOperand(Op+1); const MCOperand &MO3 = MI->getOperand(Op+2); + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. + printOperand(MI, Op, O); + return; + } + O << "[" << getRegisterName(MO1.getReg()); if (!MO2.getReg()) { @@ -210,52 +215,6 @@ O << "]"; } -void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, - raw_ostream &O) { - const MCOperand &MO1 = MI->getOperand(Op); - const MCOperand &MO2 = MI->getOperand(Op+1); - const MCOperand &MO3 = MI->getOperand(Op+2); - - O << "[" << getRegisterName(MO1.getReg()) << "], "; - - if (!MO2.getReg()) { - unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); - O << '#' - << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) - << ImmOffs; - return; - } - - O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) - << getRegisterName(MO2.getReg()); - - if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) - O << ", " - << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) - << " #" << ShImm; -} - -void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, - raw_ostream &O) { - const MCOperand &MO1 = MI->getOperand(Op); - - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. - printOperand(MI, Op, O); - return; - } - - unsigned Opcode = MI->getOpcode(); - const TargetInstrDesc &Desc = TM.getInstrInfo()->get(Opcode); - uint64_t TSFlags = Desc.TSFlags; - unsigned IdxMode = (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; - - if (IdxMode == ARMII::IndexModePost) { - printAM2PostIndexOp(MI, Op, O); - return; - } - printAM2PreOrOffsetIndexOp(MI, Op, O); -} - void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) { Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=128597&r1=128596&r2=128597&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Wed Mar 30 19:39:16 2011 @@ -22,11 +22,9 @@ class TargetMachine; class ARMInstPrinter : public MCInstPrinter { -private: - TargetMachine &TM; public: - ARMInstPrinter(TargetMachine &_TM, const MCAsmInfo &MAI) - : MCInstPrinter(MAI), TM(_TM) {} + ARMInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI) + : MCInstPrinter(MAI) {} virtual void printInst(const MCInst *MI, raw_ostream &O); virtual StringRef getOpcodeName(unsigned Opcode) const; @@ -44,11 +42,7 @@ void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, - raw_ostream &O); void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); Removed: llvm/trunk/test/MC/ARM/arm_addrmode2.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128596&view=auto ============================================================================== --- llvm/trunk/test/MC/ARM/arm_addrmode2.s (original) +++ llvm/trunk/test/MC/ARM/arm_addrmode2.s (removed) @@ -1,34 +0,0 @@ -@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | FileCheck %s - -@ Post-indexed -@ CHECK: ldrt r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6] -@ CHECK: ldrt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6] -@ CHECK: ldrt r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4] -@ CHECK: ldrbt r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6] -@ CHECK: ldrbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6] -@ CHECK: ldrbt r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4] -@ CHECK: strt r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6] -@ CHECK: strt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6] -@ CHECK: strt r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4] -@ CHECK: strbt r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6] -@ CHECK: strbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6] -@ CHECK: strbt r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4] - ldrt r1, [r0], r2 - ldrt r1, [r0], r2, lsr #3 - ldrt r1, [r0], #4 - ldrbt r1, [r0], r2 - ldrbt r1, [r0], r2, lsr #3 - ldrbt r1, [r0], #4 - strt r1, [r0], r2 - strt r1, [r0], r2, lsr #3 - strt r1, [r0], #4 - strbt r1, [r0], r2 - strbt r1, [r0], r2, lsr #3 - strbt r1, [r0], #4 - -@ Pre-indexed -@ CHECK: ldr r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7] -@ CHECK: ldrb r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7] - ldr r1, [r0, r2, lsr #3]! - ldrb r1, [r0, r2, lsr #3]! - From bruno.cardoso at gmail.com Wed Mar 30 20:05:19 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Wed, 30 Mar 2011 22:05:19 -0300 Subject: [llvm-commits] [llvm] r128585 - in /llvm/trunk: lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/InstPrinter/A In-Reply-To: References: Message-ID: > No, you can not do this. This will transitively > #include?ARMGenRegisterInfo.h.inc which declares "extern QQQQPRClass > QQQQPRRegClass;". That causes ARMInstPrinter to have a dependency on > ARMCodeGen, causing a cycle. > We'll probably revert this patch shortly. Please re-commit once you fix > this! > Nick You're right. Thanks for reverting. -- Bruno Cardoso Lopes http://www.brunocardoso.cc From ofv at wanadoo.es Wed Mar 30 22:13:54 2011 From: ofv at wanadoo.es (=?utf-8?Q?=C3=93scar_Fuentes?=) Date: Thu, 31 Mar 2011 05:13:54 +0200 Subject: [llvm-commits] [RFC] Extend GenLibDeps.pl for other library sets. Message-ID: <87bp0svv65.fsf@wanadoo.es> Currently GenLibDeps.pl is hard-coded for working on the set of libraries generated by LLVM. The patch below extends it for dumping other groups of libraries (i.e. clang). It's quite simple and it works for me but, as my Perl knowledge is nonexistent, I'll like to get it reviewed & approved first. It adds a new command-line option `-libset NAME', which indicates that the operation must be performed on libraries named libNAME* (instead of libLLVM*) --- a/utils/GenLibDeps.pl +++ b/utils/GenLibDeps.pl @@ -15,12 +15,14 @@ my $FLAT = 0; my $WHY = 0; my $PEROBJ = 0; my $PEROBJINCL = 0; +my $LIBSET = "LLVM"; while (scalar(@ARGV) and ($_ = $ARGV[0], /^[-+]/)) { shift; last if /^--$/; # Stop processing arguments on -- # List command line options here... if (/^-flat$/) { $FLAT = 1; next; } + if (/^-libset$/) { $LIBSET = $ARGV[0]; shift; next } if (/^-why/) { $WHY = 1; $FLAT = 1; next; } if (/^-perobj$/) { $PEROBJ = 1; next; } if (/^-perobjincl/) { $PEROBJINCL = 1; next;} @@ -69,10 +71,10 @@ if ($PEROBJ) { opendir DIR,$Directory; my @files = readdir DIR; closedir DIR; -my @libs = grep(/libLLVM.*\.(dylib|so|a)$/,sort(@files)); +my @libs = grep(/lib$LIBSET.*\.(dylib|so|a)$/,sort(@files)); # Omit the all-of-llvm shared library. - at libs = grep(!/libLLVM-\d\.\d(svn)?\.(dylib|so)/, @libs); -my @objs = grep(/LLVM.*\.o$/,sort(@files)); + at libs = grep(!/lib$LIBSET(-\d\.\d)?(svn)?\.(dylib|so)/, @libs); +my @objs = grep(/$LIBSET.*\.o$/,sort(@files)); # Declare the hashes we will use to keep track of the library and object file # symbol definitions. @@ -86,7 +88,7 @@ if ($PEROBJ) { foreach my $lib (@libs ) { `$ranlibPath $Directory/$lib`; my $libpath = $lib; - $libpath =~ s/^libLLVM(.*)\.a/$1/; + $libpath =~ s/^lib$LIBSET(.*)\.a/$1/; $libpath =~ s/(.+)CodeGen$/Target\/$1/; $libpath =~ s/(.+)AsmPrinter$/Target\/$1\/AsmPrinter/; $libpath =~ s/(.+)AsmParser$/Target\/$1\/AsmParser/; @@ -128,7 +130,7 @@ if ($PEROBJ) { } foreach my $lib (@libs ) { my $libpath = $lib; - $libpath =~ s/^libLLVM(.*)\.a/$1/; + $libpath =~ s/^lib$LIBSET(.*)\.a/$1/; $libpath =~ s/(.+)CodeGen$/Target\/$1/; $libpath =~ s/(.+)AsmPrinter$/Target\/$1\/AsmPrinter/; $libpath =~ s/(.+)AsmParser$/Target\/$1\/AsmParser/; From stoklund at 2pi.dk Wed Mar 30 22:54:44 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 31 Mar 2011 03:54:44 -0000 Subject: [llvm-commits] [llvm] r128610 - in /llvm/trunk: lib/CodeGen/InlineSpiller.cpp test/CodeGen/ARM/crash-greedy.ll Message-ID: <20110331035444.A764E2A6C12C@llvm.org> Author: stoklund Date: Wed Mar 30 22:54:44 2011 New Revision: 128610 URL: http://llvm.org/viewvc/llvm-project?rev=128610&view=rev Log: Pick a conservative register class when creating a small live range for remat. The rematerialized instruction may require a more constrained register class than the register being spilled. In the test case, the spilled register has been inflated to the DPR register class, but we are rematerializing a load of the ssub_0 sub-register which only exists for DPR_VFP2 registers. The register class is reinflated after spilling, so the conservative choice is only temporary. Added: llvm/trunk/test/CodeGen/ARM/crash-greedy.ll Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InlineSpiller.cpp?rev=128610&r1=128609&r2=128610&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/InlineSpiller.cpp (original) +++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp Wed Mar 30 22:54:44 2011 @@ -627,7 +627,7 @@ } // Alocate a new register for the remat. - LiveInterval &NewLI = Edit->createFrom(VirtReg.reg, LIS, VRM); + LiveInterval &NewLI = Edit->createFrom(Original, LIS, VRM); NewLI.markNotSpillable(); // Finally we can rematerialize OrigMI before MI. Added: llvm/trunk/test/CodeGen/ARM/crash-greedy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/crash-greedy.ll?rev=128610&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/crash-greedy.ll (added) +++ llvm/trunk/test/CodeGen/ARM/crash-greedy.ll Wed Mar 30 22:54:44 2011 @@ -0,0 +1,61 @@ +; RUN: llc < %s -regalloc=greedy -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim | FileCheck %s +; +; ARM tests that crash or fail with the greedy register allocator. + +target triple = "thumbv7-apple-darwin" + +declare double @exp(double) + +; CHECK remat_subreg +define void @remat_subreg(float* nocapture %x, i32* %y, i32 %n, i32 %z, float %c, float %lambda, float* nocapture %ret_f, float* nocapture %ret_df) nounwind { +entry: + %conv16 = fpext float %lambda to double + %mul17 = fmul double %conv16, -1.000000e+00 + br i1 undef, label %cond.end.us, label %cond.end + +cond.end.us: ; preds = %entry + unreachable + +cond.end: ; preds = %cond.end, %entry + %mul = fmul double undef, 0.000000e+00 + %add = fadd double undef, %mul + %add46 = fadd double undef, undef + %add75 = fadd double 0.000000e+00, undef + br i1 undef, label %for.end, label %cond.end + +for.end: ; preds = %cond.end + %conv78 = sitofp i32 %z to double + %conv83 = fpext float %c to double + %mul84 = fmul double %mul17, %conv83 + %call85 = tail call double @exp(double %mul84) nounwind + %mul86 = fmul double %conv78, %call85 + %add88 = fadd double 0.000000e+00, %mul86 +; CHECK: blx _exp + %call100 = tail call double @exp(double %mul84) nounwind + %mul101 = fmul double undef, %call100 + %add103 = fadd double %add46, %mul101 + %mul111 = fmul double undef, %conv83 + %mul119 = fmul double %mul111, undef + %add121 = fadd double undef, %mul119 + %div = fdiv double 1.000000e+00, %conv16 + %div126 = fdiv double %add, %add75 + %sub = fsub double %div, %div126 + %div129 = fdiv double %add103, %add88 + %add130 = fadd double %sub, %div129 + %conv131 = fptrunc double %add130 to float + store float %conv131, float* %ret_f, align 4 + %mul139 = fmul double %div129, %div129 + %div142 = fdiv double %add121, %add88 + %sub143 = fsub double %mul139, %div142 +; %lambda is passed on the stack, and the stack slot load is rematerialized. +; The rematted load of a float constrains the D register used for the mul. +; CHECK: vldr + %mul146 = fmul float %lambda, %lambda + %conv147 = fpext float %mul146 to double + %div148 = fdiv double 1.000000e+00, %conv147 + %sub149 = fsub double %sub143, %div148 + %conv150 = fptrunc double %sub149 to float + store float %conv150, float* %ret_df, align 4 + ret void +} + From wdietz2 at illinois.edu Thu Mar 31 02:58:42 2011 From: wdietz2 at illinois.edu (Will Dietz) Date: Thu, 31 Mar 2011 07:58:42 -0000 Subject: [llvm-commits] [poolalloc] r128617 - /poolalloc/trunk/test/dsa/var_arg/print.c Message-ID: <20110331075842.607782A6C12D@llvm.org> Author: wdietz2 Date: Thu Mar 31 02:58:42 2011 New Revision: 128617 URL: http://llvm.org/viewvc/llvm-project?rev=128617&view=rev Log: Fix test compilation errors, fix spurious failures due to printing pointer. Modified: poolalloc/trunk/test/dsa/var_arg/print.c Modified: poolalloc/trunk/test/dsa/var_arg/print.c URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/var_arg/print.c?rev=128617&r1=128616&r2=128617&view=diff ============================================================================== --- poolalloc/trunk/test/dsa/var_arg/print.c (original) +++ poolalloc/trunk/test/dsa/var_arg/print.c Thu Mar 31 02:58:42 2011 @@ -1,14 +1,14 @@ #include #include +#include //--build the code into a .bc //RUN: llvm-gcc -O0 %s -S --emit-llvm -o - | llvm-as > %t.bc //--check if ds-aa breaks, breaks opts, or results in miscompiled code //RUN: lli %t.bc > %t.refout //RUN: dsaopt %t.bc -ds-aa -O3 -o - | lli > %t.out -//RUN: diff %t.refout %t.out -//--check properties of this particular test -//N/A +// (Don't diff the results; this code prints a pointer which is silly to diff) +//RUNNO: diff %t.refout %t.out void generic_sendmsg (const char *fmt, ...) { @@ -20,9 +20,11 @@ printf("\n"); } -void main() { +int main() { int *x = malloc(sizeof(int)); generic_sendmsg("F %li %li %3.2f %3.2f", 1234, 1234,123.22, 123.45); generic_sendmsg("%s ID3:%s%s", "TEST", "AAA" , "Unknown"); generic_sendmsg("%s ID3:%s%s %p", "TEST", "AAA" , "Unknown", x); + + return 0; } From isanbard at gmail.com Thu Mar 31 03:07:09 2011 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 31 Mar 2011 08:07:09 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r128619 - /llvm-gcc-4.2/trunk/gcc/fold-const.c Message-ID: <20110331080709.BB6792A6C12D@llvm.org> Author: void Date: Thu Mar 31 03:07:09 2011 New Revision: 128619 URL: http://llvm.org/viewvc/llvm-project?rev=128619&view=rev Log: Our old friend "array ref with pointer base". The "fold_binary" function is trying to fold a "ptr + 0" into something simple. The "tree_expr_nonzero_p" function says that "&ptr[0]" is non-zero, which is correct only if ptr is an array. PR9571 Modified: llvm-gcc-4.2/trunk/gcc/fold-const.c Modified: llvm-gcc-4.2/trunk/gcc/fold-const.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/fold-const.c?rev=128619&r1=128618&r2=128619&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/fold-const.c (original) +++ llvm-gcc-4.2/trunk/gcc/fold-const.c Thu Mar 31 03:07:09 2011 @@ -12839,11 +12839,21 @@ case ADDR_EXPR: { - tree base = get_base_address (TREE_OPERAND (t, 0)); + tree targ0 = TREE_OPERAND (t, 0); + tree base = get_base_address (targ0); if (!base) return false; + /* LLVM LOCAL begin */ +#ifdef ENABLE_LLVM + /* Support the "array ref with pointer base" extension. */ + if (TREE_CODE (targ0) == ARRAY_REF && + TREE_CODE (TREE_TYPE (TREE_OPERAND(targ0, 0))) != ARRAY_TYPE) + return false; +#endif + /* LLVM LOCAL end */ + /* Weak declarations may link to NULL. */ if (VAR_OR_FUNCTION_DECL_P (base)) return !DECL_WEAK (base); From isanbard at gmail.com Thu Mar 31 03:13:57 2011 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 31 Mar 2011 08:13:57 -0000 Subject: [llvm-commits] [llvm] r128620 - /llvm/trunk/test/FrontendC/2011-03-31-ArrayRefFolding.c Message-ID: <20110331081357.6CA882A6C12D@llvm.org> Author: void Date: Thu Mar 31 03:13:57 2011 New Revision: 128620 URL: http://llvm.org/viewvc/llvm-project?rev=128620&view=rev Log: Testcase for r128619 (PR9571). Added: llvm/trunk/test/FrontendC/2011-03-31-ArrayRefFolding.c Added: llvm/trunk/test/FrontendC/2011-03-31-ArrayRefFolding.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC/2011-03-31-ArrayRefFolding.c?rev=128620&view=auto ============================================================================== --- llvm/trunk/test/FrontendC/2011-03-31-ArrayRefFolding.c (added) +++ llvm/trunk/test/FrontendC/2011-03-31-ArrayRefFolding.c Thu Mar 31 03:13:57 2011 @@ -0,0 +1,15 @@ +// RUN: %llvmgcc -S -o - -m32 -Os %s | FileCheck %s +// PR9571 + +struct t { + int x; +}; + +extern struct t *cfun; + +int f(void) { + if (!(cfun + 0)) +// CHECK: icmp eq %struct.t* %0, null + return 0; + return cfun->x; +} From baldrick at free.fr Thu Mar 31 04:58:51 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 31 Mar 2011 09:58:51 -0000 Subject: [llvm-commits] [llvm] r128622 - in /llvm/trunk/unittests/VMCore: DerivedTypesTest.cpp PassManagerTest.cpp Message-ID: <20110331095851.720F92A6C12C@llvm.org> Author: baldrick Date: Thu Mar 31 04:58:51 2011 New Revision: 128622 URL: http://llvm.org/viewvc/llvm-project?rev=128622&view=rev Log: Strip trailing whitespace. Modified: llvm/trunk/unittests/VMCore/DerivedTypesTest.cpp llvm/trunk/unittests/VMCore/PassManagerTest.cpp Modified: llvm/trunk/unittests/VMCore/DerivedTypesTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/VMCore/DerivedTypesTest.cpp?rev=128622&r1=128621&r2=128622&view=diff ============================================================================== --- llvm/trunk/unittests/VMCore/DerivedTypesTest.cpp (original) +++ llvm/trunk/unittests/VMCore/DerivedTypesTest.cpp Thu Mar 31 04:58:51 2011 @@ -19,13 +19,13 @@ static void PR7658() { LLVMContext ctx; - + WeakVH NullPtr; PATypeHolder h1; { OpaqueType *o1 = OpaqueType::get(ctx); PointerType *p1 = PointerType::get(o1, 0); - + std::vector t1; t1.push_back(IntegerType::get(ctx, 32)); t1.push_back(p1); @@ -33,41 +33,41 @@ OpaqueType *o2 = OpaqueType::get (ctx); PointerType *p2 = PointerType::get (o2, 0); t1.push_back(p2); - - + + StructType *s1 = StructType::get(ctx, t1); h1 = s1; o1->refineAbstractTypeTo(s1); o2->refineAbstractTypeTo(h1.get()); // h1 = { i32, \2*, \2* } } - - + + OpaqueType *o3 = OpaqueType::get(ctx); PointerType *p3 = PointerType::get(o3, 0); // p3 = opaque* - + std::vector t2; t2.push_back(IntegerType::get(ctx, 32)); t2.push_back(p3); - + std::vector v2; v2.push_back(ConstantInt::get(IntegerType::get(ctx, 32), 14)); v2.push_back(ConstantPointerNull::get(p3)); - + OpaqueType *o4 = OpaqueType::get(ctx); { PointerType *p4 = PointerType::get(o4, 0); t2.push_back(p4); v2.push_back(ConstantPointerNull::get(p4)); } - + WeakVH CS = ConstantStruct::get(ctx, v2, false); // { i32 14, opaque* null, opaque* null} - + StructType *s2 = StructType::get(ctx, t2); PATypeHolder h2(s2); o3->refineAbstractTypeTo(s2); o4->refineAbstractTypeTo(h2.get()); } - + TEST(OpaqueTypeTest, RegisterWithContext) { LLVMContext C; @@ -81,7 +81,7 @@ EXPECT_EQ(2u, pImpl->OpaqueTypes.size()); } EXPECT_EQ(1u, pImpl->OpaqueTypes.size()); - + PR7658(); } Modified: llvm/trunk/unittests/VMCore/PassManagerTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/VMCore/PassManagerTest.cpp?rev=128622&r1=128621&r2=128622&view=diff ============================================================================== --- llvm/trunk/unittests/VMCore/PassManagerTest.cpp (original) +++ llvm/trunk/unittests/VMCore/PassManagerTest.cpp Thu Mar 31 04:58:51 2011 @@ -40,7 +40,7 @@ void initializeCGPassPass(PassRegistry&); void initializeLPassPass(PassRegistry&); void initializeBPassPass(PassRegistry&); - + namespace { // ND = no deps // NM = no modifications From baldrick at free.fr Thu Mar 31 05:03:32 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 31 Mar 2011 10:03:32 -0000 Subject: [llvm-commits] [llvm] r128623 - /llvm/trunk/test/FrontendAda/real_cst.adb Message-ID: <20110331100332.BF8252A6C12C@llvm.org> Author: baldrick Date: Thu Mar 31 05:03:32 2011 New Revision: 128623 URL: http://llvm.org/viewvc/llvm-project?rev=128623&view=rev Log: Will not compile without the spec! Modified: llvm/trunk/test/FrontendAda/real_cst.adb Modified: llvm/trunk/test/FrontendAda/real_cst.adb URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendAda/real_cst.adb?rev=128623&r1=128622&r2=128623&view=diff ============================================================================== --- llvm/trunk/test/FrontendAda/real_cst.adb (original) +++ llvm/trunk/test/FrontendAda/real_cst.adb Thu Mar 31 05:03:32 2011 @@ -1,4 +1,4 @@ --- RUN: %llvmgcc -S -O2 -gnatn %s +-- RUN: %llvmgcc -S -O2 -gnatn %s -I%p/Support package body Real_Cst is Cst : constant Float := 0.0; procedure Write (Stream : access Ada.Streams.Root_Stream_Type'Class) is From benny.kra at googlemail.com Thu Mar 31 05:11:58 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 31 Mar 2011 10:11:58 -0000 Subject: [llvm-commits] [llvm] r128624 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCompares.cpp test/Transforms/InstCombine/fcmp.ll Message-ID: <20110331101158.3A4B02A6C12C@llvm.org> Author: d0k Date: Thu Mar 31 05:11:58 2011 New Revision: 128624 URL: http://llvm.org/viewvc/llvm-project?rev=128624&view=rev Log: InstCombine: fold fcmp (fpext x), (fpext y) -> fcmp x, y. Added: llvm/trunk/test/Transforms/InstCombine/fcmp.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=128624&r1=128623&r2=128624&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu Mar 31 05:11:58 2011 @@ -2813,5 +2813,12 @@ } } + // fcmp (fpext x), (fpext y) -> fcmp x, y + if (FPExtInst *LHSExt = dyn_cast(Op0)) + if (FPExtInst *RHSExt = dyn_cast(Op1)) + if (LHSExt->getSrcTy() == RHSExt->getSrcTy()) + return new FCmpInst(I.getPredicate(), LHSExt->getOperand(0), + RHSExt->getOperand(0)); + return Changed ? &I : 0; } Added: llvm/trunk/test/Transforms/InstCombine/fcmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fcmp.ll?rev=128624&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/fcmp.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/fcmp.ll Thu Mar 31 05:11:58 2011 @@ -0,0 +1,11 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +define i1 @test1(float %x, float %y) nounwind { + %ext1 = fpext float %x to double + %ext2 = fpext float %y to double + %cmp = fcmp ogt double %ext1, %ext2 + ret i1 %cmp +; CHECK: @test1 +; CHECK-NEXT: fcmp ogt float %x, %y +} + From benny.kra at googlemail.com Thu Mar 31 05:12:07 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 31 Mar 2011 10:12:07 -0000 Subject: [llvm-commits] [llvm] r128625 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCompares.cpp test/Transforms/InstCombine/fcmp.ll Message-ID: <20110331101207.B02362A6C12C@llvm.org> Author: d0k Date: Thu Mar 31 05:12:07 2011 New Revision: 128625 URL: http://llvm.org/viewvc/llvm-project?rev=128625&view=rev Log: InstCombine: Shrink "fcmp (fpext x), C" to "fcmp x, C" if C can be losslessly converted to the type of x. Fixes PR9592. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/trunk/test/Transforms/InstCombine/fcmp.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=128625&r1=128624&r2=128625&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu Mar 31 05:12:07 2011 @@ -2762,6 +2762,40 @@ if (Constant *RHSC = dyn_cast(Op1)) { if (Instruction *LHSI = dyn_cast(Op0)) switch (LHSI->getOpcode()) { + case Instruction::FPExt: { + // fcmp (fpext x), C -> fcmp x, (fptrunc C) if fptrunc is lossless + FPExtInst *LHSExt = cast(LHSI); + ConstantFP *RHSF = dyn_cast(RHSC); + if (!RHSF) + break; + + const fltSemantics *Sem; + // FIXME: This shouldn't be here. + if (LHSExt->getSrcTy()->isFloatTy()) + Sem = &APFloat::IEEEsingle; + else if (LHSExt->getSrcTy()->isDoubleTy()) + Sem = &APFloat::IEEEdouble; + else if (LHSExt->getSrcTy()->isFP128Ty()) + Sem = &APFloat::IEEEquad; + else if (LHSExt->getSrcTy()->isX86_FP80Ty()) + Sem = &APFloat::x87DoubleExtended; + else if (LHSExt->getSrcTy()->isPPC_FP128Ty()) + Sem = &APFloat::PPCDoubleDouble; + else + break; + + bool Lossy; + APFloat F = RHSF->getValueAPF(); + F.convert(*Sem, APFloat::rmNearestTiesToEven, &Lossy); + + // Avoid lossy conversions and denormals. + if (!Lossy && + F.compare(APFloat::getSmallestNormalized(*Sem)) != + APFloat::cmpLessThan) + return new FCmpInst(I.getPredicate(), LHSExt->getOperand(0), + ConstantFP::get(RHSC->getContext(), F)); + break; + } case Instruction::PHI: // Only fold fcmp into the PHI if the phi and fcmp are in the same // block. If in the same block, we're encouraging jump threading. If Modified: llvm/trunk/test/Transforms/InstCombine/fcmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fcmp.ll?rev=128625&r1=128624&r2=128625&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/fcmp.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/fcmp.ll Thu Mar 31 05:12:07 2011 @@ -9,3 +9,26 @@ ; CHECK-NEXT: fcmp ogt float %x, %y } +define i1 @test2(float %a) nounwind { + %ext = fpext float %a to double + %cmp = fcmp ogt double %ext, 1.000000e+00 + ret i1 %cmp +; CHECK: @test2 +; CHECK-NEXT: fcmp ogt float %a, 1.0 +} + +define i1 @test3(float %a) nounwind { + %ext = fpext float %a to double + %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float. + ret i1 %cmp +; CHECK: @test3 +; CHECK-NEXT: fpext float %a to double +} + +define i1 @test4(float %a) nounwind { + %ext = fpext float %a to double + %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float. + ret i1 %cmp +; CHECK: @test4 +; CHECK-NEXT: fpext float %a to double +} From benny.kra at googlemail.com Thu Mar 31 05:12:15 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 31 Mar 2011 10:12:15 -0000 Subject: [llvm-commits] [llvm] r128626 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCompares.cpp test/Transforms/InstCombine/fcmp.ll Message-ID: <20110331101215.928202A6C12C@llvm.org> Author: d0k Date: Thu Mar 31 05:12:15 2011 New Revision: 128626 URL: http://llvm.org/viewvc/llvm-project?rev=128626&view=rev Log: InstCombine: fold fcmp pred (fneg x), C -> fcmp swap(pred) x, -C Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/trunk/test/Transforms/InstCombine/fcmp.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=128626&r1=128625&r2=128626&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu Mar 31 05:12:15 2011 @@ -2834,6 +2834,14 @@ return SelectInst::Create(LHSI->getOperand(0), Op1, Op2); break; } + case Instruction::FSub: { + // fcmp pred (fneg x), C -> fcmp swap(pred) x, -C + Value *Op; + if (match(LHSI, m_FNeg(m_Value(Op)))) + return new FCmpInst(I.getSwappedPredicate(), Op, + ConstantExpr::getFNeg(RHSC)); + break; + } case Instruction::Load: if (GetElementPtrInst *GEP = dyn_cast(LHSI->getOperand(0))) { Modified: llvm/trunk/test/Transforms/InstCombine/fcmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fcmp.ll?rev=128626&r1=128625&r2=128626&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/fcmp.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/fcmp.ll Thu Mar 31 05:12:15 2011 @@ -32,3 +32,11 @@ ; CHECK: @test4 ; CHECK-NEXT: fpext float %a to double } + +define i1 @test5(float %a) nounwind { + %neg = fsub float -0.000000e+00, %a + %cmp = fcmp ogt float %neg, 1.000000e+00 + ret i1 %cmp +; CHECK: @test5 +; CHECK-NEXT: fcmp olt float %a, -1.0 +} From benny.kra at googlemail.com Thu Mar 31 05:12:23 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 31 Mar 2011 10:12:23 -0000 Subject: [llvm-commits] [llvm] r128627 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCompares.cpp test/Transforms/InstCombine/fcmp.ll Message-ID: <20110331101223.0F1CA2A6C12C@llvm.org> Author: d0k Date: Thu Mar 31 05:12:22 2011 New Revision: 128627 URL: http://llvm.org/viewvc/llvm-project?rev=128627&view=rev Log: InstCombine: fold fcmp (fneg x), (fneg y) -> fcmp x, y Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/trunk/test/Transforms/InstCombine/fcmp.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=128627&r1=128626&r2=128627&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu Mar 31 05:12:22 2011 @@ -2855,6 +2855,11 @@ } } + // fcmp (fneg x), (fneg y) -> fcmp x, y + Value *X, *Y; + if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y)))) + return new FCmpInst(I.getPredicate(), X, Y); + // fcmp (fpext x), (fpext y) -> fcmp x, y if (FPExtInst *LHSExt = dyn_cast(Op0)) if (FPExtInst *RHSExt = dyn_cast(Op1)) Modified: llvm/trunk/test/Transforms/InstCombine/fcmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fcmp.ll?rev=128627&r1=128626&r2=128627&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/fcmp.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/fcmp.ll Thu Mar 31 05:12:22 2011 @@ -40,3 +40,12 @@ ; CHECK: @test5 ; CHECK-NEXT: fcmp olt float %a, -1.0 } + +define i1 @test6(float %x, float %y) nounwind { + %neg1 = fsub float -0.000000e+00, %x + %neg2 = fsub float -0.000000e+00, %y + %cmp = fcmp ogt float %neg1, %neg2 + ret i1 %cmp +; CHECK: @test6 +; CHECK-NEXT: fcmp ogt float %x, %y +} From fvbommel at gmail.com Thu Mar 31 05:42:50 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Thu, 31 Mar 2011 12:42:50 +0200 Subject: [llvm-commits] [llvm] r128627 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCompares.cpp test/Transforms/InstCombine/fcmp.ll In-Reply-To: <20110331101223.0F1CA2A6C12C@llvm.org> References: <20110331101223.0F1CA2A6C12C@llvm.org> Message-ID: On Thu, Mar 31, 2011 at 12:12 PM, Benjamin Kramer wrote: > + ?// fcmp (fneg x), (fneg y) -> fcmp x, y > + ?Value *X, *Y; > + ?if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y)))) > + ? ?return new FCmpInst(I.getPredicate(), X, Y); Shouldn't this use I.getSwappedPredicate() instead? (-1 > -2, but 1 < 2) From benny.kra at googlemail.com Thu Mar 31 05:46:03 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 31 Mar 2011 10:46:03 -0000 Subject: [llvm-commits] [llvm] r128628 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCompares.cpp test/Transforms/InstCombine/fcmp.ll Message-ID: <20110331104603.D55112A6C12C@llvm.org> Author: d0k Date: Thu Mar 31 05:46:03 2011 New Revision: 128628 URL: http://llvm.org/viewvc/llvm-project?rev=128628&view=rev Log: InstCombine: Fix transform to use the swapped predicate. Thanks Frits! Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/trunk/test/Transforms/InstCombine/fcmp.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=128628&r1=128627&r2=128628&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu Mar 31 05:46:03 2011 @@ -2855,10 +2855,10 @@ } } - // fcmp (fneg x), (fneg y) -> fcmp x, y + // fcmp pred (fneg x), (fneg y) -> fcmp swap(pred) x, y Value *X, *Y; if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y)))) - return new FCmpInst(I.getPredicate(), X, Y); + return new FCmpInst(I.getSwappedPredicate(), X, Y); // fcmp (fpext x), (fpext y) -> fcmp x, y if (FPExtInst *LHSExt = dyn_cast(Op0)) Modified: llvm/trunk/test/Transforms/InstCombine/fcmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fcmp.ll?rev=128628&r1=128627&r2=128628&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/fcmp.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/fcmp.ll Thu Mar 31 05:46:03 2011 @@ -44,7 +44,7 @@ define i1 @test6(float %x, float %y) nounwind { %neg1 = fsub float -0.000000e+00, %x %neg2 = fsub float -0.000000e+00, %y - %cmp = fcmp ogt float %neg1, %neg2 + %cmp = fcmp olt float %neg1, %neg2 ret i1 %cmp ; CHECK: @test6 ; CHECK-NEXT: fcmp ogt float %x, %y From benny.kra at googlemail.com Thu Mar 31 05:52:46 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 31 Mar 2011 12:52:46 +0200 Subject: [llvm-commits] [llvm] r128627 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCompares.cpp test/Transforms/InstCombine/fcmp.ll In-Reply-To: References: <20110331101223.0F1CA2A6C12C@llvm.org> Message-ID: <395ED791-0850-44F9-B0CA-4AF9FF35D9E5@googlemail.com> On 31.03.2011, at 12:42, Frits van Bommel wrote: > On Thu, Mar 31, 2011 at 12:12 PM, Benjamin Kramer > wrote: >> + // fcmp (fneg x), (fneg y) -> fcmp x, y >> + Value *X, *Y; >> + if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y)))) >> + return new FCmpInst(I.getPredicate(), X, Y); > > Shouldn't this use I.getSwappedPredicate() instead? (-1 > -2, but 1 < 2) Oops, fixed in r128628. Thanks for the review :) From geek4civic at gmail.com Thu Mar 31 07:11:33 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Thu, 31 Mar 2011 12:11:33 -0000 Subject: [llvm-commits] [llvm] r128629 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <20110331121133.A76442A6C12C@llvm.org> Author: chapuni Date: Thu Mar 31 07:11:33 2011 New Revision: 128629 URL: http://llvm.org/viewvc/llvm-project?rev=128629&view=rev Log: lib/CodeGen/LiveIntervalAnalysis.cpp: [PR9590] Don't use std::pow(float,float) here. We don't expect the real "powf()" on some hosts (and powf() would be available on other hosts). For consistency, std::pow(double,double) may be called instead. Or, precision issue might attack us, to see unstable regalloc and stack coloring. 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=128629&r1=128628&r2=128629&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Mar 31 07:11:33 2011 @@ -1715,7 +1715,9 @@ // overflow a float. This expression behaves like 10^d for small d, but is // more tempered for large d. At d=200 we get 6.7e33 which leaves a bit of // headroom before overflow. - float lc = std::pow(1 + (100.0f / (loopDepth+10)), (float)loopDepth); + // By the way, powf() might be unavailable here. For consistency, + // We may take pow(double,double). + float lc = std::pow(1 + (100.0 / (loopDepth + 10)), (double)loopDepth); return (isDef + isUse) * lc; } From bigcheesegs at gmail.com Thu Mar 31 08:04:20 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Thu, 31 Mar 2011 13:04:20 -0000 Subject: [llvm-commits] [llvm] r128630 - in /llvm/trunk: include/llvm/Support/FileUtilities.h tools/bugpoint/BugDriver.cpp tools/bugpoint/ExecutionDriver.cpp tools/bugpoint/Miscompilation.cpp tools/bugpoint/ToolRunner.cpp tools/llvm-ld/llvm-ld.cpp Message-ID: <20110331130420.31B502A6C12C@llvm.org> Author: mspencer Date: Thu Mar 31 08:04:19 2011 New Revision: 128630 URL: http://llvm.org/viewvc/llvm-project?rev=128630&view=rev Log: Switch FileRemover from PathV1 to V2. Modified: llvm/trunk/include/llvm/Support/FileUtilities.h llvm/trunk/tools/bugpoint/BugDriver.cpp llvm/trunk/tools/bugpoint/ExecutionDriver.cpp llvm/trunk/tools/bugpoint/Miscompilation.cpp llvm/trunk/tools/bugpoint/ToolRunner.cpp llvm/trunk/tools/llvm-ld/llvm-ld.cpp Modified: llvm/trunk/include/llvm/Support/FileUtilities.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/FileUtilities.h?rev=128630&r1=128629&r2=128630&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/FileUtilities.h (original) +++ llvm/trunk/include/llvm/Support/FileUtilities.h Thu Mar 31 08:04:19 2011 @@ -15,6 +15,7 @@ #ifndef LLVM_SUPPORT_FILEUTILITIES_H #define LLVM_SUPPORT_FILEUTILITIES_H +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" namespace llvm { @@ -37,29 +38,36 @@ /// specified (if deleteIt is true). /// class FileRemover { - sys::Path Filename; + SmallString<128> Filename; bool DeleteIt; public: FileRemover() : DeleteIt(false) {} - explicit FileRemover(const sys::Path &filename, bool deleteIt = true) - : Filename(filename), DeleteIt(deleteIt) {} + explicit FileRemover(const Twine& filename, bool deleteIt = true) + : DeleteIt(deleteIt) { + filename.toVector(Filename); + } ~FileRemover() { if (DeleteIt) { // Ignore problems deleting the file. - Filename.eraseFromDisk(); + bool existed; + sys::fs::remove(Filename.str(), existed); } } /// setFile - Give ownership of the file to the FileRemover so it will /// be removed when the object is destroyed. If the FileRemover already /// had ownership of a file, remove it first. - void setFile(const sys::Path &filename, bool deleteIt = true) { - if (DeleteIt) - Filename.eraseFromDisk(); + void setFile(const Twine& filename, bool deleteIt = true) { + if (DeleteIt) { + // Ignore problems deleting the file. + bool existed; + sys::fs::remove(Filename.str(), existed); + } - Filename = filename; + Filename.clear(); + filename.toVector(Filename); DeleteIt = deleteIt; } Modified: llvm/trunk/tools/bugpoint/BugDriver.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/BugDriver.cpp?rev=128630&r1=128629&r2=128630&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/BugDriver.cpp (original) +++ llvm/trunk/tools/bugpoint/BugDriver.cpp Thu Mar 31 08:04:19 2011 @@ -194,7 +194,7 @@ // Make sure the reference output file gets deleted on exit from this // function, if appropriate. sys::Path ROF(ReferenceOutputFile); - FileRemover RemoverInstance(ROF, CreatedOutput && !SaveTemps); + FileRemover RemoverInstance(ROF.str(), CreatedOutput && !SaveTemps); // Diff the output of the raw program against the reference output. If it // matches, then we assume there is a miscompilation bug and try to Modified: llvm/trunk/tools/bugpoint/ExecutionDriver.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ExecutionDriver.cpp?rev=128630&r1=128629&r2=128630&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/ExecutionDriver.cpp (original) +++ llvm/trunk/tools/bugpoint/ExecutionDriver.cpp Thu Mar 31 08:04:19 2011 @@ -323,7 +323,7 @@ } // Remove the temporary bitcode file when we are done. - FileRemover BitcodeFileRemover(BitcodeFile, !SaveTemps); + FileRemover BitcodeFileRemover(BitcodeFile.str(), !SaveTemps); // Actually compile the program! Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit); @@ -364,7 +364,8 @@ // Remove the temporary bitcode file when we are done. sys::Path BitcodePath(BitcodeFile); - FileRemover BitcodeFileRemover(BitcodePath, CreatedBitcode && !SaveTemps); + FileRemover BitcodeFileRemover(BitcodePath.str(), + CreatedBitcode && !SaveTemps); if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output"; Modified: llvm/trunk/tools/bugpoint/Miscompilation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/Miscompilation.cpp?rev=128630&r1=128629&r2=128630&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/Miscompilation.cpp (original) +++ llvm/trunk/tools/bugpoint/Miscompilation.cpp Thu Mar 31 08:04:19 2011 @@ -943,7 +943,7 @@ } delete Test; - FileRemover TestModuleBCRemover(TestModuleBC, !SaveTemps); + FileRemover TestModuleBCRemover(TestModuleBC.str(), !SaveTemps); // Make the shared library sys::Path SafeModuleBC("bugpoint.safe.bc"); @@ -959,14 +959,14 @@ exit(1); } - FileRemover SafeModuleBCRemover(SafeModuleBC, !SaveTemps); + FileRemover SafeModuleBCRemover(SafeModuleBC.str(), !SaveTemps); std::string SharedObject = BD.compileSharedObject(SafeModuleBC.str(), Error); if (!Error.empty()) return false; delete Safe; - FileRemover SharedObjectRemover(sys::Path(SharedObject), !SaveTemps); + FileRemover SharedObjectRemover(SharedObject, !SaveTemps); // Run the code generator on the `Test' code, loading the shared library. // The function returns whether or not the new output differs from reference. Modified: llvm/trunk/tools/bugpoint/ToolRunner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ToolRunner.cpp?rev=128630&r1=128629&r2=128630&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/ToolRunner.cpp (original) +++ llvm/trunk/tools/bugpoint/ToolRunner.cpp Thu Mar 31 08:04:19 2011 @@ -503,7 +503,7 @@ sys::Path OutputAsmFile; GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, MemoryLimit); - FileRemover OutFileRemover(OutputAsmFile, !SaveTemps); + FileRemover OutFileRemover(OutputAsmFile.str(), !SaveTemps); std::vector GCCArgs(ArgsForGCC); GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end()); @@ -675,7 +675,7 @@ sys::Path OutputCFile; OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit); - FileRemover CFileRemove(OutputCFile, !SaveTemps); + FileRemover CFileRemove(OutputCFile.str(), !SaveTemps); std::vector GCCArgs(ArgsForGCC); GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end()); @@ -851,7 +851,7 @@ errs() << "\n"; ); - FileRemover OutputBinaryRemover(OutputBinary, !SaveTemps); + FileRemover OutputBinaryRemover(OutputBinary.str(), !SaveTemps); if (RemoteClientPath.isEmpty()) { DEBUG(errs() << ""); Modified: llvm/trunk/tools/llvm-ld/llvm-ld.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-ld/llvm-ld.cpp?rev=128630&r1=128629&r2=128630&view=diff ============================================================================== --- llvm/trunk/tools/llvm-ld/llvm-ld.cpp (original) +++ llvm/trunk/tools/llvm-ld/llvm-ld.cpp Thu Mar 31 08:04:19 2011 @@ -552,12 +552,12 @@ } // Arrange for the bitcode output file to be deleted on any errors. - BitcodeOutputRemover.setFile(sys::Path(BitcodeOutputFilename)); + BitcodeOutputRemover.setFile(BitcodeOutputFilename); sys::RemoveFileOnSignal(sys::Path(BitcodeOutputFilename)); // Arrange for the output file to be deleted on any errors. if (!LinkAsLibrary) { - OutputRemover.setFile(sys::Path(OutputFilename)); + OutputRemover.setFile(OutputFilename); sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } @@ -657,7 +657,7 @@ AssemblyFile.appendSuffix("s"); // Mark the output files for removal. - FileRemover AssemblyFileRemover(AssemblyFile); + FileRemover AssemblyFileRemover(AssemblyFile.str()); sys::RemoveFileOnSignal(AssemblyFile); // Determine the locations of the llc and gcc programs. @@ -684,7 +684,7 @@ CFile.appendSuffix("cbe.c"); // Mark the output files for removal. - FileRemover CFileRemover(CFile); + FileRemover CFileRemover(CFile.str()); sys::RemoveFileOnSignal(CFile); // Determine the locations of the llc and gcc programs. From bigcheesegs at gmail.com Thu Mar 31 08:06:40 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Thu, 31 Mar 2011 13:06:40 -0000 Subject: [llvm-commits] [llvm] r128631 - in /llvm/trunk: include/llvm/Support/FileUtilities.h tools/bugpoint/BugDriver.cpp tools/bugpoint/Miscompilation.cpp Message-ID: <20110331130640.283712A6C12C@llvm.org> Author: mspencer Date: Thu Mar 31 08:06:39 2011 New Revision: 128631 URL: http://llvm.org/viewvc/llvm-project?rev=128631&view=rev Log: Fix whitespace. Modified: llvm/trunk/include/llvm/Support/FileUtilities.h llvm/trunk/tools/bugpoint/BugDriver.cpp llvm/trunk/tools/bugpoint/Miscompilation.cpp Modified: llvm/trunk/include/llvm/Support/FileUtilities.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/FileUtilities.h?rev=128631&r1=128630&r2=128631&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/FileUtilities.h (original) +++ llvm/trunk/include/llvm/Support/FileUtilities.h Thu Mar 31 08:06:39 2011 @@ -22,7 +22,7 @@ /// DiffFilesWithTolerance - Compare the two files specified, returning 0 if /// the files match, 1 if they are different, and 2 if there is a file error. - /// This function allows you to specify an absolete and relative FP error that + /// This function allows you to specify an absolute and relative FP error that /// is allowed to exist. If you specify a string to fill in for the error /// option, it will set the string to an error message if an error occurs, or /// if the files are different. Modified: llvm/trunk/tools/bugpoint/BugDriver.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/BugDriver.cpp?rev=128631&r1=128630&r2=128631&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/BugDriver.cpp (original) +++ llvm/trunk/tools/bugpoint/BugDriver.cpp Thu Mar 31 08:06:39 2011 @@ -71,7 +71,7 @@ LLVMContext& ctxt) : Context(ctxt), ToolName(toolname), ReferenceOutputFile(OutputFile), Program(0), Interpreter(0), SafeInterpreter(0), gcc(0), - run_find_bugs(find_bugs), Timeout(timeout), + run_find_bugs(find_bugs), Timeout(timeout), MemoryLimit(memlimit), UseValgrind(use_valgrind) {} BugDriver::~BugDriver() { @@ -97,7 +97,7 @@ if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getHostTriple()); - + TargetTriple.setTriple(TheTriple.getTriple()); } @@ -118,7 +118,7 @@ // Load the first input file. Program = ParseInputFile(Filenames[0], Context); if (Program == 0) return true; - + outs() << "Read input file : '" << Filenames[0] << "'\n"; for (unsigned i = 1, e = Filenames.size(); i != e; ++i) { @@ -152,12 +152,12 @@ return runManyPasses(PassesToRun, ErrMsg); } - // If we're not running as a child, the first thing that we must do is - // determine what the problem is. Does the optimization series crash the - // compiler, or does it produce illegal code? We make the top-level - // decision by trying to run all of the passes on the the input program, - // which should generate a bitcode file. If it does generate a bitcode - // file, then we know the compiler didn't crash, so try to diagnose a + // If we're not running as a child, the first thing that we must do is + // determine what the problem is. Does the optimization series crash the + // compiler, or does it produce illegal code? We make the top-level + // decision by trying to run all of the passes on the the input program, + // which should generate a bitcode file. If it does generate a bitcode + // file, then we know the compiler didn't crash, so try to diagnose a // miscompilation. if (!PassesToRun.empty()) { outs() << "Running selected passes on program to test for crash: "; @@ -197,7 +197,7 @@ FileRemover RemoverInstance(ROF.str(), CreatedOutput && !SaveTemps); // Diff the output of the raw program against the reference output. If it - // matches, then we assume there is a miscompilation bug and try to + // matches, then we assume there is a miscompilation bug and try to // diagnose it. outs() << "*** Checking the code generator...\n"; bool Diff = diffProgram(Program, "", "", false, &Error); Modified: llvm/trunk/tools/bugpoint/Miscompilation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/Miscompilation.cpp?rev=128631&r1=128630&r2=128631&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/Miscompilation.cpp (original) +++ llvm/trunk/tools/bugpoint/Miscompilation.cpp Thu Mar 31 08:06:39 2011 @@ -34,12 +34,12 @@ } namespace { - static llvm::cl::opt - DisableLoopExtraction("disable-loop-extraction", + static llvm::cl::opt + DisableLoopExtraction("disable-loop-extraction", cl::desc("Don't extract loops when searching for miscompilations"), cl::init(false)); - static llvm::cl::opt - DisableBlockExtraction("disable-block-extraction", + static llvm::cl::opt + DisableBlockExtraction("disable-block-extraction", cl::desc("Don't extract blocks when searching for miscompilations"), cl::init(false)); @@ -75,7 +75,7 @@ BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); exit(BD.debugOptimizerCrash()); } - + // Check to see if the finished program matches the reference output... bool Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", true /*delete bitcode*/, &Error); @@ -309,7 +309,7 @@ bool MadeChange = false; while (1) { if (BugpointIsInterrupted) return MadeChange; - + ValueToValueMapTy VMap; Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap); Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, @@ -354,7 +354,7 @@ BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to-le.bc", ToOptimizeLoopExtracted); - errs() << "Please submit the " + errs() << "Please submit the " << OutputPrefix << "-loop-extract-fail-*.bc files.\n"; delete ToOptimize; delete ToNotOptimize; @@ -409,9 +409,9 @@ MiscompiledFunctions.clear(); for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first); - + assert(NewF && "Function not found??"); - assert(NewF->getFunctionType() == MisCompFunctions[i].second && + assert(NewF->getFunctionType() == MisCompFunctions[i].second && "found wrong function type?"); MiscompiledFunctions.push_back(NewF); } @@ -523,7 +523,7 @@ std::vector &MiscompiledFunctions, std::string &Error) { if (BugpointIsInterrupted) return false; - + std::vector Blocks; for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) for (Function::iterator I = MiscompiledFunctions[i]->begin(), @@ -593,7 +593,7 @@ for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first); assert(NewF && "Function not found??"); - assert(NewF->getFunctionType() == MisCompFunctions[i].second && + assert(NewF->getFunctionType() == MisCompFunctions[i].second && "Function has wrong type??"); MiscompiledFunctions.push_back(NewF); } @@ -731,7 +731,7 @@ << getPassesString(getPassesToRun()) << '\n'; EmitProgressBitcode(Program, "passinput"); - std::vector MiscompiledFunctions = + std::vector MiscompiledFunctions = DebugAMiscompilation(*this, TestOptimizer, *Error); if (!Error->empty()) return; @@ -845,7 +845,7 @@ // Create a new global to hold the cached function pointer. Constant *NullPtr = ConstantPointerNull::get(F->getType()); GlobalVariable *Cache = - new GlobalVariable(*F->getParent(), F->getType(), + new GlobalVariable(*F->getParent(), F->getType(), false, GlobalValue::InternalLinkage, NullPtr,F->getName()+".fpcache"); From bruno.cardoso at gmail.com Thu Mar 31 09:52:28 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Thu, 31 Mar 2011 14:52:28 -0000 Subject: [llvm-commits] [llvm] r128632 - in /llvm/trunk: lib/Target/ARM/ARMAddressingModes.h lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.h test/MC/ARM/arm_addrmode2.s Message-ID: <20110331145228.F0EEA2A6C12E@llvm.org> Author: bruno Date: Thu Mar 31 09:52:28 2011 New Revision: 128632 URL: http://llvm.org/viewvc/llvm-project?rev=128632&view=rev Log: Reapply r128585 without generating a lib depedency cycle. An updated log: - Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and {STR,LDC}{2}_{PRE,POST} fixing the encoding wherever is possible. - Move all instructions which use am2offset without a pattern to use addrmode2. - Add a new encoding bit to describe the index mode used and teach printAddrMode2Operand to check by the addressing mode which index mode to print. - Testcases Added: llvm/trunk/test/MC/ARM/arm_addrmode2.s Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h llvm/trunk/lib/Target/ARM/ARMBaseInfo.h llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h llvm/trunk/lib/Target/ARM/ARMInstrFormats.td llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAddressingModes.h?rev=128632&r1=128631&r2=128632&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAddressingModes.h (original) +++ llvm/trunk/lib/Target/ARM/ARMAddressingModes.h Thu Mar 31 09:52:28 2011 @@ -408,16 +408,18 @@ // // The first operand is always a Reg. The second operand is a reg if in // reg/reg form, otherwise it's reg#0. The third field encodes the operation - // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. + // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The + // forth operand 16-17 encodes the index mode. // // If this addressing mode is a frame index (before prolog/epilog insertion // and code rewriting), this operand will have the form: FI#, reg0, // with no shift amount for the frame offset. // - static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO) { + static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, + unsigned IdxMode = 0) { assert(Imm12 < (1 << 12) && "Imm too large!"); bool isSub = Opc == sub; - return Imm12 | ((int)isSub << 12) | (SO << 13); + return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ; } static inline unsigned getAM2Offset(unsigned AM2Opc) { return AM2Opc & ((1 << 12)-1); @@ -426,7 +428,10 @@ return ((AM2Opc >> 12) & 1) ? sub : add; } static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) { - return (ShiftOpc)(AM2Opc >> 13); + return (ShiftOpc)((AM2Opc >> 13) & 7); + } + static inline unsigned getAM2IdxMode(unsigned AM2Opc) { + return (AM2Opc >> 16); } Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=128632&r1=128631&r2=128632&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Thu Mar 31 09:52:28 2011 @@ -200,6 +200,59 @@ } namespace ARMII { + + /// ARM Index Modes + enum IndexMode { + IndexModeNone = 0, + IndexModePre = 1, + IndexModePost = 2, + IndexModeUpd = 3 + }; + + /// ARM Addressing Modes + enum AddrMode { + AddrModeNone = 0, + AddrMode1 = 1, + AddrMode2 = 2, + AddrMode3 = 3, + AddrMode4 = 4, + AddrMode5 = 5, + AddrMode6 = 6, + AddrModeT1_1 = 7, + AddrModeT1_2 = 8, + AddrModeT1_4 = 9, + AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data + AddrModeT2_i12 = 11, + AddrModeT2_i8 = 12, + AddrModeT2_so = 13, + AddrModeT2_pc = 14, // +/- i12 for pc relative data + AddrModeT2_i8s4 = 15, // i8 * 4 + AddrMode_i12 = 16 + }; + + inline static const char *AddrModeToString(AddrMode addrmode) { + switch (addrmode) { + default: llvm_unreachable("Unknown memory operation"); + case AddrModeNone: return "AddrModeNone"; + case AddrMode1: return "AddrMode1"; + case AddrMode2: return "AddrMode2"; + case AddrMode3: return "AddrMode3"; + case AddrMode4: return "AddrMode4"; + case AddrMode5: return "AddrMode5"; + case AddrMode6: return "AddrMode6"; + case AddrModeT1_1: return "AddrModeT1_1"; + case AddrModeT1_2: return "AddrModeT1_2"; + case AddrModeT1_4: return "AddrModeT1_4"; + case AddrModeT1_s: return "AddrModeT1_s"; + case AddrModeT2_i12: return "AddrModeT2_i12"; + case AddrModeT2_i8: return "AddrModeT2_i8"; + case AddrModeT2_so: return "AddrModeT2_so"; + case AddrModeT2_pc: return "AddrModeT2_pc"; + case AddrModeT2_i8s4: return "AddrModeT2_i8s4"; + case AddrMode_i12: return "AddrMode_i12"; + } + } + /// Target Operand Flag enum. enum TOF { //===------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=128632&r1=128631&r2=128632&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Thu Mar 31 09:52:28 2011 @@ -34,25 +34,7 @@ //===------------------------------------------------------------------===// // This four-bit field describes the addressing mode used. - - AddrModeMask = 0x1f, - AddrModeNone = 0, - AddrMode1 = 1, - AddrMode2 = 2, - AddrMode3 = 3, - AddrMode4 = 4, - AddrMode5 = 5, - AddrMode6 = 6, - AddrModeT1_1 = 7, - AddrModeT1_2 = 8, - AddrModeT1_4 = 9, - AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data - AddrModeT2_i12 = 11, - AddrModeT2_i8 = 12, - AddrModeT2_so = 13, - AddrModeT2_pc = 14, // +/- i12 for pc relative data - AddrModeT2_i8s4 = 15, // i8 * 4 - AddrMode_i12 = 16, + AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h // Size* - Flags to keep track of the size of an instruction. SizeShift = 5, @@ -64,11 +46,9 @@ // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load // and store ops only. Generic "updating" flag is used for ld/st multiple. + // The index mode enums are declared in ARMBaseInfo.h IndexModeShift = 8, IndexModeMask = 3 << IndexModeShift, - IndexModePre = 1, - IndexModePost = 2, - IndexModeUpd = 3, //===------------------------------------------------------------------===// // Instruction encoding formats. Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128632&r1=128631&r2=128632&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu Mar 31 09:52:28 2011 @@ -515,15 +515,15 @@ : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, pattern> { // AM2 store w/ two operands: (GPR, am2offset) + // {17-14} Rn // {13} 1 == Rm, 0 == imm12 // {12} isAdd // {11-0} imm12/Rm - bits<14> offset; - bits<4> Rn; - let Inst{25} = offset{13}; - let Inst{23} = offset{12}; - let Inst{19-16} = Rn; - let Inst{11-0} = offset{11-0}; + bits<18> addr; + let Inst{25} = addr{13}; + let Inst{23} = addr{12}; + let Inst{19-16} = addr{17-14}; + let Inst{11-0} = addr{11-0}; } // addrmode3 instructions Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128632&r1=128631&r2=128632&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Mar 31 09:52:28 2011 @@ -498,6 +498,12 @@ let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } +def MemMode2AsmOperand : AsmOperandClass { + let Name = "MemMode2"; + let SuperClasses = []; + let ParserMethod = "tryParseMemMode2Operand"; +} + // addrmode2 := reg +/- imm12 // := reg +/- reg shop imm // @@ -505,6 +511,7 @@ ComplexPattern { let EncoderMethod = "getAddrMode2OpValue"; let PrintMethod = "printAddrMode2Operand"; + let ParserMatchClass = MemMode2AsmOperand; let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } @@ -1656,20 +1663,21 @@ let Inst{23} = addr{12}; let Inst{19-16} = addr{17-14}; let Inst{11-0} = addr{11-0}; + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; } def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), - (ins GPR:$Rn, am2offset:$offset), - IndexModePost, LdFrm, itin, - opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> { + (ins addrmode2:$addr), IndexModePost, LdFrm, itin, + opc, "\t$Rt, $addr", "$addr.base = $Rn_wb", []> { + // {17-14} Rn // {13} 1 == Rm, 0 == imm12 // {12} isAdd // {11-0} imm12/Rm - bits<14> offset; - bits<4> Rn; - let Inst{25} = offset{13}; - let Inst{23} = offset{12}; - let Inst{19-16} = Rn; - let Inst{11-0} = offset{11-0}; + bits<18> addr; + let Inst{25} = addr{13}; + let Inst{23} = addr{12}; + let Inst{19-16} = addr{17-14}; + let Inst{11-0} = addr{11-0}; + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; } } @@ -1714,17 +1722,35 @@ // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. let mayLoad = 1, neverHasSideEffects = 1 in { -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb), - (ins GPR:$base, am2offset:$offset), IndexModePost, - LdFrm, IIC_iLoad_ru, - "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { +def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb), + (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru, + "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { + // {17-14} Rn + // {13} 1 == Rm, 0 == imm12 + // {12} isAdd + // {11-0} imm12/Rm + bits<18> addr; + let Inst{25} = addr{13}; + let Inst{23} = addr{12}; let Inst{21} = 1; // overwrite -} -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb), - (ins GPR:$base, am2offset:$offset), IndexModePost, - LdFrm, IIC_iLoad_bh_ru, - "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { + let Inst{19-16} = addr{17-14}; + let Inst{11-0} = addr{11-0}; + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; +} +def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), + (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru, + "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { + // {17-14} Rn + // {13} 1 == Rm, 0 == imm12 + // {12} isAdd + // {11-0} imm12/Rm + bits<18> addr; + let Inst{25} = addr{13}; + let Inst{23} = addr{12}; let Inst{21} = 1; // overwrite + let Inst{19-16} = addr{17-14}; + let Inst{11-0} = addr{11-0}; + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; } def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb), (ins GPR:$base, am3offset:$offset), IndexModePost, @@ -1818,20 +1844,20 @@ // STRT, STRBT, and STRHT are for disassembly only. -def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn,am2offset:$offset), +def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), IndexModePost, StFrm, IIC_iStore_ru, - "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", + "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb", [/* For disassembly only; pattern left blank */]> { let Inst{21} = 1; // overwrite + let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; } -def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), +def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), IndexModePost, StFrm, IIC_iStore_bh_ru, - "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", + "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb", [/* For disassembly only; pattern left blank */]> { let Inst{21} = 1; // overwrite + let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; } def STRHT: AI3sthpo<(outs GPR:$base_wb), @@ -3391,8 +3417,9 @@ let Inst{23-20} = opc1; } -class ACI - : I + : I { let Inst{27-25} = 0b110; } @@ -3411,7 +3438,7 @@ def _PRE : ACI<(outs), (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - opc, "\tp$cop, cr$CRd, $addr!"> { + opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> { let Inst{31-28} = op31_28; let Inst{24} = 1; // P = 1 let Inst{21} = 1; // W = 1 @@ -3420,8 +3447,8 @@ } def _POST : ACI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), - opc, "\tp$cop, cr$CRd, [$base], $offset"> { + (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), + opc, "\tp$cop, cr$CRd, $addr", IndexModePost> { let Inst{31-28} = op31_28; let Inst{24} = 0; // P = 0 let Inst{21} = 1; // W = 1 @@ -3452,7 +3479,7 @@ def L_PRE : ACI<(outs), (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> { let Inst{31-28} = op31_28; let Inst{24} = 1; // P = 1 let Inst{21} = 1; // W = 1 @@ -3461,8 +3488,8 @@ } def L_POST : ACI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> { + (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr", IndexModePost> { let Inst{31-28} = op31_28; let Inst{24} = 0; // P = 0 let Inst{21} = 1; // W = 1 Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128632&r1=128631&r2=128632&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Mar 31 09:52:28 2011 @@ -48,7 +48,8 @@ bool TryParseRegisterWithWriteBack(SmallVectorImpl &); bool TryParseShiftRegister(SmallVectorImpl &); bool ParseRegisterList(SmallVectorImpl &); - bool ParseMemory(SmallVectorImpl &); + bool ParseMemory(SmallVectorImpl &, + ARMII::AddrMode AddrMode); bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic); bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); const MCExpr *ApplyPrefixToExpr(const MCExpr *E, @@ -95,6 +96,14 @@ SmallVectorImpl&); OperandMatchResultTy tryParseMSRMaskOperand( SmallVectorImpl&); + OperandMatchResultTy tryParseMemMode2Operand( + SmallVectorImpl&); + + // Asm Match Converter Methods + bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &); + bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &); public: ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) @@ -172,6 +181,7 @@ /// Combined record for all forms of ARM address expressions. struct { + ARMII::AddrMode AddrMode; unsigned BaseRegNum; union { unsigned RegNum; ///< Offset register num, when OffsetIsReg. @@ -293,7 +303,9 @@ /// @name Memory Operand Accessors /// @{ - + ARMII::AddrMode getMemAddrMode() const { + return Mem.AddrMode; + } unsigned getMemBaseRegNum() const { return Mem.BaseRegNum; } @@ -338,6 +350,27 @@ bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } bool isMemory() const { return Kind == Memory; } bool isShifter() const { return Kind == Shifter; } + bool isMemMode2() const { + if (getMemAddrMode() != ARMII::AddrMode2) + return false; + + if (getMemOffsetIsReg()) + return true; + + if (getMemNegative() && + !(getMemPostindexed() || getMemPreindexed())) + return false; + + const MCConstantExpr *CE = dyn_cast(getMemOffset()); + if (!CE) return false; + int64_t Value = CE->getValue(); + + // The offset must be in the range 0-4095 (imm12). + if (Value > 4095 || Value < -4095) + return false; + + return true; + } bool isMemMode5() const { if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || getMemNegative()) @@ -465,6 +498,47 @@ "No offset operand support in mode 7"); } + void addMemMode2Operands(MCInst &Inst, unsigned N) const { + assert(isMemMode2() && "Invalid mode or number of operands!"); + Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); + unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); + + if (getMemOffsetIsReg()) { + Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); + + ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; + ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; + int64_t ShiftAmount = 0; + + if (getMemOffsetRegShifted()) { + ShOpc = getMemShiftType(); + const MCConstantExpr *CE = + dyn_cast(getMemShiftAmount()); + ShiftAmount = CE->getValue(); + } + + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, + ShOpc, IdxMode))); + return; + } + + // Create a operand placeholder to always yield the same number of operands. + Inst.addOperand(MCOperand::CreateReg(0)); + + // FIXME: #-0 is encoded differently than #0. Does the parser preserve + // the difference? + const MCConstantExpr *CE = dyn_cast(getMemOffset()); + assert(CE && "Non-constant mode 2 offset operand!"); + int64_t Offset = CE->getValue(); + + if (Offset >= 0) + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, + Offset, ARM_AM::no_shift, IdxMode))); + else + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, + -Offset, ARM_AM::no_shift, IdxMode))); + } + void addMemMode5Operands(MCInst &Inst, unsigned N) const { assert(N == 2 && isMemMode5() && "Invalid number of operands!"); @@ -599,9 +673,9 @@ return Op; } - static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, - const MCExpr *Offset, int OffsetRegNum, - bool OffsetRegShifted, + static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, + bool OffsetIsReg, const MCExpr *Offset, + int OffsetRegNum, bool OffsetRegShifted, enum ARM_AM::ShiftOpc ShiftType, const MCExpr *ShiftAmount, bool Preindexed, bool Postindexed, bool Negative, bool Writeback, @@ -618,6 +692,7 @@ "Cannot have expression offset and register offset!"); ARMOperand *Op = new ARMOperand(Memory); + Op->Mem.AddrMode = AddrMode; Op->Mem.BaseRegNum = BaseRegNum; Op->Mem.OffsetIsReg = OffsetIsReg; if (OffsetIsReg) @@ -689,7 +764,8 @@ break; case Memory: OS << " &Operands) { + SMLoc S = Parser.getTok().getLoc(); + const AsmToken &Tok = Parser.getTok(); + assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\""); + + if (ParseMemory(Operands, ARMII::AddrMode2)) + return MatchOperand_NoMatch; + + return MatchOperand_Success; +} + +/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. +/// Needed here because the Asm Gen Matcher can't handle properly tied operands +/// when they refer multiple MIOperands inside a single one. +bool ARMAsmParser:: +CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &Operands) { + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); + + // Create a writeback register dummy placeholder. + Inst.addOperand(MCOperand::CreateImm(0)); + + ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); + return true; +} + +/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. +/// Needed here because the Asm Gen Matcher can't handle properly tied operands +/// when they refer multiple MIOperands inside a single one. +bool ARMAsmParser:: +CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &Operands) { + // Create a writeback register dummy placeholder. + Inst.addOperand(MCOperand::CreateImm(0)); + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); + ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); + return true; +} + /// Parse an ARM memory expression, return false if successful else return true /// or an error. The first token must be a '[' when called. /// /// TODO Only preindexing and postindexing addressing are started, unindexed /// with option, etc are still to do. bool ARMAsmParser:: -ParseMemory(SmallVectorImpl &Operands) { +ParseMemory(SmallVectorImpl &Operands, + ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { SMLoc S, E; assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a Left Bracket"); @@ -1196,6 +1316,9 @@ ExclaimTok.getLoc()); Writeback = true; Parser.Lex(); // Eat exclaim token + } else { // In addressing mode 2, pre-indexed mode always end with "!" + if (AddrMode == ARMII::AddrMode2) + Preindexed = false; } } else { // The "[Rn" we have so far was not followed by a comma. @@ -1231,11 +1354,10 @@ Offset = MCConstantExpr::Create(0, getContext()); } - Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, - OffsetRegNum, OffsetRegShifted, - ShiftType, ShiftAmount, Preindexed, - Postindexed, Negative, Writeback, - S, E)); + Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, + Offset, OffsetRegNum, OffsetRegShifted, + ShiftType, ShiftAmount, Preindexed, + Postindexed, Negative, Writeback, S, E)); if (WBOp) Operands.push_back(WBOp); Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128632&r1=128631&r2=128632&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Thu Mar 31 09:52:28 2011 @@ -643,8 +643,11 @@ if (PW) { MI.addOperand(MCOperand::CreateReg(0)); ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; + const TargetInstrDesc &TID = ARMInsts[Opcode]; + unsigned IndexMode = + (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << 2, - ARM_AM::no_shift); + ARM_AM::no_shift, IndexMode); MI.addOperand(MCOperand::CreateImm(Offset)); OpIdx = 5; } else { @@ -1073,6 +1076,8 @@ return false; ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; + unsigned IndexMode = + (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; if (getIBit(insn) == 0) { // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2). // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already @@ -1084,7 +1089,8 @@ // Disassemble the 12-bit immediate offset. unsigned Imm12 = slice(insn, 11, 0); - unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift); + unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift, + IndexMode); MI.addOperand(MCOperand::CreateImm(Offset)); OpIdx += 1; } else { @@ -1099,7 +1105,7 @@ // A8.4.1. Possible rrx or shift amount of 32... getImmShiftSE(ShOp, ShImm); MI.addOperand(MCOperand::CreateImm( - ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp))); + ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, IndexMode))); OpIdx += 2; } Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=128632&r1=128631&r2=128632&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Thu Mar 31 09:52:28 2011 @@ -181,18 +181,12 @@ } } - -void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, - raw_ostream &O) { +void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, + raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(Op); const MCOperand &MO2 = MI->getOperand(Op+1); const MCOperand &MO3 = MI->getOperand(Op+2); - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. - printOperand(MI, Op, O); - return; - } - O << "[" << getRegisterName(MO1.getReg()); if (!MO2.getReg()) { @@ -215,6 +209,50 @@ O << "]"; } +void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, + raw_ostream &O) { + const MCOperand &MO1 = MI->getOperand(Op); + const MCOperand &MO2 = MI->getOperand(Op+1); + const MCOperand &MO3 = MI->getOperand(Op+2); + + O << "[" << getRegisterName(MO1.getReg()) << "], "; + + if (!MO2.getReg()) { + unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); + O << '#' + << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) + << ImmOffs; + return; + } + + O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) + << getRegisterName(MO2.getReg()); + + if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) + O << ", " + << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) + << " #" << ShImm; +} + +void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, + raw_ostream &O) { + const MCOperand &MO1 = MI->getOperand(Op); + + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. + printOperand(MI, Op, O); + return; + } + + const MCOperand &MO3 = MI->getOperand(Op+2); + unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm()); + + if (IdxMode == ARMII::IndexModePost) { + printAM2PostIndexOp(MI, Op, O); + return; + } + printAM2PreOrOffsetIndexOp(MI, Op, O); +} + void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) { Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=128632&r1=128631&r2=128632&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Thu Mar 31 09:52:28 2011 @@ -42,7 +42,11 @@ void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, + raw_ostream &O); void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); Added: llvm/trunk/test/MC/ARM/arm_addrmode2.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128632&view=auto ============================================================================== --- llvm/trunk/test/MC/ARM/arm_addrmode2.s (added) +++ llvm/trunk/test/MC/ARM/arm_addrmode2.s Thu Mar 31 09:52:28 2011 @@ -0,0 +1,38 @@ +@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | FileCheck %s + +@ Post-indexed +@ CHECK: ldrt r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6] +@ CHECK: ldrt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6] +@ CHECK: ldrt r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4] +@ CHECK: ldrbt r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6] +@ CHECK: ldrbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6] +@ CHECK: ldrbt r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4] +@ CHECK: strt r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6] +@ CHECK: strt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6] +@ CHECK: strt r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4] +@ CHECK: strbt r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6] +@ CHECK: strbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6] +@ CHECK: strbt r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4] +@ CHECK: ldr r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0x90,0xe6] +@ CHECK: ldrb r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xd0,0xe6] + ldrt r1, [r0], r2 + ldrt r1, [r0], r2, lsr #3 + ldrt r1, [r0], #4 + ldrbt r1, [r0], r2 + ldrbt r1, [r0], r2, lsr #3 + ldrbt r1, [r0], #4 + strt r1, [r0], r2 + strt r1, [r0], r2, lsr #3 + strt r1, [r0], #4 + strbt r1, [r0], r2 + strbt r1, [r0], r2, lsr #3 + strbt r1, [r0], #4 + ldr r1, [r0], r2, lsr #3 + ldrb r1, [r0], r2, lsr #3 + +@ Pre-indexed +@ CHECK: ldr r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7] +@ CHECK: ldrb r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7] + ldr r1, [r0, r2, lsr #3]! + ldrb r1, [r0, r2, lsr #3]! + From richard at xmos.com Thu Mar 31 10:13:13 2011 From: richard at xmos.com (Richard Osborne) Date: Thu, 31 Mar 2011 15:13:13 -0000 Subject: [llvm-commits] [llvm] r128633 - in /llvm/trunk: include/llvm/IntrinsicsXCore.td lib/Target/XCore/XCoreInstrInfo.td test/CodeGen/XCore/threads.ll Message-ID: <20110331151313.DD0C62A6C12C@llvm.org> Author: friedgold Date: Thu Mar 31 10:13:13 2011 New Revision: 128633 URL: http://llvm.org/viewvc/llvm-project?rev=128633&view=rev Log: Add XCore intrinsics for initializing / starting / synchronizing threads. Added: llvm/trunk/test/CodeGen/XCore/threads.ll Modified: llvm/trunk/include/llvm/IntrinsicsXCore.td llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Modified: llvm/trunk/include/llvm/IntrinsicsXCore.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsXCore.td?rev=128633&r1=128632&r2=128633&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsXCore.td (original) +++ llvm/trunk/include/llvm/IntrinsicsXCore.td Thu Mar 31 10:13:13 2011 @@ -69,4 +69,21 @@ def int_xcore_checkevent : Intrinsic<[llvm_ptr_ty],[llvm_ptr_ty]>; def int_xcore_clre : Intrinsic<[],[],[]>; + + // Intrinsics for threads. + def int_xcore_getst : Intrinsic <[llvm_anyptr_ty],[llvm_anyptr_ty], + [NoCapture<0>]>; + def int_xcore_msync : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>; + def int_xcore_ssync : Intrinsic <[],[]>; + def int_xcore_mjoin : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>; + def int_xcore_initsp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty], + [NoCapture<0>]>; + def int_xcore_initpc : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty], + [NoCapture<0>]>; + def int_xcore_initlr : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty], + [NoCapture<0>]>; + def int_xcore_initcp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty], + [NoCapture<0>]>; + def int_xcore_initdp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty], + [NoCapture<0>]>; } Modified: llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td?rev=128633&r1=128632&r2=128633&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td (original) +++ llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Thu Mar 31 10:13:13 2011 @@ -739,7 +739,7 @@ } // Two operand short -// TODO getr, getst +// TODO eet, eef, testwct, tsetmr, sext (reg), zext (reg) def NOT : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b), "not $dst, $b", [(set GRRegs:$dst, (not GRRegs:$b))]>; @@ -748,8 +748,6 @@ "neg $dst, $b", [(set GRRegs:$dst, (ineg GRRegs:$b))]>; -// TODO setd, eet, eef, testwct, tinitpc, tinitdp, -// tinitsp, tinitcp, tsetmr, sext (reg), zext (reg) let Constraints = "$src1 = $dst" in { let neverHasSideEffects = 1 in def SEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), @@ -837,9 +835,29 @@ "setd res[$r], $val", [(int_xcore_setd GRRegs:$r, GRRegs:$val)]>; +def GETST_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), + "getst $dst, res[$r]", + [(set GRRegs:$dst, (int_xcore_getst GRRegs:$r))]>; + +def INITSP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src), + "init t[$t]:sp, $src", + [(int_xcore_initsp GRRegs:$t, GRRegs:$src)]>; + +def INITPC_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src), + "init t[$t]:pc, $src", + [(int_xcore_initpc GRRegs:$t, GRRegs:$src)]>; + +def INITCP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src), + "init t[$t]:cp, $src", + [(int_xcore_initcp GRRegs:$t, GRRegs:$src)]>; + +def INITDP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src), + "init t[$t]:dp, $src", + [(int_xcore_initdp GRRegs:$t, GRRegs:$src)]>; + // Two operand long // TODO endin, peek, -// getd, testlcl, tinitlr +// getd, testlcl def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), "bitrev $dst, $src", [(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>; @@ -868,6 +886,10 @@ "set ps[$src1], $src2", [(int_xcore_setps GRRegs:$src1, GRRegs:$src2)]>; +def INITLR_l2r : _FL2R<(outs), (ins GRRegs:$t, GRRegs:$src), + "init t[$t]:lr, $src", + [(int_xcore_initlr GRRegs:$t, GRRegs:$src)]>; + def SETCLK_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), "setclk res[$src1], $src2", [(int_xcore_setclk GRRegs:$src1, GRRegs:$src2)]>; @@ -881,9 +903,16 @@ [(int_xcore_setpsc GRRegs:$src1, GRRegs:$src2)]>; // One operand short -// TODO edu, eeu, waitet, waitef, tstart, msync, mjoin, clrtp +// TODO edu, eeu, waitet, waitef, tstart, clrtp // setdp, setcp, setev, kcall // dgetreg +def MSYNC_1r : _F1R<(outs), (ins GRRegs:$i), + "msync res[$i]", + [(int_xcore_msync GRRegs:$i)]>; +def MJOIN_1r : _F1R<(outs), (ins GRRegs:$i), + "mjoin res[$i]", + [(int_xcore_mjoin GRRegs:$i)]>; + let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in def BAU_1r : _F1R<(outs), (ins GRRegs:$addr), "bau $addr", @@ -940,7 +969,7 @@ [(int_xcore_eeu GRRegs:$r)]>; // Zero operand short -// TODO ssync, freet, ldspc, stspc, ldssr, stssr, ldsed, stsed, +// TODO freet, ldspc, stspc, ldssr, stssr, ldsed, stsed, // stet, geted, getet, getkep, getksp, setkep, getid, kret, dcall, dret, // dentsp, drestsp @@ -951,6 +980,10 @@ "get r11, id", [(set R11, (int_xcore_getid))]>; +def SSYNC_0r : _F0R<(outs), (ins), + "ssync", + [(int_xcore_ssync)]>; + let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1, hasSideEffects = 1 in def WAITEU_0R : _F0R<(outs), (ins), Added: llvm/trunk/test/CodeGen/XCore/threads.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/threads.ll?rev=128633&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/threads.ll (added) +++ llvm/trunk/test/CodeGen/XCore/threads.ll Thu Mar 31 10:13:13 2011 @@ -0,0 +1,67 @@ +; RUN: llc -march=xcore < %s | FileCheck %s + +declare i8 addrspace(1)* @llvm.xcore.getst.p1i8.p1i8(i8 addrspace(1)* %r) +declare void @llvm.xcore.msync.p1i8(i8 addrspace(1)* %r) +declare void @llvm.xcore.ssync() +declare void @llvm.xcore.mjoin.p1i8(i8 addrspace(1)* %r) +declare void @llvm.xcore.initsp.p1i8(i8 addrspace(1)* %r, i8* %value) +declare void @llvm.xcore.initpc.p1i8(i8 addrspace(1)* %r, i8* %value) +declare void @llvm.xcore.initlr.p1i8(i8 addrspace(1)* %r, i8* %value) +declare void @llvm.xcore.initcp.p1i8(i8 addrspace(1)* %r, i8* %value) +declare void @llvm.xcore.initdp.p1i8(i8 addrspace(1)* %r, i8* %value) + +define i8 addrspace(1)* @getst(i8 addrspace(1)* %r) { +; CHECK: getst: +; CHECK: getst r0, res[r0] + %result = call i8 addrspace(1)* @llvm.xcore.getst.p1i8.p1i8(i8 addrspace(1)* %r) + ret i8 addrspace(1)* %result +} + +define void @ssync() { +; CHECK: ssync: +; CHECK: ssync + call void @llvm.xcore.ssync() + ret void +} + +define void @mjoin(i8 addrspace(1)* %r) { +; CHECK: mjoin: +; CHECK: mjoin res[r0] + call void @llvm.xcore.mjoin.p1i8(i8 addrspace(1)* %r) + ret void +} + +define void @initsp(i8 addrspace(1)* %t, i8* %src) { +; CHECK: initsp: +; CHECK: init t[r0]:sp, r1 + call void @llvm.xcore.initsp.p1i8(i8 addrspace(1)* %t, i8* %src) + ret void +} + +define void @initpc(i8 addrspace(1)* %t, i8* %src) { +; CHECK: initpc: +; CHECK: init t[r0]:pc, r1 + call void @llvm.xcore.initpc.p1i8(i8 addrspace(1)* %t, i8* %src) + ret void +} + +define void @initlr(i8 addrspace(1)* %t, i8* %src) { +; CHECK: initlr: +; CHECK: init t[r0]:lr, r1 + call void @llvm.xcore.initlr.p1i8(i8 addrspace(1)* %t, i8* %src) + ret void +} + +define void @initcp(i8 addrspace(1)* %t, i8* %src) { +; CHECK: initcp: +; CHECK: init t[r0]:cp, r1 + call void @llvm.xcore.initcp.p1i8(i8 addrspace(1)* %t, i8* %src) + ret void +} + +define void @initdp(i8 addrspace(1)* %t, i8* %src) { +; CHECK: initdp: +; CHECK: init t[r0]:dp, r1 + call void @llvm.xcore.initdp.p1i8(i8 addrspace(1)* %t, i8* %src) + ret void +} From stoklund at 2pi.dk Thu Mar 31 10:14:11 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 31 Mar 2011 15:14:11 -0000 Subject: [llvm-commits] [llvm] r128634 - /llvm/trunk/lib/CodeGen/LiveIntervalUnion.h Message-ID: <20110331151412.033652A6C12C@llvm.org> Author: stoklund Date: Thu Mar 31 10:14:11 2011 New Revision: 128634 URL: http://llvm.org/viewvc/llvm-project?rev=128634&view=rev Log: Fix bug found by valgrind. Modified: llvm/trunk/lib/CodeGen/LiveIntervalUnion.h Modified: llvm/trunk/lib/CodeGen/LiveIntervalUnion.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalUnion.h?rev=128634&r1=128633&r2=128634&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalUnion.h (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalUnion.h Thu Mar 31 10:14:11 2011 @@ -166,7 +166,7 @@ unsigned Tag, UserTag; public: - Query(): LiveUnion(), VirtReg() {} + Query(): LiveUnion(), VirtReg(), Tag(0), UserTag(0) {} Query(LiveInterval *VReg, LiveIntervalUnion *LIU): LiveUnion(LIU), VirtReg(VReg), CheckedFirstInterference(false), From dpatel at apple.com Thu Mar 31 10:34:56 2011 From: dpatel at apple.com (Devang Patel) Date: Thu, 31 Mar 2011 08:34:56 -0700 Subject: [llvm-commits] [llvm] r128632 - in /llvm/trunk: lib/Target/ARM/ARMAddressingModes.h lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.h test/MC/ARM/arm_addrmode2.s In-Reply-To: <20110331145228.F0EEA2A6C12E@llvm.org> References: <20110331145228.F0EEA2A6C12E@llvm.org> Message-ID: Bruno, This is causing clang test failures. LLVM :: CodeGen/ARM/ldr_post.ll LLVM :: CodeGen/ARM/ldst-f32-2-i32.ll LLVM :: CodeGen/ARM/str_pre-2.ll Can you take a look ? Thanks, - Devang On Mar 31, 2011, at 7:52 AM, Bruno Cardoso Lopes wrote: > Author: bruno > Date: Thu Mar 31 09:52:28 2011 > New Revision: 128632 > > URL: http://llvm.org/viewvc/llvm-project?rev=128632&view=rev > Log: > Reapply r128585 without generating a lib depedency cycle. An updated log: > > - Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and > {STR,LDC}{2}_{PRE,POST} fixing the encoding wherever is possible. > - Move all instructions which use am2offset without a pattern to use > addrmode2. > - Add a new encoding bit to describe the index mode used and teach > printAddrMode2Operand to check by the addressing mode which index > mode to print. > - Testcases > > Added: > llvm/trunk/test/MC/ARM/arm_addrmode2.s > Modified: > llvm/trunk/lib/Target/ARM/ARMAddressingModes.h > llvm/trunk/lib/Target/ARM/ARMBaseInfo.h > llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h > llvm/trunk/lib/Target/ARM/ARMInstrFormats.td > llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp > llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp > llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp > llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h > > Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAddressingModes.h?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMAddressingModes.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMAddressingModes.h Thu Mar 31 09:52:28 2011 > @@ -408,16 +408,18 @@ > // > // The first operand is always a Reg. The second operand is a reg if in > // reg/reg form, otherwise it's reg#0. The third field encodes the operation > - // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. > + // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The > + // forth operand 16-17 encodes the index mode. > // > // If this addressing mode is a frame index (before prolog/epilog insertion > // and code rewriting), this operand will have the form: FI#, reg0, > // with no shift amount for the frame offset. > // > - static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO) { > + static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, > + unsigned IdxMode = 0) { > assert(Imm12 < (1 << 12) && "Imm too large!"); > bool isSub = Opc == sub; > - return Imm12 | ((int)isSub << 12) | (SO << 13); > + return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ; > } > static inline unsigned getAM2Offset(unsigned AM2Opc) { > return AM2Opc & ((1 << 12)-1); > @@ -426,7 +428,10 @@ > return ((AM2Opc >> 12) & 1) ? sub : add; > } > static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) { > - return (ShiftOpc)(AM2Opc >> 13); > + return (ShiftOpc)((AM2Opc >> 13) & 7); > + } > + static inline unsigned getAM2IdxMode(unsigned AM2Opc) { > + return (AM2Opc >> 16); > } > > > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Thu Mar 31 09:52:28 2011 > @@ -200,6 +200,59 @@ > } > > namespace ARMII { > + > + /// ARM Index Modes > + enum IndexMode { > + IndexModeNone = 0, > + IndexModePre = 1, > + IndexModePost = 2, > + IndexModeUpd = 3 > + }; > + > + /// ARM Addressing Modes > + enum AddrMode { > + AddrModeNone = 0, > + AddrMode1 = 1, > + AddrMode2 = 2, > + AddrMode3 = 3, > + AddrMode4 = 4, > + AddrMode5 = 5, > + AddrMode6 = 6, > + AddrModeT1_1 = 7, > + AddrModeT1_2 = 8, > + AddrModeT1_4 = 9, > + AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data > + AddrModeT2_i12 = 11, > + AddrModeT2_i8 = 12, > + AddrModeT2_so = 13, > + AddrModeT2_pc = 14, // +/- i12 for pc relative data > + AddrModeT2_i8s4 = 15, // i8 * 4 > + AddrMode_i12 = 16 > + }; > + > + inline static const char *AddrModeToString(AddrMode addrmode) { > + switch (addrmode) { > + default: llvm_unreachable("Unknown memory operation"); > + case AddrModeNone: return "AddrModeNone"; > + case AddrMode1: return "AddrMode1"; > + case AddrMode2: return "AddrMode2"; > + case AddrMode3: return "AddrMode3"; > + case AddrMode4: return "AddrMode4"; > + case AddrMode5: return "AddrMode5"; > + case AddrMode6: return "AddrMode6"; > + case AddrModeT1_1: return "AddrModeT1_1"; > + case AddrModeT1_2: return "AddrModeT1_2"; > + case AddrModeT1_4: return "AddrModeT1_4"; > + case AddrModeT1_s: return "AddrModeT1_s"; > + case AddrModeT2_i12: return "AddrModeT2_i12"; > + case AddrModeT2_i8: return "AddrModeT2_i8"; > + case AddrModeT2_so: return "AddrModeT2_so"; > + case AddrModeT2_pc: return "AddrModeT2_pc"; > + case AddrModeT2_i8s4: return "AddrModeT2_i8s4"; > + case AddrMode_i12: return "AddrMode_i12"; > + } > + } > + > /// Target Operand Flag enum. > enum TOF { > //===------------------------------------------------------------------===// > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Thu Mar 31 09:52:28 2011 > @@ -34,25 +34,7 @@ > > //===------------------------------------------------------------------===// > // This four-bit field describes the addressing mode used. > - > - AddrModeMask = 0x1f, > - AddrModeNone = 0, > - AddrMode1 = 1, > - AddrMode2 = 2, > - AddrMode3 = 3, > - AddrMode4 = 4, > - AddrMode5 = 5, > - AddrMode6 = 6, > - AddrModeT1_1 = 7, > - AddrModeT1_2 = 8, > - AddrModeT1_4 = 9, > - AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data > - AddrModeT2_i12 = 11, > - AddrModeT2_i8 = 12, > - AddrModeT2_so = 13, > - AddrModeT2_pc = 14, // +/- i12 for pc relative data > - AddrModeT2_i8s4 = 15, // i8 * 4 > - AddrMode_i12 = 16, > + AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h > > // Size* - Flags to keep track of the size of an instruction. > SizeShift = 5, > @@ -64,11 +46,9 @@ > > // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load > // and store ops only. Generic "updating" flag is used for ld/st multiple. > + // The index mode enums are declared in ARMBaseInfo.h > IndexModeShift = 8, > IndexModeMask = 3 << IndexModeShift, > - IndexModePre = 1, > - IndexModePost = 2, > - IndexModeUpd = 3, > > //===------------------------------------------------------------------===// > // Instruction encoding formats. > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu Mar 31 09:52:28 2011 > @@ -515,15 +515,15 @@ > : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, > pattern> { > // AM2 store w/ two operands: (GPR, am2offset) > + // {17-14} Rn > // {13} 1 == Rm, 0 == imm12 > // {12} isAdd > // {11-0} imm12/Rm > - bits<14> offset; > - bits<4> Rn; > - let Inst{25} = offset{13}; > - let Inst{23} = offset{12}; > - let Inst{19-16} = Rn; > - let Inst{11-0} = offset{11-0}; > + bits<18> addr; > + let Inst{25} = addr{13}; > + let Inst{23} = addr{12}; > + let Inst{19-16} = addr{17-14}; > + let Inst{11-0} = addr{11-0}; > } > > // addrmode3 instructions > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Mar 31 09:52:28 2011 > @@ -498,6 +498,12 @@ > let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); > } > > +def MemMode2AsmOperand : AsmOperandClass { > + let Name = "MemMode2"; > + let SuperClasses = []; > + let ParserMethod = "tryParseMemMode2Operand"; > +} > + > // addrmode2 := reg +/- imm12 > // := reg +/- reg shop imm > // > @@ -505,6 +511,7 @@ > ComplexPattern { > let EncoderMethod = "getAddrMode2OpValue"; > let PrintMethod = "printAddrMode2Operand"; > + let ParserMatchClass = MemMode2AsmOperand; > let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); > } > > @@ -1656,20 +1663,21 @@ > let Inst{23} = addr{12}; > let Inst{19-16} = addr{17-14}; > let Inst{11-0} = addr{11-0}; > + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > } > def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), > - (ins GPR:$Rn, am2offset:$offset), > - IndexModePost, LdFrm, itin, > - opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> { > + (ins addrmode2:$addr), IndexModePost, LdFrm, itin, > + opc, "\t$Rt, $addr", "$addr.base = $Rn_wb", []> { > + // {17-14} Rn > // {13} 1 == Rm, 0 == imm12 > // {12} isAdd > // {11-0} imm12/Rm > - bits<14> offset; > - bits<4> Rn; > - let Inst{25} = offset{13}; > - let Inst{23} = offset{12}; > - let Inst{19-16} = Rn; > - let Inst{11-0} = offset{11-0}; > + bits<18> addr; > + let Inst{25} = addr{13}; > + let Inst{23} = addr{12}; > + let Inst{19-16} = addr{17-14}; > + let Inst{11-0} = addr{11-0}; > + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > } > } > > @@ -1714,17 +1722,35 @@ > > // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. > let mayLoad = 1, neverHasSideEffects = 1 in { > -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb), > - (ins GPR:$base, am2offset:$offset), IndexModePost, > - LdFrm, IIC_iLoad_ru, > - "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { > +def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb), > + (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru, > + "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { > + // {17-14} Rn > + // {13} 1 == Rm, 0 == imm12 > + // {12} isAdd > + // {11-0} imm12/Rm > + bits<18> addr; > + let Inst{25} = addr{13}; > + let Inst{23} = addr{12}; > let Inst{21} = 1; // overwrite > -} > -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb), > - (ins GPR:$base, am2offset:$offset), IndexModePost, > - LdFrm, IIC_iLoad_bh_ru, > - "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { > + let Inst{19-16} = addr{17-14}; > + let Inst{11-0} = addr{11-0}; > + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > +} > +def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), > + (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru, > + "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { > + // {17-14} Rn > + // {13} 1 == Rm, 0 == imm12 > + // {12} isAdd > + // {11-0} imm12/Rm > + bits<18> addr; > + let Inst{25} = addr{13}; > + let Inst{23} = addr{12}; > let Inst{21} = 1; // overwrite > + let Inst{19-16} = addr{17-14}; > + let Inst{11-0} = addr{11-0}; > + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > } > def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb), > (ins GPR:$base, am3offset:$offset), IndexModePost, > @@ -1818,20 +1844,20 @@ > > // STRT, STRBT, and STRHT are for disassembly only. > > -def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), > - (ins GPR:$Rt, GPR:$Rn,am2offset:$offset), > +def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), > IndexModePost, StFrm, IIC_iStore_ru, > - "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", > + "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb", > [/* For disassembly only; pattern left blank */]> { > let Inst{21} = 1; // overwrite > + let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; > } > > -def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), > - (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), > +def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), > IndexModePost, StFrm, IIC_iStore_bh_ru, > - "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", > + "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb", > [/* For disassembly only; pattern left blank */]> { > let Inst{21} = 1; // overwrite > + let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; > } > > def STRHT: AI3sthpo<(outs GPR:$base_wb), > @@ -3391,8 +3417,9 @@ > let Inst{23-20} = opc1; > } > > -class ACI > - : I +class ACI + IndexMode im = IndexModeNone> > + : I opc, asm, "", [/* For disassembly only; pattern left blank */]> { > let Inst{27-25} = 0b110; > } > @@ -3411,7 +3438,7 @@ > > def _PRE : ACI<(outs), > (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - opc, "\tp$cop, cr$CRd, $addr!"> { > + opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> { > let Inst{31-28} = op31_28; > let Inst{24} = 1; // P = 1 > let Inst{21} = 1; // W = 1 > @@ -3420,8 +3447,8 @@ > } > > def _POST : ACI<(outs), > - (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), > - opc, "\tp$cop, cr$CRd, [$base], $offset"> { > + (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > + opc, "\tp$cop, cr$CRd, $addr", IndexModePost> { > let Inst{31-28} = op31_28; > let Inst{24} = 0; // P = 0 > let Inst{21} = 1; // W = 1 > @@ -3452,7 +3479,7 @@ > > def L_PRE : ACI<(outs), > (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { > + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> { > let Inst{31-28} = op31_28; > let Inst{24} = 1; // P = 1 > let Inst{21} = 1; // W = 1 > @@ -3461,8 +3488,8 @@ > } > > def L_POST : ACI<(outs), > - (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), > - !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> { > + (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr", IndexModePost> { > let Inst{31-28} = op31_28; > let Inst{24} = 0; // P = 0 > let Inst{21} = 1; // W = 1 > > Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) > +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Mar 31 09:52:28 2011 > @@ -48,7 +48,8 @@ > bool TryParseRegisterWithWriteBack(SmallVectorImpl &); > bool TryParseShiftRegister(SmallVectorImpl &); > bool ParseRegisterList(SmallVectorImpl &); > - bool ParseMemory(SmallVectorImpl &); > + bool ParseMemory(SmallVectorImpl &, > + ARMII::AddrMode AddrMode); > bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic); > bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); > const MCExpr *ApplyPrefixToExpr(const MCExpr *E, > @@ -95,6 +96,14 @@ > SmallVectorImpl&); > OperandMatchResultTy tryParseMSRMaskOperand( > SmallVectorImpl&); > + OperandMatchResultTy tryParseMemMode2Operand( > + SmallVectorImpl&); > + > + // Asm Match Converter Methods > + bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > + const SmallVectorImpl &); > + bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > + const SmallVectorImpl &); > > public: > ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) > @@ -172,6 +181,7 @@ > > /// Combined record for all forms of ARM address expressions. > struct { > + ARMII::AddrMode AddrMode; > unsigned BaseRegNum; > union { > unsigned RegNum; ///< Offset register num, when OffsetIsReg. > @@ -293,7 +303,9 @@ > > /// @name Memory Operand Accessors > /// @{ > - > + ARMII::AddrMode getMemAddrMode() const { > + return Mem.AddrMode; > + } > unsigned getMemBaseRegNum() const { > return Mem.BaseRegNum; > } > @@ -338,6 +350,27 @@ > bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } > bool isMemory() const { return Kind == Memory; } > bool isShifter() const { return Kind == Shifter; } > + bool isMemMode2() const { > + if (getMemAddrMode() != ARMII::AddrMode2) > + return false; > + > + if (getMemOffsetIsReg()) > + return true; > + > + if (getMemNegative() && > + !(getMemPostindexed() || getMemPreindexed())) > + return false; > + > + const MCConstantExpr *CE = dyn_cast(getMemOffset()); > + if (!CE) return false; > + int64_t Value = CE->getValue(); > + > + // The offset must be in the range 0-4095 (imm12). > + if (Value > 4095 || Value < -4095) > + return false; > + > + return true; > + } > bool isMemMode5() const { > if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || > getMemNegative()) > @@ -465,6 +498,47 @@ > "No offset operand support in mode 7"); > } > > + void addMemMode2Operands(MCInst &Inst, unsigned N) const { > + assert(isMemMode2() && "Invalid mode or number of operands!"); > + Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); > + unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); > + > + if (getMemOffsetIsReg()) { > + Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); > + > + ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; > + ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; > + int64_t ShiftAmount = 0; > + > + if (getMemOffsetRegShifted()) { > + ShOpc = getMemShiftType(); > + const MCConstantExpr *CE = > + dyn_cast(getMemShiftAmount()); > + ShiftAmount = CE->getValue(); > + } > + > + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, > + ShOpc, IdxMode))); > + return; > + } > + > + // Create a operand placeholder to always yield the same number of operands. > + Inst.addOperand(MCOperand::CreateReg(0)); > + > + // FIXME: #-0 is encoded differently than #0. Does the parser preserve > + // the difference? > + const MCConstantExpr *CE = dyn_cast(getMemOffset()); > + assert(CE && "Non-constant mode 2 offset operand!"); > + int64_t Offset = CE->getValue(); > + > + if (Offset >= 0) > + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, > + Offset, ARM_AM::no_shift, IdxMode))); > + else > + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, > + -Offset, ARM_AM::no_shift, IdxMode))); > + } > + > void addMemMode5Operands(MCInst &Inst, unsigned N) const { > assert(N == 2 && isMemMode5() && "Invalid number of operands!"); > > @@ -599,9 +673,9 @@ > return Op; > } > > - static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, > - const MCExpr *Offset, int OffsetRegNum, > - bool OffsetRegShifted, > + static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, > + bool OffsetIsReg, const MCExpr *Offset, > + int OffsetRegNum, bool OffsetRegShifted, > enum ARM_AM::ShiftOpc ShiftType, > const MCExpr *ShiftAmount, bool Preindexed, > bool Postindexed, bool Negative, bool Writeback, > @@ -618,6 +692,7 @@ > "Cannot have expression offset and register offset!"); > > ARMOperand *Op = new ARMOperand(Memory); > + Op->Mem.AddrMode = AddrMode; > Op->Mem.BaseRegNum = BaseRegNum; > Op->Mem.OffsetIsReg = OffsetIsReg; > if (OffsetIsReg) > @@ -689,7 +764,8 @@ > break; > case Memory: > OS << " - << "base:" << getMemBaseRegNum(); > + << "am:" << ARMII::AddrModeToString(getMemAddrMode()) > + << " base:" << getMemBaseRegNum(); > if (getMemOffsetIsReg()) { > OS << " offset: if (getMemOffsetRegShifted()) { > @@ -1132,13 +1208,57 @@ > return MatchOperand_Success; > } > > +/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand. > +ARMAsmParser::OperandMatchResultTy ARMAsmParser:: > +tryParseMemMode2Operand(SmallVectorImpl &Operands) { > + SMLoc S = Parser.getTok().getLoc(); > + const AsmToken &Tok = Parser.getTok(); > + assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\""); > + > + if (ParseMemory(Operands, ARMII::AddrMode2)) > + return MatchOperand_NoMatch; > + > + return MatchOperand_Success; > +} > + > +/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. > +/// Needed here because the Asm Gen Matcher can't handle properly tied operands > +/// when they refer multiple MIOperands inside a single one. > +bool ARMAsmParser:: > +CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > + const SmallVectorImpl &Operands) { > + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); > + > + // Create a writeback register dummy placeholder. > + Inst.addOperand(MCOperand::CreateImm(0)); > + > + ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); > + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); > + return true; > +} > + > +/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. > +/// Needed here because the Asm Gen Matcher can't handle properly tied operands > +/// when they refer multiple MIOperands inside a single one. > +bool ARMAsmParser:: > +CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > + const SmallVectorImpl &Operands) { > + // Create a writeback register dummy placeholder. > + Inst.addOperand(MCOperand::CreateImm(0)); > + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); > + ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); > + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); > + return true; > +} > + > /// Parse an ARM memory expression, return false if successful else return true > /// or an error. The first token must be a '[' when called. > /// > /// TODO Only preindexing and postindexing addressing are started, unindexed > /// with option, etc are still to do. > bool ARMAsmParser:: > -ParseMemory(SmallVectorImpl &Operands) { > +ParseMemory(SmallVectorImpl &Operands, > + ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { > SMLoc S, E; > assert(Parser.getTok().is(AsmToken::LBrac) && > "Token is not a Left Bracket"); > @@ -1196,6 +1316,9 @@ > ExclaimTok.getLoc()); > Writeback = true; > Parser.Lex(); // Eat exclaim token > + } else { // In addressing mode 2, pre-indexed mode always end with "!" > + if (AddrMode == ARMII::AddrMode2) > + Preindexed = false; > } > } else { > // The "[Rn" we have so far was not followed by a comma. > @@ -1231,11 +1354,10 @@ > Offset = MCConstantExpr::Create(0, getContext()); > } > > - Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, > - OffsetRegNum, OffsetRegShifted, > - ShiftType, ShiftAmount, Preindexed, > - Postindexed, Negative, Writeback, > - S, E)); > + Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, > + Offset, OffsetRegNum, OffsetRegShifted, > + ShiftType, ShiftAmount, Preindexed, > + Postindexed, Negative, Writeback, S, E)); > if (WBOp) > Operands.push_back(WBOp); > > > Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) > +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Thu Mar 31 09:52:28 2011 > @@ -643,8 +643,11 @@ > if (PW) { > MI.addOperand(MCOperand::CreateReg(0)); > ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; > + const TargetInstrDesc &TID = ARMInsts[Opcode]; > + unsigned IndexMode = > + (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; > unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << 2, > - ARM_AM::no_shift); > + ARM_AM::no_shift, IndexMode); > MI.addOperand(MCOperand::CreateImm(Offset)); > OpIdx = 5; > } else { > @@ -1073,6 +1076,8 @@ > return false; > > ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; > + unsigned IndexMode = > + (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; > if (getIBit(insn) == 0) { > // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2). > // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already > @@ -1084,7 +1089,8 @@ > > // Disassemble the 12-bit immediate offset. > unsigned Imm12 = slice(insn, 11, 0); > - unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift); > + unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift, > + IndexMode); > MI.addOperand(MCOperand::CreateImm(Offset)); > OpIdx += 1; > } else { > @@ -1099,7 +1105,7 @@ > // A8.4.1. Possible rrx or shift amount of 32... > getImmShiftSE(ShOp, ShImm); > MI.addOperand(MCOperand::CreateImm( > - ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp))); > + ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, IndexMode))); > OpIdx += 2; > } > > > Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original) > +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Thu Mar 31 09:52:28 2011 > @@ -181,18 +181,12 @@ > } > } > > - > -void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, > - raw_ostream &O) { > +void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, > + raw_ostream &O) { > const MCOperand &MO1 = MI->getOperand(Op); > const MCOperand &MO2 = MI->getOperand(Op+1); > const MCOperand &MO3 = MI->getOperand(Op+2); > > - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. > - printOperand(MI, Op, O); > - return; > - } > - > O << "[" << getRegisterName(MO1.getReg()); > > if (!MO2.getReg()) { > @@ -215,6 +209,50 @@ > O << "]"; > } > > +void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, > + raw_ostream &O) { > + const MCOperand &MO1 = MI->getOperand(Op); > + const MCOperand &MO2 = MI->getOperand(Op+1); > + const MCOperand &MO3 = MI->getOperand(Op+2); > + > + O << "[" << getRegisterName(MO1.getReg()) << "], "; > + > + if (!MO2.getReg()) { > + unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); > + O << '#' > + << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) > + << ImmOffs; > + return; > + } > + > + O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) > + << getRegisterName(MO2.getReg()); > + > + if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) > + O << ", " > + << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) > + << " #" << ShImm; > +} > + > +void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, > + raw_ostream &O) { > + const MCOperand &MO1 = MI->getOperand(Op); > + > + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. > + printOperand(MI, Op, O); > + return; > + } > + > + const MCOperand &MO3 = MI->getOperand(Op+2); > + unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm()); > + > + if (IdxMode == ARMII::IndexModePost) { > + printAM2PostIndexOp(MI, Op, O); > + return; > + } > + printAM2PreOrOffsetIndexOp(MI, Op, O); > +} > + > void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, > unsigned OpNum, > raw_ostream &O) { > > Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original) > +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Thu Mar 31 09:52:28 2011 > @@ -42,7 +42,11 @@ > void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > > void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > + > void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > + void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O); > + void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, > + raw_ostream &O); > void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, > raw_ostream &O); > void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > > Added: llvm/trunk/test/MC/ARM/arm_addrmode2.s > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128632&view=auto > ============================================================================== > --- llvm/trunk/test/MC/ARM/arm_addrmode2.s (added) > +++ llvm/trunk/test/MC/ARM/arm_addrmode2.s Thu Mar 31 09:52:28 2011 > @@ -0,0 +1,38 @@ > +@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | FileCheck %s > + > +@ Post-indexed > +@ CHECK: ldrt r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6] > +@ CHECK: ldrt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6] > +@ CHECK: ldrt r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4] > +@ CHECK: ldrbt r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6] > +@ CHECK: ldrbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6] > +@ CHECK: ldrbt r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4] > +@ CHECK: strt r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6] > +@ CHECK: strt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6] > +@ CHECK: strt r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4] > +@ CHECK: strbt r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6] > +@ CHECK: strbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6] > +@ CHECK: strbt r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4] > +@ CHECK: ldr r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0x90,0xe6] > +@ CHECK: ldrb r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xd0,0xe6] > + ldrt r1, [r0], r2 > + ldrt r1, [r0], r2, lsr #3 > + ldrt r1, [r0], #4 > + ldrbt r1, [r0], r2 > + ldrbt r1, [r0], r2, lsr #3 > + ldrbt r1, [r0], #4 > + strt r1, [r0], r2 > + strt r1, [r0], r2, lsr #3 > + strt r1, [r0], #4 > + strbt r1, [r0], r2 > + strbt r1, [r0], r2, lsr #3 > + strbt r1, [r0], #4 > + ldr r1, [r0], r2, lsr #3 > + ldrb r1, [r0], r2, lsr #3 > + > +@ Pre-indexed > +@ CHECK: ldr r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7] > +@ CHECK: ldrb r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7] > + ldr r1, [r0, r2, lsr #3]! > + ldrb r1, [r0, r2, lsr #3]! > + > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110331/8848c14a/attachment-0001.html From bruno.cardoso at gmail.com Thu Mar 31 10:40:02 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Thu, 31 Mar 2011 12:40:02 -0300 Subject: [llvm-commits] [llvm] r128632 - in /llvm/trunk: lib/Target/ARM/ARMAddressingModes.h lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmPar Message-ID: On Thu, Mar 31, 2011 at 12:34 PM, Devang Patel wrote: > Bruno, > This is causing clang test failures. > > LLVM :: CodeGen/ARM/ldr_post.ll > LLVM :: CodeGen/ARM/ldst-f32-2-i32.ll > LLVM :: CodeGen/ARM/str_pre-2.ll > > Can you take a look ? > Thanks, Yes. Looking at it right now > Devang > On Mar 31, 2011, at 7:52 AM, Bruno Cardoso Lopes wrote: > > Author: bruno > Date: Thu Mar 31 09:52:28 2011 > New Revision: 128632 > > URL: http://llvm.org/viewvc/llvm-project?rev=128632&view=rev > Log: > Reapply r128585 without generating a lib depedency cycle. An updated log: > > - Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and > ?{STR,LDC}{2}_{PRE,POST} fixing the encoding wherever is possible. > - Move all instructions which use am2offset without a pattern to use > ?addrmode2. > - Add a new encoding bit to describe the index mode used and teach > ?printAddrMode2Operand to check by the addressing mode which index > ?mode to print. > - Testcases > > Added: > ???llvm/trunk/test/MC/ARM/arm_addrmode2.s > Modified: > ???llvm/trunk/lib/Target/ARM/ARMAddressingModes.h > ???llvm/trunk/lib/Target/ARM/ARMBaseInfo.h > ???llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h > ???llvm/trunk/lib/Target/ARM/ARMInstrFormats.td > ???llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > ???llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp > ???llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp > ???llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp > ???llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h > > Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAddressingModes.h?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMAddressingModes.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMAddressingModes.h Thu Mar 31 09:52:28 2011 > @@ -408,16 +408,18 @@ > ??// > ??// The first operand is always a Reg. ?The second operand is a reg if in > ??// reg/reg form, otherwise it's reg#0. ?The third field encodes the > operation > - ?// in bit 12, the immediate in bits 0-11, and the shift op in 13-15. > + ?// in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The > + ?// forth operand 16-17 encodes the index mode. > ??// > ??// If this addressing mode is a frame index (before prolog/epilog > insertion > ??// and code rewriting), this operand will have the form: ?FI#, reg0, > > ??// with no shift amount for the frame offset. > ??// > - ?static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc > SO) { > + ?static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc > SO, > + ??????????????????????????????????unsigned IdxMode = 0) { > ????assert(Imm12 < (1 << 12) && "Imm too large!"); > ????bool isSub = Opc == sub; > - ???return Imm12 | ((int)isSub << 12) | (SO << 13); > + ???return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ; > ??} > ??static inline unsigned getAM2Offset(unsigned AM2Opc) { > ????return AM2Opc & ((1 << 12)-1); > @@ -426,7 +428,10 @@ > ????return ((AM2Opc >> 12) & 1) ? sub : add; > ??} > ??static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) { > - ???return (ShiftOpc)(AM2Opc >> 13); > + ???return (ShiftOpc)((AM2Opc >> 13) & 7); > + ?} > + ?static inline unsigned getAM2IdxMode(unsigned AM2Opc) { > + ???return (AM2Opc >> 16); > ??} > > > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Thu Mar 31 09:52:28 2011 > @@ -200,6 +200,59 @@ > } > > namespace ARMII { > + > + ?/// ARM Index Modes > + ?enum IndexMode { > + ???IndexModeNone ?= 0, > + ???IndexModePre ??= 1, > + ???IndexModePost ?= 2, > + ???IndexModeUpd ??= 3 > + ?}; > + > + ?/// ARM Addressing Modes > + ?enum AddrMode { > + ???AddrModeNone ???= 0, > + ???AddrMode1 ??????= 1, > + ???AddrMode2 ??????= 2, > + ???AddrMode3 ??????= 3, > + ???AddrMode4 ??????= 4, > + ???AddrMode5 ??????= 5, > + ???AddrMode6 ??????= 6, > + ???AddrModeT1_1 ???= 7, > + ???AddrModeT1_2 ???= 8, > + ???AddrModeT1_4 ???= 9, > + ???AddrModeT1_s ???= 10, // i8 * 4 for pc and sp relative data > + ???AddrModeT2_i12 ?= 11, > + ???AddrModeT2_i8 ??= 12, > + ???AddrModeT2_so ??= 13, > + ???AddrModeT2_pc ??= 14, // +/- i12 for pc relative data > + ???AddrModeT2_i8s4 = 15, // i8 * 4 > + ???AddrMode_i12 ???= 16 > + ?}; > + > + ?inline static const char *AddrModeToString(AddrMode addrmode) { > + ???switch (addrmode) { > + ???default: llvm_unreachable("Unknown memory operation"); > + ???case AddrModeNone: ???return "AddrModeNone"; > + ???case AddrMode1: ??????return "AddrMode1"; > + ???case AddrMode2: ??????return "AddrMode2"; > + ???case AddrMode3: ??????return "AddrMode3"; > + ???case AddrMode4: ??????return "AddrMode4"; > + ???case AddrMode5: ??????return "AddrMode5"; > + ???case AddrMode6: ??????return "AddrMode6"; > + ???case AddrModeT1_1: ???return "AddrModeT1_1"; > + ???case AddrModeT1_2: ???return "AddrModeT1_2"; > + ???case AddrModeT1_4: ???return "AddrModeT1_4"; > + ???case AddrModeT1_s: ???return "AddrModeT1_s"; > + ???case AddrModeT2_i12: ?return "AddrModeT2_i12"; > + ???case AddrModeT2_i8: ??return "AddrModeT2_i8"; > + ???case AddrModeT2_so: ??return "AddrModeT2_so"; > + ???case AddrModeT2_pc: ??return "AddrModeT2_pc"; > + ???case AddrModeT2_i8s4: return "AddrModeT2_i8s4"; > + ???case AddrMode_i12: ???return "AddrMode_i12"; > + ???} > + ?} > + > ??/// Target Operand Flag enum. > ??enum TOF { > ????//===------------------------------------------------------------------===// > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Thu Mar 31 09:52:28 2011 > @@ -34,25 +34,7 @@ > > ????//===------------------------------------------------------------------===// > ????// This four-bit field describes the addressing mode used. > - > - ???AddrModeMask ?= 0x1f, > - ???AddrModeNone ???= 0, > - ???AddrMode1 ??????= 1, > - ???AddrMode2 ??????= 2, > - ???AddrMode3 ??????= 3, > - ???AddrMode4 ??????= 4, > - ???AddrMode5 ??????= 5, > - ???AddrMode6 ??????= 6, > - ???AddrModeT1_1 ???= 7, > - ???AddrModeT1_2 ???= 8, > - ???AddrModeT1_4 ???= 9, > - ???AddrModeT1_s ???= 10, // i8 * 4 for pc and sp relative data > - ???AddrModeT2_i12 ?= 11, > - ???AddrModeT2_i8 ??= 12, > - ???AddrModeT2_so ??= 13, > - ???AddrModeT2_pc ??= 14, // +/- i12 for pc relative data > - ???AddrModeT2_i8s4 = 15, // i8 * 4 > - ???AddrMode_i12 ???= 16, > + ???AddrModeMask ?= 0x1f, // The AddrMode enums are declared in > ARMBaseInfo.h > > ????// Size* - Flags to keep track of the size of an instruction. > ????SizeShift ????= 5, > @@ -64,11 +46,9 @@ > > ????// IndexMode - Unindex, pre-indexed, or post-indexed are valid for load > ????// and store ops only. ?Generic "updating" flag is used for ld/st > multiple. > + ???// The index mode enums are declared in ARMBaseInfo.h > ????IndexModeShift = 8, > ????IndexModeMask ?= 3 << IndexModeShift, > - ???IndexModePre ??= 1, > - ???IndexModePost ?= 2, > - ???IndexModeUpd ??= 3, > > ????//===------------------------------------------------------------------===// > ????// Instruction encoding formats. > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu Mar 31 09:52:28 2011 > @@ -515,15 +515,15 @@ > ??: AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, > ???????????????pattern> { > ??// AM2 store w/ two operands: (GPR, am2offset) > + ?// {17-14} ?Rn > ??// {13} ????1 == Rm, 0 == imm12 > ??// {12} ????isAdd > ??// {11-0} ??imm12/Rm > - ?bits<14> offset; > - ?bits<4> Rn; > - ?let Inst{25} = offset{13}; > - ?let Inst{23} = offset{12}; > - ?let Inst{19-16} = Rn; > - ?let Inst{11-0} = offset{11-0}; > + ?bits<18> addr; > + ?let Inst{25} = addr{13}; > + ?let Inst{23} = addr{12}; > + ?let Inst{19-16} = addr{17-14}; > + ?let Inst{11-0} = addr{11-0}; > } > > // addrmode3 instructions > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Mar 31 09:52:28 2011 > @@ -498,6 +498,12 @@ > ??let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); > } > > +def MemMode2AsmOperand : AsmOperandClass { > + ?let Name = "MemMode2"; > + ?let SuperClasses = []; > + ?let ParserMethod = "tryParseMemMode2Operand"; > +} > + > // addrmode2 := reg +/- imm12 > // ??????????:= reg +/- reg shop imm > // > @@ -505,6 +511,7 @@ > ????????????????ComplexPattern { > ??let EncoderMethod = "getAddrMode2OpValue"; > ??let PrintMethod = "printAddrMode2Operand"; > + ?let ParserMatchClass = MemMode2AsmOperand; > ??let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); > } > > @@ -1656,20 +1663,21 @@ > ????let Inst{23} = addr{12}; > ????let Inst{19-16} = addr{17-14}; > ????let Inst{11-0} = addr{11-0}; > + ???let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > ??} > ??def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), > - ?????????????????????(ins GPR:$Rn, am2offset:$offset), > - ?????????????????????IndexModePost, LdFrm, itin, > - ?????????????????????opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> { > + ?????????????????????(ins addrmode2:$addr), IndexModePost, LdFrm, itin, > + ?????????????????????opc, "\t$Rt, $addr", "$addr.base = $Rn_wb", []> { > + ???// {17-14} ?Rn > ????// {13} ????1 == Rm, 0 == imm12 > ????// {12} ????isAdd > ????// {11-0} ??imm12/Rm > - ???bits<14> offset; > - ???bits<4> Rn; > - ???let Inst{25} = offset{13}; > - ???let Inst{23} = offset{12}; > - ???let Inst{19-16} = Rn; > - ???let Inst{11-0} = offset{11-0}; > + ???bits<18> addr; > + ???let Inst{25} = addr{13}; > + ???let Inst{23} = addr{12}; > + ???let Inst{19-16} = addr{17-14}; > + ???let Inst{11-0} = addr{11-0}; > + ???let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > ??} > } > > @@ -1714,17 +1722,35 @@ > > // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. > let mayLoad = 1, neverHasSideEffects = 1 in { > -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb), > - ??????????????????(ins GPR:$base, am2offset:$offset), IndexModePost, > - ??????????????????LdFrm, IIC_iLoad_ru, > - ??????????????????"ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", > []> { > +def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb), > + ??????????????????(ins addrmode2:$addr), IndexModePost, LdFrm, > IIC_iLoad_ru, > + ??????????????????"ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { > + ?// {17-14} ?Rn > + ?// {13} ????1 == Rm, 0 == imm12 > + ?// {12} ????isAdd > + ?// {11-0} ??imm12/Rm > + ?bits<18> addr; > + ?let Inst{25} = addr{13}; > + ?let Inst{23} = addr{12}; > ??let Inst{21} = 1; // overwrite > -} > -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb), > - ?????????????????(ins GPR:$base, am2offset:$offset), IndexModePost, > - ?????????????????LdFrm, IIC_iLoad_bh_ru, > - ?????????????????"ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", > []> { > + ?let Inst{19-16} = addr{17-14}; > + ?let Inst{11-0} = addr{11-0}; > + ?let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > +} > +def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), > + ?????????????????(ins addrmode2:$addr), IndexModePost, LdFrm, > IIC_iLoad_bh_ru, > + ?????????????????"ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { > + ?// {17-14} ?Rn > + ?// {13} ????1 == Rm, 0 == imm12 > + ?// {12} ????isAdd > + ?// {11-0} ??imm12/Rm > + ?bits<18> addr; > + ?let Inst{25} = addr{13}; > + ?let Inst{23} = addr{12}; > ??let Inst{21} = 1; // overwrite > + ?let Inst{19-16} = addr{17-14}; > + ?let Inst{11-0} = addr{11-0}; > + ?let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > } > def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb), > ?????????????????(ins GPR:$base, am3offset:$offset), IndexModePost, > @@ -1818,20 +1844,20 @@ > > // STRT, STRBT, and STRHT are for disassembly only. > > -def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), > - ???????????????????(ins GPR:$Rt, GPR:$Rn,am2offset:$offset), > +def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, > addrmode2:$addr), > ????????????????????IndexModePost, StFrm, IIC_iStore_ru, > - ???????????????????"strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", > + ???????????????????"strt", "\t$Rt, $addr", "$addr.base = $Rn_wb", > ????????????????????[/* For disassembly only; pattern left blank */]> { > ??let Inst{21} = 1; // overwrite > + ?let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; > } > > -def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), > - ????????????????????(ins GPR:$Rt, GPR:$Rn, am2offset:$offset), > +def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, > addrmode2:$addr), > ?????????????????????IndexModePost, StFrm, IIC_iStore_bh_ru, > - ????????????????????"strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", > + ????????????????????"strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb", > ?????????????????????[/* For disassembly only; pattern left blank */]> { > ??let Inst{21} = 1; // overwrite > + ?let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; > } > > def STRHT: AI3sthpo<(outs GPR:$base_wb), > @@ -3391,8 +3417,9 @@ > ??let Inst{23-20} = opc1; > } > > -class ACI > - ?: I NoItinerary, > +class ACI + ?????????IndexMode im = IndexModeNone> > + ?: I ??????opc, asm, "", [/* For disassembly only; pattern left blank */]> { > ??let Inst{27-25} = 0b110; > } > @@ -3411,7 +3438,7 @@ > > ??def _PRE : ACI<(outs), > ??????(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - ?????opc, "\tp$cop, cr$CRd, $addr!"> { > + ?????opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> { > ????let Inst{31-28} = op31_28; > ????let Inst{24} = 1; // P = 1 > ????let Inst{21} = 1; // W = 1 > @@ -3420,8 +3447,8 @@ > ??} > > ??def _POST : ACI<(outs), > - ?????(ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), > - ?????opc, "\tp$cop, cr$CRd, [$base], $offset"> { > + ?????(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > + ?????opc, "\tp$cop, cr$CRd, $addr", IndexModePost> { > ????let Inst{31-28} = op31_28; > ????let Inst{24} = 0; // P = 0 > ????let Inst{21} = 1; // W = 1 > @@ -3452,7 +3479,7 @@ > > ??def L_PRE : ACI<(outs), > ??????(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - ?????!strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { > + ?????!strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> { > ????let Inst{31-28} = op31_28; > ????let Inst{24} = 1; // P = 1 > ????let Inst{21} = 1; // W = 1 > @@ -3461,8 +3488,8 @@ > ??} > > ??def L_POST : ACI<(outs), > - ?????(ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), > - ?????!strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> { > + ?????(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > + ?????!strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr", IndexModePost> { > ????let Inst{31-28} = op31_28; > ????let Inst{24} = 0; // P = 0 > ????let Inst{21} = 1; // W = 1 > > Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) > +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Mar 31 09:52:28 > 2011 > @@ -48,7 +48,8 @@ > ??bool TryParseRegisterWithWriteBack(SmallVectorImpl > &); > ??bool TryParseShiftRegister(SmallVectorImpl &); > ??bool ParseRegisterList(SmallVectorImpl &); > - ?bool ParseMemory(SmallVectorImpl &); > + ?bool ParseMemory(SmallVectorImpl &, > + ??????????????????ARMII::AddrMode AddrMode); > ??bool ParseOperand(SmallVectorImpl &, StringRef > Mnemonic); > ??bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); > ??const MCExpr *ApplyPrefixToExpr(const MCExpr *E, > @@ -95,6 +96,14 @@ > ????SmallVectorImpl&); > ??OperandMatchResultTy tryParseMSRMaskOperand( > ????SmallVectorImpl&); > + ?OperandMatchResultTy tryParseMemMode2Operand( > + ???SmallVectorImpl&); > + > + ?// Asm Match Converter Methods > + ?bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > + ?????????????????????????????????const > SmallVectorImpl &); > + ?bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > + ?????????????????????????????????const > SmallVectorImpl &); > > public: > ??ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) > @@ -172,6 +181,7 @@ > > ????/// Combined record for all forms of ARM address expressions. > ????struct { > + ?????ARMII::AddrMode AddrMode; > ??????unsigned BaseRegNum; > ??????union { > ????????unsigned RegNum; ????///< Offset register num, when OffsetIsReg. > @@ -293,7 +303,9 @@ > > ??/// @name Memory Operand Accessors > ??/// @{ > - > + ?ARMII::AddrMode getMemAddrMode() const { > + ???return Mem.AddrMode; > + ?} > ??unsigned getMemBaseRegNum() const { > ????return Mem.BaseRegNum; > ??} > @@ -338,6 +350,27 @@ > ??bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } > ??bool isMemory() const { return Kind == Memory; } > ??bool isShifter() const { return Kind == Shifter; } > + ?bool isMemMode2() const { > + ???if (getMemAddrMode() != ARMII::AddrMode2) > + ?????return false; > + > + ???if (getMemOffsetIsReg()) > + ?????return true; > + > + ???if (getMemNegative() && > + ???????!(getMemPostindexed() || getMemPreindexed())) > + ?????return false; > + > + ???const MCConstantExpr *CE = dyn_cast(getMemOffset()); > + ???if (!CE) return false; > + ???int64_t Value = CE->getValue(); > + > + ???// The offset must be in the range 0-4095 (imm12). > + ???if (Value > 4095 || Value < -4095) > + ?????return false; > + > + ???return true; > + ?} > ??bool isMemMode5() const { > ????if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || > ????????getMemNegative()) > @@ -465,6 +498,47 @@ > ???????????"No offset operand support in mode 7"); > ??} > > + ?void addMemMode2Operands(MCInst &Inst, unsigned N) const { > + ???assert(isMemMode2() && "Invalid mode or number of operands!"); > + ???Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); > + ???unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); > + > + ???if (getMemOffsetIsReg()) { > + ?????Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); > + > + ?????ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; > + ?????ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; > + ?????int64_t ShiftAmount = 0; > + > + ?????if (getMemOffsetRegShifted()) { > + ???????ShOpc = getMemShiftType(); > + ???????const MCConstantExpr *CE = > + ??????????????????dyn_cast(getMemShiftAmount()); > + ???????ShiftAmount = CE->getValue(); > + ?????} > + > + ?????Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, > ShiftAmount, > + ??????????????????????????????????????????ShOpc, IdxMode))); > + ?????return; > + ???} > + > + ???// Create a operand placeholder to always yield the same number of > operands. > + ???Inst.addOperand(MCOperand::CreateReg(0)); > + > + ???// FIXME: #-0 is encoded differently than #0. Does the parser preserve > + ???// the difference? > + ???const MCConstantExpr *CE = dyn_cast(getMemOffset()); > + ???assert(CE && "Non-constant mode 2 offset operand!"); > + ???int64_t Offset = CE->getValue(); > + > + ???if (Offset >= 0) > + ?????Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, > + ??????????????????????????????????????????Offset, ARM_AM::no_shift, > IdxMode))); > + ???else > + ?????Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, > + ?????????????????????????????????????????-Offset, ARM_AM::no_shift, > IdxMode))); > + ?} > + > ??void addMemMode5Operands(MCInst &Inst, unsigned N) const { > ????assert(N == 2 && isMemMode5() && "Invalid number of operands!"); > > @@ -599,9 +673,9 @@ > ????return Op; > ??} > > - ?static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, > - ??????????????????????????????const MCExpr *Offset, int OffsetRegNum, > - ??????????????????????????????bool OffsetRegShifted, > + ?static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned > BaseRegNum, > + ??????????????????????????????bool OffsetIsReg, const MCExpr *Offset, > + ??????????????????????????????int OffsetRegNum, bool OffsetRegShifted, > ???????????????????????????????enum ARM_AM::ShiftOpc ShiftType, > ???????????????????????????????const MCExpr *ShiftAmount, bool Preindexed, > ???????????????????????????????bool Postindexed, bool Negative, bool > Writeback, > @@ -618,6 +692,7 @@ > ???????????"Cannot have expression offset and register offset!"); > > ????ARMOperand *Op = new ARMOperand(Memory); > + ???Op->Mem.AddrMode = AddrMode; > ????Op->Mem.BaseRegNum = BaseRegNum; > ????Op->Mem.OffsetIsReg = OffsetIsReg; > ????if (OffsetIsReg) > @@ -689,7 +764,8 @@ > ????break; > ??case Memory: > ????OS << " - ??????<< "base:" << getMemBaseRegNum(); > + ??????<< "am:" << ARMII::AddrModeToString(getMemAddrMode()) > + ??????<< " base:" << getMemBaseRegNum(); > ????if (getMemOffsetIsReg()) { > ??????OS << " offset: ??????if (getMemOffsetRegShifted()) { > @@ -1132,13 +1208,57 @@ > ??return MatchOperand_Success; > } > > +/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 > operand. > +ARMAsmParser::OperandMatchResultTy ARMAsmParser:: > +tryParseMemMode2Operand(SmallVectorImpl &Operands) { > + ?SMLoc S = Parser.getTok().getLoc(); > + ?const AsmToken &Tok = Parser.getTok(); > + ?assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\""); > + > + ?if (ParseMemory(Operands, ARMII::AddrMode2)) > + ???return MatchOperand_NoMatch; > + > + ?return MatchOperand_Success; > +} > + > +/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. > +/// Needed here because the Asm Gen Matcher can't handle properly tied > operands > +/// when they refer multiple MIOperands inside a single one. > +bool ARMAsmParser:: > +CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > + ????????????????????????const SmallVectorImpl > &Operands) { > + ?((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); > + > + ?// Create a writeback register dummy placeholder. > + ?Inst.addOperand(MCOperand::CreateImm(0)); > + > + ?((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); > + ?((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); > + ?return true; > +} > + > +/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. > +/// Needed here because the Asm Gen Matcher can't handle properly tied > operands > +/// when they refer multiple MIOperands inside a single one. > +bool ARMAsmParser:: > +CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > + ????????????????????????const SmallVectorImpl > &Operands) { > + ?// Create a writeback register dummy placeholder. > + ?Inst.addOperand(MCOperand::CreateImm(0)); > + ?((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); > + ?((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); > + ?((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); > + ?return true; > +} > + > /// Parse an ARM memory expression, return false if successful else return > true > /// or an error. ?The first token must be a '[' when called. > /// > /// TODO Only preindexing and postindexing addressing are started, unindexed > /// with option, etc are still to do. > bool ARMAsmParser:: > -ParseMemory(SmallVectorImpl &Operands) { > +ParseMemory(SmallVectorImpl &Operands, > + ???????????ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { > ??SMLoc S, E; > ??assert(Parser.getTok().is(AsmToken::LBrac) && > ?????????"Token is not a Left Bracket"); > @@ -1196,6 +1316,9 @@ > ?????????????????????????????????????ExclaimTok.getLoc()); > ??????Writeback = true; > ??????Parser.Lex(); // Eat exclaim token > + ???} else { // In addressing mode 2, pre-indexed mode always end with "!" > + ?????if (AddrMode == ARMII::AddrMode2) > + ???????Preindexed = false; > ????} > ??} else { > ????// The "[Rn" we have so far was not followed by a comma. > @@ -1231,11 +1354,10 @@ > ??????Offset = MCConstantExpr::Create(0, getContext()); > ??} > > - ?Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, > - ??????????????????????????????????????????OffsetRegNum, OffsetRegShifted, > - ??????????????????????????????????????????ShiftType, ShiftAmount, > Preindexed, > - ??????????????????????????????????????????Postindexed, Negative, > Writeback, > - ??????????????????????????????????????????S, E)); > + ?Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, > OffsetIsReg, > + ????????????????????????????????????Offset, OffsetRegNum, > OffsetRegShifted, > + ????????????????????????????????????ShiftType, ShiftAmount, Preindexed, > + ????????????????????????????????????Postindexed, Negative, Writeback, S, > E)); > ??if (WBOp) > ????Operands.push_back(WBOp); > > > Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp > (original) > +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Thu Mar > 31 09:52:28 2011 > @@ -643,8 +643,11 @@ > ????if (PW) { > ??????MI.addOperand(MCOperand::CreateReg(0)); > ??????ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : > ARM_AM::sub; > + ?????const TargetInstrDesc &TID = ARMInsts[Opcode]; > + ?????unsigned IndexMode = > + ?????????????????(TID.TSFlags & ARMII::IndexModeMask) >> > ARMII::IndexModeShift; > ??????unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << > 2, > - ?????????????????????????????????????????ARM_AM::no_shift); > + ?????????????????????????????????????????ARM_AM::no_shift, IndexMode); > ??????MI.addOperand(MCOperand::CreateImm(Offset)); > ??????OpIdx = 5; > ????} else { > @@ -1073,6 +1076,8 @@ > ????return false; > > ??ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; > + ?unsigned IndexMode = > + ??????????????(TID.TSFlags & ARMII::IndexModeMask) >> > ARMII::IndexModeShift; > ??if (getIBit(insn) == 0) { > ????// For pre- and post-indexed case, add a reg0 operand (Addressing Mode > #2). > ????// Otherwise, skip the reg operand since for addrmode_imm12, Rn has > already > @@ -1084,7 +1089,8 @@ > > ????// Disassemble the 12-bit immediate offset. > ????unsigned Imm12 = slice(insn, 11, 0); > - ???unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, > ARM_AM::no_shift); > + ???unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, > ARM_AM::no_shift, > + ???????????????????????????????????????IndexMode); > ????MI.addOperand(MCOperand::CreateImm(Offset)); > ????OpIdx += 1; > ??} else { > @@ -1099,7 +1105,7 @@ > ????// A8.4.1. ?Possible rrx or shift amount of 32... > ????getImmShiftSE(ShOp, ShImm); > ????MI.addOperand(MCOperand::CreateImm( > - ???????????????????ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp))); > + ???????????????????ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, > IndexMode))); > ????OpIdx += 2; > ??} > > > Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original) > +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Thu Mar 31 > 09:52:28 2011 > @@ -181,18 +181,12 @@ > ??} > } > > - > -void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, > - ??????????????????????????????????????????raw_ostream &O) { > +void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned > Op, > + ???????????????????????????????????????????????raw_ostream &O) { > ??const MCOperand &MO1 = MI->getOperand(Op); > ??const MCOperand &MO2 = MI->getOperand(Op+1); > ??const MCOperand &MO3 = MI->getOperand(Op+2); > > - ?if (!MO1.isReg()) { ??// FIXME: This is for CP entries, but isn't right. > - ???printOperand(MI, Op, O); > - ???return; > - ?} > - > ??O << "[" << getRegisterName(MO1.getReg()); > > ??if (!MO2.getReg()) { > @@ -215,6 +209,50 @@ > ??O << "]"; > } > > +void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, > + ????????????????????????????????????????raw_ostream &O) { > + ?const MCOperand &MO1 = MI->getOperand(Op); > + ?const MCOperand &MO2 = MI->getOperand(Op+1); > + ?const MCOperand &MO3 = MI->getOperand(Op+2); > + > + ?O << "[" << getRegisterName(MO1.getReg()) << "], "; > + > + ?if (!MO2.getReg()) { > + ???unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); > + ???O << '#' > + ?????<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) > + ?????<< ImmOffs; > + ???return; > + ?} > + > + ?O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) > + ???<< getRegisterName(MO2.getReg()); > + > + ?if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) > + ???O << ", " > + ???<< ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) > + ???<< " #" << ShImm; > +} > + > +void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, > + ??????????????????????????????????????????raw_ostream &O) { > + ?const MCOperand &MO1 = MI->getOperand(Op); > + > + ?if (!MO1.isReg()) { ??// FIXME: This is for CP entries, but isn't right. > + ???printOperand(MI, Op, O); > + ???return; > + ?} > + > + ?const MCOperand &MO3 = MI->getOperand(Op+2); > + ?unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm()); > + > + ?if (IdxMode == ARMII::IndexModePost) { > + ???printAM2PostIndexOp(MI, Op, O); > + ???return; > + ?} > + ?printAM2PreOrOffsetIndexOp(MI, Op, O); > +} > + > void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, > ?????????????????????????????????????????????????unsigned OpNum, > ?????????????????????????????????????????????????raw_ostream &O) { > > Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=128632&r1=128631&r2=128632&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original) > +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Thu Mar 31 > 09:52:28 2011 > @@ -42,7 +42,11 @@ > ??void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > > ??void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > + > ??void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream > &O); > + ?void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream > &O); > + ?void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, > + ?????????????????????????????????raw_ostream &O); > ??void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, > ???????????????????????????????????raw_ostream &O); > ??void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream > &O); > > Added: llvm/trunk/test/MC/ARM/arm_addrmode2.s > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128632&view=auto > ============================================================================== > --- llvm/trunk/test/MC/ARM/arm_addrmode2.s (added) > +++ llvm/trunk/test/MC/ARM/arm_addrmode2.s Thu Mar 31 09:52:28 2011 > @@ -0,0 +1,38 @@ > +@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding > %s | FileCheck %s > + > +@ Post-indexed > +@ CHECK: ldrt ?r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6] > +@ CHECK: ldrt ?r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6] > +@ CHECK: ldrt ?r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4] > +@ CHECK: ldrbt ?r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6] > +@ CHECK: ldrbt ?r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6] > +@ CHECK: ldrbt ?r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4] > +@ CHECK: strt ?r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6] > +@ CHECK: strt ?r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6] > +@ CHECK: strt ?r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4] > +@ CHECK: strbt ?r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6] > +@ CHECK: strbt ?r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6] > +@ CHECK: strbt ?r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4] > +@ CHECK: ldr ?r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0x90,0xe6] > +@ CHECK: ldrb ?r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xd0,0xe6] > + ???????ldrt ?r1, [r0], r2 > + ???????ldrt ?r1, [r0], r2, lsr #3 > + ???????ldrt ?r1, [r0], #4 > + ???????ldrbt ?r1, [r0], r2 > + ???????ldrbt ?r1, [r0], r2, lsr #3 > + ???????ldrbt ?r1, [r0], #4 > + ???????strt ?r1, [r0], r2 > + ???????strt ?r1, [r0], r2, lsr #3 > + ???????strt ?r1, [r0], #4 > + ???????strbt ?r1, [r0], r2 > + ???????strbt ?r1, [r0], r2, lsr #3 > + ???????strbt ?r1, [r0], #4 > + ???????ldr ?r1, [r0], r2, lsr #3 > + ???????ldrb ?r1, [r0], r2, lsr #3 > + > +@ Pre-indexed > +@ CHECK: ldr ?r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7] > +@ CHECK: ldrb ?r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7] > + ???????ldr ?r1, [r0, r2, lsr #3]! > + ???????ldrb ?r1, [r0, r2, lsr #3]! > + > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -- Bruno Cardoso Lopes http://www.brunocardoso.cc From bruno.cardoso at gmail.com Thu Mar 31 10:54:36 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Thu, 31 Mar 2011 15:54:36 -0000 Subject: [llvm-commits] [llvm] r128635 - in /llvm/trunk: lib/Target/ARM/ARMAddressingModes.h lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.h test/MC/ARM/arm_addrmode2.s Message-ID: <20110331155436.CED622A6C12C@llvm.org> Author: bruno Date: Thu Mar 31 10:54:36 2011 New Revision: 128635 URL: http://llvm.org/viewvc/llvm-project?rev=128635&view=rev Log: Revert r128632 again, until I figure out what break the tests Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h llvm/trunk/lib/Target/ARM/ARMBaseInfo.h llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h llvm/trunk/lib/Target/ARM/ARMInstrFormats.td llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h llvm/trunk/test/MC/ARM/arm_addrmode2.s Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAddressingModes.h?rev=128635&r1=128634&r2=128635&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAddressingModes.h (original) +++ llvm/trunk/lib/Target/ARM/ARMAddressingModes.h Thu Mar 31 10:54:36 2011 @@ -408,18 +408,16 @@ // // The first operand is always a Reg. The second operand is a reg if in // reg/reg form, otherwise it's reg#0. The third field encodes the operation - // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The - // forth operand 16-17 encodes the index mode. + // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. // // If this addressing mode is a frame index (before prolog/epilog insertion // and code rewriting), this operand will have the form: FI#, reg0, // with no shift amount for the frame offset. // - static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, - unsigned IdxMode = 0) { + static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO) { assert(Imm12 < (1 << 12) && "Imm too large!"); bool isSub = Opc == sub; - return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ; + return Imm12 | ((int)isSub << 12) | (SO << 13); } static inline unsigned getAM2Offset(unsigned AM2Opc) { return AM2Opc & ((1 << 12)-1); @@ -428,10 +426,7 @@ return ((AM2Opc >> 12) & 1) ? sub : add; } static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) { - return (ShiftOpc)((AM2Opc >> 13) & 7); - } - static inline unsigned getAM2IdxMode(unsigned AM2Opc) { - return (AM2Opc >> 16); + return (ShiftOpc)(AM2Opc >> 13); } Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=128635&r1=128634&r2=128635&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Thu Mar 31 10:54:36 2011 @@ -200,59 +200,6 @@ } namespace ARMII { - - /// ARM Index Modes - enum IndexMode { - IndexModeNone = 0, - IndexModePre = 1, - IndexModePost = 2, - IndexModeUpd = 3 - }; - - /// ARM Addressing Modes - enum AddrMode { - AddrModeNone = 0, - AddrMode1 = 1, - AddrMode2 = 2, - AddrMode3 = 3, - AddrMode4 = 4, - AddrMode5 = 5, - AddrMode6 = 6, - AddrModeT1_1 = 7, - AddrModeT1_2 = 8, - AddrModeT1_4 = 9, - AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data - AddrModeT2_i12 = 11, - AddrModeT2_i8 = 12, - AddrModeT2_so = 13, - AddrModeT2_pc = 14, // +/- i12 for pc relative data - AddrModeT2_i8s4 = 15, // i8 * 4 - AddrMode_i12 = 16 - }; - - inline static const char *AddrModeToString(AddrMode addrmode) { - switch (addrmode) { - default: llvm_unreachable("Unknown memory operation"); - case AddrModeNone: return "AddrModeNone"; - case AddrMode1: return "AddrMode1"; - case AddrMode2: return "AddrMode2"; - case AddrMode3: return "AddrMode3"; - case AddrMode4: return "AddrMode4"; - case AddrMode5: return "AddrMode5"; - case AddrMode6: return "AddrMode6"; - case AddrModeT1_1: return "AddrModeT1_1"; - case AddrModeT1_2: return "AddrModeT1_2"; - case AddrModeT1_4: return "AddrModeT1_4"; - case AddrModeT1_s: return "AddrModeT1_s"; - case AddrModeT2_i12: return "AddrModeT2_i12"; - case AddrModeT2_i8: return "AddrModeT2_i8"; - case AddrModeT2_so: return "AddrModeT2_so"; - case AddrModeT2_pc: return "AddrModeT2_pc"; - case AddrModeT2_i8s4: return "AddrModeT2_i8s4"; - case AddrMode_i12: return "AddrMode_i12"; - } - } - /// Target Operand Flag enum. enum TOF { //===------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=128635&r1=128634&r2=128635&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Thu Mar 31 10:54:36 2011 @@ -34,7 +34,25 @@ //===------------------------------------------------------------------===// // This four-bit field describes the addressing mode used. - AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h + + AddrModeMask = 0x1f, + AddrModeNone = 0, + AddrMode1 = 1, + AddrMode2 = 2, + AddrMode3 = 3, + AddrMode4 = 4, + AddrMode5 = 5, + AddrMode6 = 6, + AddrModeT1_1 = 7, + AddrModeT1_2 = 8, + AddrModeT1_4 = 9, + AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data + AddrModeT2_i12 = 11, + AddrModeT2_i8 = 12, + AddrModeT2_so = 13, + AddrModeT2_pc = 14, // +/- i12 for pc relative data + AddrModeT2_i8s4 = 15, // i8 * 4 + AddrMode_i12 = 16, // Size* - Flags to keep track of the size of an instruction. SizeShift = 5, @@ -46,9 +64,11 @@ // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load // and store ops only. Generic "updating" flag is used for ld/st multiple. - // The index mode enums are declared in ARMBaseInfo.h IndexModeShift = 8, IndexModeMask = 3 << IndexModeShift, + IndexModePre = 1, + IndexModePost = 2, + IndexModeUpd = 3, //===------------------------------------------------------------------===// // Instruction encoding formats. Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128635&r1=128634&r2=128635&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu Mar 31 10:54:36 2011 @@ -515,15 +515,15 @@ : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, pattern> { // AM2 store w/ two operands: (GPR, am2offset) - // {17-14} Rn // {13} 1 == Rm, 0 == imm12 // {12} isAdd // {11-0} imm12/Rm - bits<18> addr; - let Inst{25} = addr{13}; - let Inst{23} = addr{12}; - let Inst{19-16} = addr{17-14}; - let Inst{11-0} = addr{11-0}; + bits<14> offset; + bits<4> Rn; + let Inst{25} = offset{13}; + let Inst{23} = offset{12}; + let Inst{19-16} = Rn; + let Inst{11-0} = offset{11-0}; } // addrmode3 instructions Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128635&r1=128634&r2=128635&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Mar 31 10:54:36 2011 @@ -498,12 +498,6 @@ let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } -def MemMode2AsmOperand : AsmOperandClass { - let Name = "MemMode2"; - let SuperClasses = []; - let ParserMethod = "tryParseMemMode2Operand"; -} - // addrmode2 := reg +/- imm12 // := reg +/- reg shop imm // @@ -511,7 +505,6 @@ ComplexPattern { let EncoderMethod = "getAddrMode2OpValue"; let PrintMethod = "printAddrMode2Operand"; - let ParserMatchClass = MemMode2AsmOperand; let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } @@ -1663,21 +1656,20 @@ let Inst{23} = addr{12}; let Inst{19-16} = addr{17-14}; let Inst{11-0} = addr{11-0}; - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; } def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), - (ins addrmode2:$addr), IndexModePost, LdFrm, itin, - opc, "\t$Rt, $addr", "$addr.base = $Rn_wb", []> { - // {17-14} Rn + (ins GPR:$Rn, am2offset:$offset), + IndexModePost, LdFrm, itin, + opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> { // {13} 1 == Rm, 0 == imm12 // {12} isAdd // {11-0} imm12/Rm - bits<18> addr; - let Inst{25} = addr{13}; - let Inst{23} = addr{12}; - let Inst{19-16} = addr{17-14}; - let Inst{11-0} = addr{11-0}; - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; + bits<14> offset; + bits<4> Rn; + let Inst{25} = offset{13}; + let Inst{23} = offset{12}; + let Inst{19-16} = Rn; + let Inst{11-0} = offset{11-0}; } } @@ -1722,35 +1714,17 @@ // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. let mayLoad = 1, neverHasSideEffects = 1 in { -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb), - (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru, - "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { - // {17-14} Rn - // {13} 1 == Rm, 0 == imm12 - // {12} isAdd - // {11-0} imm12/Rm - bits<18> addr; - let Inst{25} = addr{13}; - let Inst{23} = addr{12}; +def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb), + (ins GPR:$base, am2offset:$offset), IndexModePost, + LdFrm, IIC_iLoad_ru, + "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { let Inst{21} = 1; // overwrite - let Inst{19-16} = addr{17-14}; - let Inst{11-0} = addr{11-0}; - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; -} -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), - (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru, - "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { - // {17-14} Rn - // {13} 1 == Rm, 0 == imm12 - // {12} isAdd - // {11-0} imm12/Rm - bits<18> addr; - let Inst{25} = addr{13}; - let Inst{23} = addr{12}; +} +def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb), + (ins GPR:$base, am2offset:$offset), IndexModePost, + LdFrm, IIC_iLoad_bh_ru, + "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { let Inst{21} = 1; // overwrite - let Inst{19-16} = addr{17-14}; - let Inst{11-0} = addr{11-0}; - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; } def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb), (ins GPR:$base, am3offset:$offset), IndexModePost, @@ -1844,20 +1818,20 @@ // STRT, STRBT, and STRHT are for disassembly only. -def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), +def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, GPR:$Rn,am2offset:$offset), IndexModePost, StFrm, IIC_iStore_ru, - "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb", + "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", [/* For disassembly only; pattern left blank */]> { let Inst{21} = 1; // overwrite - let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; } -def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), +def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), IndexModePost, StFrm, IIC_iStore_bh_ru, - "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb", + "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", [/* For disassembly only; pattern left blank */]> { let Inst{21} = 1; // overwrite - let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; } def STRHT: AI3sthpo<(outs GPR:$base_wb), @@ -3417,9 +3391,8 @@ let Inst{23-20} = opc1; } -class ACI - : I + : I { let Inst{27-25} = 0b110; } @@ -3438,7 +3411,7 @@ def _PRE : ACI<(outs), (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> { + opc, "\tp$cop, cr$CRd, $addr!"> { let Inst{31-28} = op31_28; let Inst{24} = 1; // P = 1 let Inst{21} = 1; // W = 1 @@ -3447,8 +3420,8 @@ } def _POST : ACI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - opc, "\tp$cop, cr$CRd, $addr", IndexModePost> { + (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), + opc, "\tp$cop, cr$CRd, [$base], $offset"> { let Inst{31-28} = op31_28; let Inst{24} = 0; // P = 0 let Inst{21} = 1; // W = 1 @@ -3479,7 +3452,7 @@ def L_PRE : ACI<(outs), (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> { + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { let Inst{31-28} = op31_28; let Inst{24} = 1; // P = 1 let Inst{21} = 1; // W = 1 @@ -3488,8 +3461,8 @@ } def L_POST : ACI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr", IndexModePost> { + (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), + !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> { let Inst{31-28} = op31_28; let Inst{24} = 0; // P = 0 let Inst{21} = 1; // W = 1 Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128635&r1=128634&r2=128635&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Mar 31 10:54:36 2011 @@ -48,8 +48,7 @@ bool TryParseRegisterWithWriteBack(SmallVectorImpl &); bool TryParseShiftRegister(SmallVectorImpl &); bool ParseRegisterList(SmallVectorImpl &); - bool ParseMemory(SmallVectorImpl &, - ARMII::AddrMode AddrMode); + bool ParseMemory(SmallVectorImpl &); bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic); bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); const MCExpr *ApplyPrefixToExpr(const MCExpr *E, @@ -96,14 +95,6 @@ SmallVectorImpl&); OperandMatchResultTy tryParseMSRMaskOperand( SmallVectorImpl&); - OperandMatchResultTy tryParseMemMode2Operand( - SmallVectorImpl&); - - // Asm Match Converter Methods - bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, - const SmallVectorImpl &); - bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, - const SmallVectorImpl &); public: ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) @@ -181,7 +172,6 @@ /// Combined record for all forms of ARM address expressions. struct { - ARMII::AddrMode AddrMode; unsigned BaseRegNum; union { unsigned RegNum; ///< Offset register num, when OffsetIsReg. @@ -303,9 +293,7 @@ /// @name Memory Operand Accessors /// @{ - ARMII::AddrMode getMemAddrMode() const { - return Mem.AddrMode; - } + unsigned getMemBaseRegNum() const { return Mem.BaseRegNum; } @@ -350,27 +338,6 @@ bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } bool isMemory() const { return Kind == Memory; } bool isShifter() const { return Kind == Shifter; } - bool isMemMode2() const { - if (getMemAddrMode() != ARMII::AddrMode2) - return false; - - if (getMemOffsetIsReg()) - return true; - - if (getMemNegative() && - !(getMemPostindexed() || getMemPreindexed())) - return false; - - const MCConstantExpr *CE = dyn_cast(getMemOffset()); - if (!CE) return false; - int64_t Value = CE->getValue(); - - // The offset must be in the range 0-4095 (imm12). - if (Value > 4095 || Value < -4095) - return false; - - return true; - } bool isMemMode5() const { if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || getMemNegative()) @@ -498,47 +465,6 @@ "No offset operand support in mode 7"); } - void addMemMode2Operands(MCInst &Inst, unsigned N) const { - assert(isMemMode2() && "Invalid mode or number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); - unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); - - if (getMemOffsetIsReg()) { - Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); - - ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; - ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; - int64_t ShiftAmount = 0; - - if (getMemOffsetRegShifted()) { - ShOpc = getMemShiftType(); - const MCConstantExpr *CE = - dyn_cast(getMemShiftAmount()); - ShiftAmount = CE->getValue(); - } - - Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, - ShOpc, IdxMode))); - return; - } - - // Create a operand placeholder to always yield the same number of operands. - Inst.addOperand(MCOperand::CreateReg(0)); - - // FIXME: #-0 is encoded differently than #0. Does the parser preserve - // the difference? - const MCConstantExpr *CE = dyn_cast(getMemOffset()); - assert(CE && "Non-constant mode 2 offset operand!"); - int64_t Offset = CE->getValue(); - - if (Offset >= 0) - Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, - Offset, ARM_AM::no_shift, IdxMode))); - else - Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, - -Offset, ARM_AM::no_shift, IdxMode))); - } - void addMemMode5Operands(MCInst &Inst, unsigned N) const { assert(N == 2 && isMemMode5() && "Invalid number of operands!"); @@ -673,9 +599,9 @@ return Op; } - static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, - bool OffsetIsReg, const MCExpr *Offset, - int OffsetRegNum, bool OffsetRegShifted, + static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, + const MCExpr *Offset, int OffsetRegNum, + bool OffsetRegShifted, enum ARM_AM::ShiftOpc ShiftType, const MCExpr *ShiftAmount, bool Preindexed, bool Postindexed, bool Negative, bool Writeback, @@ -692,7 +618,6 @@ "Cannot have expression offset and register offset!"); ARMOperand *Op = new ARMOperand(Memory); - Op->Mem.AddrMode = AddrMode; Op->Mem.BaseRegNum = BaseRegNum; Op->Mem.OffsetIsReg = OffsetIsReg; if (OffsetIsReg) @@ -764,8 +689,7 @@ break; case Memory: OS << " &Operands) { - SMLoc S = Parser.getTok().getLoc(); - const AsmToken &Tok = Parser.getTok(); - assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\""); - - if (ParseMemory(Operands, ARMII::AddrMode2)) - return MatchOperand_NoMatch; - - return MatchOperand_Success; -} - -/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. -/// Needed here because the Asm Gen Matcher can't handle properly tied operands -/// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: -CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, - const SmallVectorImpl &Operands) { - ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); - - // Create a writeback register dummy placeholder. - Inst.addOperand(MCOperand::CreateImm(0)); - - ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); - ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; -} - -/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. -/// Needed here because the Asm Gen Matcher can't handle properly tied operands -/// when they refer multiple MIOperands inside a single one. -bool ARMAsmParser:: -CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, - const SmallVectorImpl &Operands) { - // Create a writeback register dummy placeholder. - Inst.addOperand(MCOperand::CreateImm(0)); - ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); - ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); - ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); - return true; -} - /// Parse an ARM memory expression, return false if successful else return true /// or an error. The first token must be a '[' when called. /// /// TODO Only preindexing and postindexing addressing are started, unindexed /// with option, etc are still to do. bool ARMAsmParser:: -ParseMemory(SmallVectorImpl &Operands, - ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { +ParseMemory(SmallVectorImpl &Operands) { SMLoc S, E; assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a Left Bracket"); @@ -1316,9 +1196,6 @@ ExclaimTok.getLoc()); Writeback = true; Parser.Lex(); // Eat exclaim token - } else { // In addressing mode 2, pre-indexed mode always end with "!" - if (AddrMode == ARMII::AddrMode2) - Preindexed = false; } } else { // The "[Rn" we have so far was not followed by a comma. @@ -1354,10 +1231,11 @@ Offset = MCConstantExpr::Create(0, getContext()); } - Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, - Offset, OffsetRegNum, OffsetRegShifted, - ShiftType, ShiftAmount, Preindexed, - Postindexed, Negative, Writeback, S, E)); + Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, + OffsetRegNum, OffsetRegShifted, + ShiftType, ShiftAmount, Preindexed, + Postindexed, Negative, Writeback, + S, E)); if (WBOp) Operands.push_back(WBOp); Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128635&r1=128634&r2=128635&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Thu Mar 31 10:54:36 2011 @@ -643,11 +643,8 @@ if (PW) { MI.addOperand(MCOperand::CreateReg(0)); ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; - const TargetInstrDesc &TID = ARMInsts[Opcode]; - unsigned IndexMode = - (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << 2, - ARM_AM::no_shift, IndexMode); + ARM_AM::no_shift); MI.addOperand(MCOperand::CreateImm(Offset)); OpIdx = 5; } else { @@ -1076,8 +1073,6 @@ return false; ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; - unsigned IndexMode = - (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; if (getIBit(insn) == 0) { // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2). // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already @@ -1089,8 +1084,7 @@ // Disassemble the 12-bit immediate offset. unsigned Imm12 = slice(insn, 11, 0); - unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift, - IndexMode); + unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift); MI.addOperand(MCOperand::CreateImm(Offset)); OpIdx += 1; } else { @@ -1105,7 +1099,7 @@ // A8.4.1. Possible rrx or shift amount of 32... getImmShiftSE(ShOp, ShImm); MI.addOperand(MCOperand::CreateImm( - ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, IndexMode))); + ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp))); OpIdx += 2; } Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=128635&r1=128634&r2=128635&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Thu Mar 31 10:54:36 2011 @@ -181,12 +181,18 @@ } } -void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, - raw_ostream &O) { + +void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, + raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(Op); const MCOperand &MO2 = MI->getOperand(Op+1); const MCOperand &MO3 = MI->getOperand(Op+2); + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. + printOperand(MI, Op, O); + return; + } + O << "[" << getRegisterName(MO1.getReg()); if (!MO2.getReg()) { @@ -209,50 +215,6 @@ O << "]"; } -void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, - raw_ostream &O) { - const MCOperand &MO1 = MI->getOperand(Op); - const MCOperand &MO2 = MI->getOperand(Op+1); - const MCOperand &MO3 = MI->getOperand(Op+2); - - O << "[" << getRegisterName(MO1.getReg()) << "], "; - - if (!MO2.getReg()) { - unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); - O << '#' - << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) - << ImmOffs; - return; - } - - O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) - << getRegisterName(MO2.getReg()); - - if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) - O << ", " - << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) - << " #" << ShImm; -} - -void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, - raw_ostream &O) { - const MCOperand &MO1 = MI->getOperand(Op); - - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. - printOperand(MI, Op, O); - return; - } - - const MCOperand &MO3 = MI->getOperand(Op+2); - unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm()); - - if (IdxMode == ARMII::IndexModePost) { - printAM2PostIndexOp(MI, Op, O); - return; - } - printAM2PreOrOffsetIndexOp(MI, Op, O); -} - void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) { Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=128635&r1=128634&r2=128635&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Thu Mar 31 10:54:36 2011 @@ -42,11 +42,7 @@ void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, - raw_ostream &O); void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); Modified: llvm/trunk/test/MC/ARM/arm_addrmode2.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128635&r1=128634&r2=128635&view=diff ============================================================================== --- llvm/trunk/test/MC/ARM/arm_addrmode2.s (original) +++ llvm/trunk/test/MC/ARM/arm_addrmode2.s Thu Mar 31 10:54:36 2011 @@ -1,38 +0,0 @@ -@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | FileCheck %s - -@ Post-indexed -@ CHECK: ldrt r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6] -@ CHECK: ldrt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6] -@ CHECK: ldrt r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4] -@ CHECK: ldrbt r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6] -@ CHECK: ldrbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6] -@ CHECK: ldrbt r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4] -@ CHECK: strt r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6] -@ CHECK: strt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6] -@ CHECK: strt r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4] -@ CHECK: strbt r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6] -@ CHECK: strbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6] -@ CHECK: strbt r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4] -@ CHECK: ldr r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0x90,0xe6] -@ CHECK: ldrb r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xd0,0xe6] - ldrt r1, [r0], r2 - ldrt r1, [r0], r2, lsr #3 - ldrt r1, [r0], #4 - ldrbt r1, [r0], r2 - ldrbt r1, [r0], r2, lsr #3 - ldrbt r1, [r0], #4 - strt r1, [r0], r2 - strt r1, [r0], r2, lsr #3 - strt r1, [r0], #4 - strbt r1, [r0], r2 - strbt r1, [r0], r2, lsr #3 - strbt r1, [r0], #4 - ldr r1, [r0], r2, lsr #3 - ldrb r1, [r0], r2, lsr #3 - -@ Pre-indexed -@ CHECK: ldr r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7] -@ CHECK: ldrb r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7] - ldr r1, [r0, r2, lsr #3]! - ldrb r1, [r0, r2, lsr #3]! - From grosbach at apple.com Thu Mar 31 11:13:34 2011 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 31 Mar 2011 09:13:34 -0700 Subject: [llvm-commits] [llvm] r128635 - in /llvm/trunk: lib/Target/ARM/ARMAddressingModes.h lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.h test/MC/ARM/arm_addrmode2.s In-Reply-To: <20110331155436.CED622A6C12C@llvm.org> References: <20110331155436.CED622A6C12C@llvm.org> Message-ID: <727DB6AA-C6E3-4904-A1F5-4DC4D9A1E0EE@apple.com> Hi Bruno, I'm glad to see you're looking at this. Hopefully the bugs won't be too hard to track down. If you're feeling ambitious, addrmode2 is on its way out in favor of addrmode_imm12 and ldst_so_reg. Specifically, addrmode2 conflates the immediate and register addressing and modally indicates which of the two it's defining by the second register operand being zero. This, as I'm sure you've encountered, gives the asm parser all sorts of fun to deal with, as there are operands that aren't part of the assembly syntax and aren't easily inferable without custom handling. Splitting the operand into parts has two major benefits. First, it helps with the above by making the instruction definition only have machine operands which are actually part of the real instructions. Second, the different addressing modes typically have a different scheduling itinerary, and that's not expressive with a combined addressing mode construct. The AI_ldr1 multiclass, used by the base LDR instructions, has an example of how this works. When you get to doing parsing for the _PRE/_POST instructions that do have associated patterns, there's some complications due to the writeback tied register constraint. The best way we have to represent that right now, albeit kinda ugly, is to use a pseudo-instruction for the code-gen that has the writeback output operand tied to the source base reg, and an assembler-only real instruction (which has the encoding information) that doesn't have an explicit output writeback operand, just the source base operand. The ARMAsmPrinter MC lowering pseudo-expansion would lower the former to the latter. -Jim On Mar 31, 2011, at 8:54 AM, Bruno Cardoso Lopes wrote: > Author: bruno > Date: Thu Mar 31 10:54:36 2011 > New Revision: 128635 > > URL: http://llvm.org/viewvc/llvm-project?rev=128635&view=rev > Log: > Revert r128632 again, until I figure out what break the tests > > Modified: > llvm/trunk/lib/Target/ARM/ARMAddressingModes.h > llvm/trunk/lib/Target/ARM/ARMBaseInfo.h > llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h > llvm/trunk/lib/Target/ARM/ARMInstrFormats.td > llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp > llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp > llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp > llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h > llvm/trunk/test/MC/ARM/arm_addrmode2.s > > Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAddressingModes.h?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMAddressingModes.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMAddressingModes.h Thu Mar 31 10:54:36 2011 > @@ -408,18 +408,16 @@ > // > // The first operand is always a Reg. The second operand is a reg if in > // reg/reg form, otherwise it's reg#0. The third field encodes the operation > - // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The > - // forth operand 16-17 encodes the index mode. > + // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. > // > // If this addressing mode is a frame index (before prolog/epilog insertion > // and code rewriting), this operand will have the form: FI#, reg0, > // with no shift amount for the frame offset. > // > - static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, > - unsigned IdxMode = 0) { > + static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO) { > assert(Imm12 < (1 << 12) && "Imm too large!"); > bool isSub = Opc == sub; > - return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ; > + return Imm12 | ((int)isSub << 12) | (SO << 13); > } > static inline unsigned getAM2Offset(unsigned AM2Opc) { > return AM2Opc & ((1 << 12)-1); > @@ -428,10 +426,7 @@ > return ((AM2Opc >> 12) & 1) ? sub : add; > } > static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) { > - return (ShiftOpc)((AM2Opc >> 13) & 7); > - } > - static inline unsigned getAM2IdxMode(unsigned AM2Opc) { > - return (AM2Opc >> 16); > + return (ShiftOpc)(AM2Opc >> 13); > } > > > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Thu Mar 31 10:54:36 2011 > @@ -200,59 +200,6 @@ > } > > namespace ARMII { > - > - /// ARM Index Modes > - enum IndexMode { > - IndexModeNone = 0, > - IndexModePre = 1, > - IndexModePost = 2, > - IndexModeUpd = 3 > - }; > - > - /// ARM Addressing Modes > - enum AddrMode { > - AddrModeNone = 0, > - AddrMode1 = 1, > - AddrMode2 = 2, > - AddrMode3 = 3, > - AddrMode4 = 4, > - AddrMode5 = 5, > - AddrMode6 = 6, > - AddrModeT1_1 = 7, > - AddrModeT1_2 = 8, > - AddrModeT1_4 = 9, > - AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data > - AddrModeT2_i12 = 11, > - AddrModeT2_i8 = 12, > - AddrModeT2_so = 13, > - AddrModeT2_pc = 14, // +/- i12 for pc relative data > - AddrModeT2_i8s4 = 15, // i8 * 4 > - AddrMode_i12 = 16 > - }; > - > - inline static const char *AddrModeToString(AddrMode addrmode) { > - switch (addrmode) { > - default: llvm_unreachable("Unknown memory operation"); > - case AddrModeNone: return "AddrModeNone"; > - case AddrMode1: return "AddrMode1"; > - case AddrMode2: return "AddrMode2"; > - case AddrMode3: return "AddrMode3"; > - case AddrMode4: return "AddrMode4"; > - case AddrMode5: return "AddrMode5"; > - case AddrMode6: return "AddrMode6"; > - case AddrModeT1_1: return "AddrModeT1_1"; > - case AddrModeT1_2: return "AddrModeT1_2"; > - case AddrModeT1_4: return "AddrModeT1_4"; > - case AddrModeT1_s: return "AddrModeT1_s"; > - case AddrModeT2_i12: return "AddrModeT2_i12"; > - case AddrModeT2_i8: return "AddrModeT2_i8"; > - case AddrModeT2_so: return "AddrModeT2_so"; > - case AddrModeT2_pc: return "AddrModeT2_pc"; > - case AddrModeT2_i8s4: return "AddrModeT2_i8s4"; > - case AddrMode_i12: return "AddrMode_i12"; > - } > - } > - > /// Target Operand Flag enum. > enum TOF { > //===------------------------------------------------------------------===// > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Thu Mar 31 10:54:36 2011 > @@ -34,7 +34,25 @@ > > //===------------------------------------------------------------------===// > // This four-bit field describes the addressing mode used. > - AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h > + > + AddrModeMask = 0x1f, > + AddrModeNone = 0, > + AddrMode1 = 1, > + AddrMode2 = 2, > + AddrMode3 = 3, > + AddrMode4 = 4, > + AddrMode5 = 5, > + AddrMode6 = 6, > + AddrModeT1_1 = 7, > + AddrModeT1_2 = 8, > + AddrModeT1_4 = 9, > + AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data > + AddrModeT2_i12 = 11, > + AddrModeT2_i8 = 12, > + AddrModeT2_so = 13, > + AddrModeT2_pc = 14, // +/- i12 for pc relative data > + AddrModeT2_i8s4 = 15, // i8 * 4 > + AddrMode_i12 = 16, > > // Size* - Flags to keep track of the size of an instruction. > SizeShift = 5, > @@ -46,9 +64,11 @@ > > // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load > // and store ops only. Generic "updating" flag is used for ld/st multiple. > - // The index mode enums are declared in ARMBaseInfo.h > IndexModeShift = 8, > IndexModeMask = 3 << IndexModeShift, > + IndexModePre = 1, > + IndexModePost = 2, > + IndexModeUpd = 3, > > //===------------------------------------------------------------------===// > // Instruction encoding formats. > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu Mar 31 10:54:36 2011 > @@ -515,15 +515,15 @@ > : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, > pattern> { > // AM2 store w/ two operands: (GPR, am2offset) > - // {17-14} Rn > // {13} 1 == Rm, 0 == imm12 > // {12} isAdd > // {11-0} imm12/Rm > - bits<18> addr; > - let Inst{25} = addr{13}; > - let Inst{23} = addr{12}; > - let Inst{19-16} = addr{17-14}; > - let Inst{11-0} = addr{11-0}; > + bits<14> offset; > + bits<4> Rn; > + let Inst{25} = offset{13}; > + let Inst{23} = offset{12}; > + let Inst{19-16} = Rn; > + let Inst{11-0} = offset{11-0}; > } > > // addrmode3 instructions > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Mar 31 10:54:36 2011 > @@ -498,12 +498,6 @@ > let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); > } > > -def MemMode2AsmOperand : AsmOperandClass { > - let Name = "MemMode2"; > - let SuperClasses = []; > - let ParserMethod = "tryParseMemMode2Operand"; > -} > - > // addrmode2 := reg +/- imm12 > // := reg +/- reg shop imm > // > @@ -511,7 +505,6 @@ > ComplexPattern { > let EncoderMethod = "getAddrMode2OpValue"; > let PrintMethod = "printAddrMode2Operand"; > - let ParserMatchClass = MemMode2AsmOperand; > let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); > } > > @@ -1663,21 +1656,20 @@ > let Inst{23} = addr{12}; > let Inst{19-16} = addr{17-14}; > let Inst{11-0} = addr{11-0}; > - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > } > def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), > - (ins addrmode2:$addr), IndexModePost, LdFrm, itin, > - opc, "\t$Rt, $addr", "$addr.base = $Rn_wb", []> { > - // {17-14} Rn > + (ins GPR:$Rn, am2offset:$offset), > + IndexModePost, LdFrm, itin, > + opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> { > // {13} 1 == Rm, 0 == imm12 > // {12} isAdd > // {11-0} imm12/Rm > - bits<18> addr; > - let Inst{25} = addr{13}; > - let Inst{23} = addr{12}; > - let Inst{19-16} = addr{17-14}; > - let Inst{11-0} = addr{11-0}; > - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > + bits<14> offset; > + bits<4> Rn; > + let Inst{25} = offset{13}; > + let Inst{23} = offset{12}; > + let Inst{19-16} = Rn; > + let Inst{11-0} = offset{11-0}; > } > } > > @@ -1722,35 +1714,17 @@ > > // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. > let mayLoad = 1, neverHasSideEffects = 1 in { > -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb), > - (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru, > - "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { > - // {17-14} Rn > - // {13} 1 == Rm, 0 == imm12 > - // {12} isAdd > - // {11-0} imm12/Rm > - bits<18> addr; > - let Inst{25} = addr{13}; > - let Inst{23} = addr{12}; > +def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb), > + (ins GPR:$base, am2offset:$offset), IndexModePost, > + LdFrm, IIC_iLoad_ru, > + "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { > let Inst{21} = 1; // overwrite > - let Inst{19-16} = addr{17-14}; > - let Inst{11-0} = addr{11-0}; > - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > -} > -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), > - (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru, > - "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { > - // {17-14} Rn > - // {13} 1 == Rm, 0 == imm12 > - // {12} isAdd > - // {11-0} imm12/Rm > - bits<18> addr; > - let Inst{25} = addr{13}; > - let Inst{23} = addr{12}; > +} > +def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb), > + (ins GPR:$base, am2offset:$offset), IndexModePost, > + LdFrm, IIC_iLoad_bh_ru, > + "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { > let Inst{21} = 1; // overwrite > - let Inst{19-16} = addr{17-14}; > - let Inst{11-0} = addr{11-0}; > - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > } > def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb), > (ins GPR:$base, am3offset:$offset), IndexModePost, > @@ -1844,20 +1818,20 @@ > > // STRT, STRBT, and STRHT are for disassembly only. > > -def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), > +def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), > + (ins GPR:$Rt, GPR:$Rn,am2offset:$offset), > IndexModePost, StFrm, IIC_iStore_ru, > - "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb", > + "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", > [/* For disassembly only; pattern left blank */]> { > let Inst{21} = 1; // overwrite > - let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; > } > > -def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), > +def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), > + (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), > IndexModePost, StFrm, IIC_iStore_bh_ru, > - "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb", > + "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", > [/* For disassembly only; pattern left blank */]> { > let Inst{21} = 1; // overwrite > - let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; > } > > def STRHT: AI3sthpo<(outs GPR:$base_wb), > @@ -3417,9 +3391,8 @@ > let Inst{23-20} = opc1; > } > > -class ACI - IndexMode im = IndexModeNone> > - : I +class ACI > + : I opc, asm, "", [/* For disassembly only; pattern left blank */]> { > let Inst{27-25} = 0b110; > } > @@ -3438,7 +3411,7 @@ > > def _PRE : ACI<(outs), > (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> { > + opc, "\tp$cop, cr$CRd, $addr!"> { > let Inst{31-28} = op31_28; > let Inst{24} = 1; // P = 1 > let Inst{21} = 1; // W = 1 > @@ -3447,8 +3420,8 @@ > } > > def _POST : ACI<(outs), > - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - opc, "\tp$cop, cr$CRd, $addr", IndexModePost> { > + (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), > + opc, "\tp$cop, cr$CRd, [$base], $offset"> { > let Inst{31-28} = op31_28; > let Inst{24} = 0; // P = 0 > let Inst{21} = 1; // W = 1 > @@ -3479,7 +3452,7 @@ > > def L_PRE : ACI<(outs), > (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> { > + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { > let Inst{31-28} = op31_28; > let Inst{24} = 1; // P = 1 > let Inst{21} = 1; // W = 1 > @@ -3488,8 +3461,8 @@ > } > > def L_POST : ACI<(outs), > - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr", IndexModePost> { > + (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), > + !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> { > let Inst{31-28} = op31_28; > let Inst{24} = 0; // P = 0 > let Inst{21} = 1; // W = 1 > > Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) > +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Mar 31 10:54:36 2011 > @@ -48,8 +48,7 @@ > bool TryParseRegisterWithWriteBack(SmallVectorImpl &); > bool TryParseShiftRegister(SmallVectorImpl &); > bool ParseRegisterList(SmallVectorImpl &); > - bool ParseMemory(SmallVectorImpl &, > - ARMII::AddrMode AddrMode); > + bool ParseMemory(SmallVectorImpl &); > bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic); > bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); > const MCExpr *ApplyPrefixToExpr(const MCExpr *E, > @@ -96,14 +95,6 @@ > SmallVectorImpl&); > OperandMatchResultTy tryParseMSRMaskOperand( > SmallVectorImpl&); > - OperandMatchResultTy tryParseMemMode2Operand( > - SmallVectorImpl&); > - > - // Asm Match Converter Methods > - bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > - const SmallVectorImpl &); > - bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > - const SmallVectorImpl &); > > public: > ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) > @@ -181,7 +172,6 @@ > > /// Combined record for all forms of ARM address expressions. > struct { > - ARMII::AddrMode AddrMode; > unsigned BaseRegNum; > union { > unsigned RegNum; ///< Offset register num, when OffsetIsReg. > @@ -303,9 +293,7 @@ > > /// @name Memory Operand Accessors > /// @{ > - ARMII::AddrMode getMemAddrMode() const { > - return Mem.AddrMode; > - } > + > unsigned getMemBaseRegNum() const { > return Mem.BaseRegNum; > } > @@ -350,27 +338,6 @@ > bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } > bool isMemory() const { return Kind == Memory; } > bool isShifter() const { return Kind == Shifter; } > - bool isMemMode2() const { > - if (getMemAddrMode() != ARMII::AddrMode2) > - return false; > - > - if (getMemOffsetIsReg()) > - return true; > - > - if (getMemNegative() && > - !(getMemPostindexed() || getMemPreindexed())) > - return false; > - > - const MCConstantExpr *CE = dyn_cast(getMemOffset()); > - if (!CE) return false; > - int64_t Value = CE->getValue(); > - > - // The offset must be in the range 0-4095 (imm12). > - if (Value > 4095 || Value < -4095) > - return false; > - > - return true; > - } > bool isMemMode5() const { > if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || > getMemNegative()) > @@ -498,47 +465,6 @@ > "No offset operand support in mode 7"); > } > > - void addMemMode2Operands(MCInst &Inst, unsigned N) const { > - assert(isMemMode2() && "Invalid mode or number of operands!"); > - Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); > - unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); > - > - if (getMemOffsetIsReg()) { > - Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); > - > - ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; > - ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; > - int64_t ShiftAmount = 0; > - > - if (getMemOffsetRegShifted()) { > - ShOpc = getMemShiftType(); > - const MCConstantExpr *CE = > - dyn_cast(getMemShiftAmount()); > - ShiftAmount = CE->getValue(); > - } > - > - Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, > - ShOpc, IdxMode))); > - return; > - } > - > - // Create a operand placeholder to always yield the same number of operands. > - Inst.addOperand(MCOperand::CreateReg(0)); > - > - // FIXME: #-0 is encoded differently than #0. Does the parser preserve > - // the difference? > - const MCConstantExpr *CE = dyn_cast(getMemOffset()); > - assert(CE && "Non-constant mode 2 offset operand!"); > - int64_t Offset = CE->getValue(); > - > - if (Offset >= 0) > - Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, > - Offset, ARM_AM::no_shift, IdxMode))); > - else > - Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, > - -Offset, ARM_AM::no_shift, IdxMode))); > - } > - > void addMemMode5Operands(MCInst &Inst, unsigned N) const { > assert(N == 2 && isMemMode5() && "Invalid number of operands!"); > > @@ -673,9 +599,9 @@ > return Op; > } > > - static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, > - bool OffsetIsReg, const MCExpr *Offset, > - int OffsetRegNum, bool OffsetRegShifted, > + static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, > + const MCExpr *Offset, int OffsetRegNum, > + bool OffsetRegShifted, > enum ARM_AM::ShiftOpc ShiftType, > const MCExpr *ShiftAmount, bool Preindexed, > bool Postindexed, bool Negative, bool Writeback, > @@ -692,7 +618,6 @@ > "Cannot have expression offset and register offset!"); > > ARMOperand *Op = new ARMOperand(Memory); > - Op->Mem.AddrMode = AddrMode; > Op->Mem.BaseRegNum = BaseRegNum; > Op->Mem.OffsetIsReg = OffsetIsReg; > if (OffsetIsReg) > @@ -764,8 +689,7 @@ > break; > case Memory: > OS << " - << "am:" << ARMII::AddrModeToString(getMemAddrMode()) > - << " base:" << getMemBaseRegNum(); > + << "base:" << getMemBaseRegNum(); > if (getMemOffsetIsReg()) { > OS << " offset: if (getMemOffsetRegShifted()) { > @@ -1208,57 +1132,13 @@ > return MatchOperand_Success; > } > > -/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand. > -ARMAsmParser::OperandMatchResultTy ARMAsmParser:: > -tryParseMemMode2Operand(SmallVectorImpl &Operands) { > - SMLoc S = Parser.getTok().getLoc(); > - const AsmToken &Tok = Parser.getTok(); > - assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\""); > - > - if (ParseMemory(Operands, ARMII::AddrMode2)) > - return MatchOperand_NoMatch; > - > - return MatchOperand_Success; > -} > - > -/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. > -/// Needed here because the Asm Gen Matcher can't handle properly tied operands > -/// when they refer multiple MIOperands inside a single one. > -bool ARMAsmParser:: > -CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > - const SmallVectorImpl &Operands) { > - ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); > - > - // Create a writeback register dummy placeholder. > - Inst.addOperand(MCOperand::CreateImm(0)); > - > - ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); > - ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); > - return true; > -} > - > -/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. > -/// Needed here because the Asm Gen Matcher can't handle properly tied operands > -/// when they refer multiple MIOperands inside a single one. > -bool ARMAsmParser:: > -CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > - const SmallVectorImpl &Operands) { > - // Create a writeback register dummy placeholder. > - Inst.addOperand(MCOperand::CreateImm(0)); > - ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); > - ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); > - ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); > - return true; > -} > - > /// Parse an ARM memory expression, return false if successful else return true > /// or an error. The first token must be a '[' when called. > /// > /// TODO Only preindexing and postindexing addressing are started, unindexed > /// with option, etc are still to do. > bool ARMAsmParser:: > -ParseMemory(SmallVectorImpl &Operands, > - ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { > +ParseMemory(SmallVectorImpl &Operands) { > SMLoc S, E; > assert(Parser.getTok().is(AsmToken::LBrac) && > "Token is not a Left Bracket"); > @@ -1316,9 +1196,6 @@ > ExclaimTok.getLoc()); > Writeback = true; > Parser.Lex(); // Eat exclaim token > - } else { // In addressing mode 2, pre-indexed mode always end with "!" > - if (AddrMode == ARMII::AddrMode2) > - Preindexed = false; > } > } else { > // The "[Rn" we have so far was not followed by a comma. > @@ -1354,10 +1231,11 @@ > Offset = MCConstantExpr::Create(0, getContext()); > } > > - Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, > - Offset, OffsetRegNum, OffsetRegShifted, > - ShiftType, ShiftAmount, Preindexed, > - Postindexed, Negative, Writeback, S, E)); > + Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, > + OffsetRegNum, OffsetRegShifted, > + ShiftType, ShiftAmount, Preindexed, > + Postindexed, Negative, Writeback, > + S, E)); > if (WBOp) > Operands.push_back(WBOp); > > > Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) > +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Thu Mar 31 10:54:36 2011 > @@ -643,11 +643,8 @@ > if (PW) { > MI.addOperand(MCOperand::CreateReg(0)); > ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; > - const TargetInstrDesc &TID = ARMInsts[Opcode]; > - unsigned IndexMode = > - (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; > unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << 2, > - ARM_AM::no_shift, IndexMode); > + ARM_AM::no_shift); > MI.addOperand(MCOperand::CreateImm(Offset)); > OpIdx = 5; > } else { > @@ -1076,8 +1073,6 @@ > return false; > > ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; > - unsigned IndexMode = > - (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; > if (getIBit(insn) == 0) { > // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2). > // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already > @@ -1089,8 +1084,7 @@ > > // Disassemble the 12-bit immediate offset. > unsigned Imm12 = slice(insn, 11, 0); > - unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift, > - IndexMode); > + unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift); > MI.addOperand(MCOperand::CreateImm(Offset)); > OpIdx += 1; > } else { > @@ -1105,7 +1099,7 @@ > // A8.4.1. Possible rrx or shift amount of 32... > getImmShiftSE(ShOp, ShImm); > MI.addOperand(MCOperand::CreateImm( > - ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, IndexMode))); > + ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp))); > OpIdx += 2; > } > > > Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original) > +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Thu Mar 31 10:54:36 2011 > @@ -181,12 +181,18 @@ > } > } > > -void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, > - raw_ostream &O) { > + > +void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, > + raw_ostream &O) { > const MCOperand &MO1 = MI->getOperand(Op); > const MCOperand &MO2 = MI->getOperand(Op+1); > const MCOperand &MO3 = MI->getOperand(Op+2); > > + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. > + printOperand(MI, Op, O); > + return; > + } > + > O << "[" << getRegisterName(MO1.getReg()); > > if (!MO2.getReg()) { > @@ -209,50 +215,6 @@ > O << "]"; > } > > -void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, > - raw_ostream &O) { > - const MCOperand &MO1 = MI->getOperand(Op); > - const MCOperand &MO2 = MI->getOperand(Op+1); > - const MCOperand &MO3 = MI->getOperand(Op+2); > - > - O << "[" << getRegisterName(MO1.getReg()) << "], "; > - > - if (!MO2.getReg()) { > - unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); > - O << '#' > - << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) > - << ImmOffs; > - return; > - } > - > - O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) > - << getRegisterName(MO2.getReg()); > - > - if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) > - O << ", " > - << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) > - << " #" << ShImm; > -} > - > -void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, > - raw_ostream &O) { > - const MCOperand &MO1 = MI->getOperand(Op); > - > - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. > - printOperand(MI, Op, O); > - return; > - } > - > - const MCOperand &MO3 = MI->getOperand(Op+2); > - unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm()); > - > - if (IdxMode == ARMII::IndexModePost) { > - printAM2PostIndexOp(MI, Op, O); > - return; > - } > - printAM2PreOrOffsetIndexOp(MI, Op, O); > -} > - > void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, > unsigned OpNum, > raw_ostream &O) { > > Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original) > +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Thu Mar 31 10:54:36 2011 > @@ -42,11 +42,7 @@ > void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > > void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > - > void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > - void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O); > - void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, > - raw_ostream &O); > void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, > raw_ostream &O); > void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > > Modified: llvm/trunk/test/MC/ARM/arm_addrmode2.s > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/test/MC/ARM/arm_addrmode2.s (original) > +++ llvm/trunk/test/MC/ARM/arm_addrmode2.s Thu Mar 31 10:54:36 2011 > @@ -1,38 +0,0 @@ > -@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | FileCheck %s > - > -@ Post-indexed > -@ CHECK: ldrt r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6] > -@ CHECK: ldrt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6] > -@ CHECK: ldrt r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4] > -@ CHECK: ldrbt r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6] > -@ CHECK: ldrbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6] > -@ CHECK: ldrbt r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4] > -@ CHECK: strt r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6] > -@ CHECK: strt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6] > -@ CHECK: strt r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4] > -@ CHECK: strbt r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6] > -@ CHECK: strbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6] > -@ CHECK: strbt r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4] > -@ CHECK: ldr r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0x90,0xe6] > -@ CHECK: ldrb r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xd0,0xe6] > - ldrt r1, [r0], r2 > - ldrt r1, [r0], r2, lsr #3 > - ldrt r1, [r0], #4 > - ldrbt r1, [r0], r2 > - ldrbt r1, [r0], r2, lsr #3 > - ldrbt r1, [r0], #4 > - strt r1, [r0], r2 > - strt r1, [r0], r2, lsr #3 > - strt r1, [r0], #4 > - strbt r1, [r0], r2 > - strbt r1, [r0], r2, lsr #3 > - strbt r1, [r0], #4 > - ldr r1, [r0], r2, lsr #3 > - ldrb r1, [r0], r2, lsr #3 > - > -@ Pre-indexed > -@ CHECK: ldr r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7] > -@ CHECK: ldrb r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7] > - ldr r1, [r0, r2, lsr #3]! > - ldrb r1, [r0, r2, lsr #3]! > - > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Thu Mar 31 11:24:55 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 31 Mar 2011 18:24:55 +0200 Subject: [llvm-commits] [PATCH] Instcombine : extractelement(cast) -> cast(extractelement) In-Reply-To: <6594DDFF12B03D4E89690887C248699402787296A3@hasmsx504.ger.corp.intel.com> References: <6594DDFF12B03D4E89690887C248699402787296A3@hasmsx504.ger.corp.intel.com> Message-ID: <4D94AAD7.1000604@free.fr> Hi Nadav, > + return CastInst::Create(CI->getOpcode(), cast(EE), > > + EI.getType()); as far as I can see there is no need to cast to an instruction. And if the vector was a constant then the builder will have created a constant extract element in which case casting to an instruction will cause an assertion failure. So I suggest you just remove the cast. Looks good otherwise. Ciao, Duncan. From dpatel at apple.com Thu Mar 31 11:53:49 2011 From: dpatel at apple.com (Devang Patel) Date: Thu, 31 Mar 2011 16:53:49 -0000 Subject: [llvm-commits] [llvm] r128639 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Message-ID: <20110331165349.57A8F2A6C12C@llvm.org> Author: dpatel Date: Thu Mar 31 11:53:49 2011 New Revision: 128639 URL: http://llvm.org/viewvc/llvm-project?rev=128639&view=rev Log: Remove dead code. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=128639&r1=128638&r2=128639&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Thu Mar 31 11:53:49 2011 @@ -255,12 +255,8 @@ MCSymbol *FunctionBeginSym, *FunctionEndSym; DIEInteger *DIEIntegerOne; -private: - /// getNumSourceIds - Return the number of unique source ids. - unsigned getNumSourceIds() const { - return SourceIdMap.size(); - } +private: /// assignAbbrevNumber - Define a unique number for the abbreviation. /// From daniel at zuster.org Thu Mar 31 12:01:56 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 31 Mar 2011 17:01:56 -0000 Subject: [llvm-commits] [llvm] r128640 - /llvm/trunk/test/MC/ARM/arm_addrmode2.s Message-ID: <20110331170156.DC82D2A6C12C@llvm.org> Author: ddunbar Date: Thu Mar 31 12:01:56 2011 New Revision: 128640 URL: http://llvm.org/viewvc/llvm-project?rev=128640&view=rev Log: Remove stray empty test file. Removed: llvm/trunk/test/MC/ARM/arm_addrmode2.s Removed: llvm/trunk/test/MC/ARM/arm_addrmode2.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128639&view=auto ============================================================================== (empty) From daniel at zuster.org Thu Mar 31 12:06:24 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 31 Mar 2011 10:06:24 -0700 Subject: [llvm-commits] [llvm] r128635 - in /llvm/trunk: lib/Target/ARM/ARMAddressingModes.h lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmPar Message-ID: Hi Bruno, FYI, you removed all the contents of arm_addrmode2.s, but didn't remove the file. This means the test will fail, because it is empty. I removed the file in r128640. - Daniel On Thu, Mar 31, 2011 at 8:54 AM, Bruno Cardoso Lopes wrote: > Author: bruno > Date: Thu Mar 31 10:54:36 2011 > New Revision: 128635 > > URL: http://llvm.org/viewvc/llvm-project?rev=128635&view=rev > Log: > Revert r128632 again, until I figure out what break the tests > > Modified: > ? ?llvm/trunk/lib/Target/ARM/ARMAddressingModes.h > ? ?llvm/trunk/lib/Target/ARM/ARMBaseInfo.h > ? ?llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h > ? ?llvm/trunk/lib/Target/ARM/ARMInstrFormats.td > ? ?llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > ? ?llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp > ? ?llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp > ? ?llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp > ? ?llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h > ? ?llvm/trunk/test/MC/ARM/arm_addrmode2.s > > Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAddressingModes.h?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMAddressingModes.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMAddressingModes.h Thu Mar 31 10:54:36 2011 > @@ -408,18 +408,16 @@ > ? // > ? // The first operand is always a Reg. ?The second operand is a reg if in > ? // reg/reg form, otherwise it's reg#0. ?The third field encodes the operation > - ?// in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The > - ?// forth operand 16-17 encodes the index mode. > + ?// in bit 12, the immediate in bits 0-11, and the shift op in 13-15. > ? // > ? // If this addressing mode is a frame index (before prolog/epilog insertion > ? // and code rewriting), this operand will have the form: ?FI#, reg0, > ? // with no shift amount for the frame offset. > ? // > - ?static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned IdxMode = 0) { > + ?static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO) { > ? ? assert(Imm12 < (1 << 12) && "Imm too large!"); > ? ? bool isSub = Opc == sub; > - ? ?return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ; > + ? ?return Imm12 | ((int)isSub << 12) | (SO << 13); > ? } > ? static inline unsigned getAM2Offset(unsigned AM2Opc) { > ? ? return AM2Opc & ((1 << 12)-1); > @@ -428,10 +426,7 @@ > ? ? return ((AM2Opc >> 12) & 1) ? sub : add; > ? } > ? static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) { > - ? ?return (ShiftOpc)((AM2Opc >> 13) & 7); > - ?} > - ?static inline unsigned getAM2IdxMode(unsigned AM2Opc) { > - ? ?return (AM2Opc >> 16); > + ? ?return (ShiftOpc)(AM2Opc >> 13); > ? } > > > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Thu Mar 31 10:54:36 2011 > @@ -200,59 +200,6 @@ > ?} > > ?namespace ARMII { > - > - ?/// ARM Index Modes > - ?enum IndexMode { > - ? ?IndexModeNone ?= 0, > - ? ?IndexModePre ? = 1, > - ? ?IndexModePost ?= 2, > - ? ?IndexModeUpd ? = 3 > - ?}; > - > - ?/// ARM Addressing Modes > - ?enum AddrMode { > - ? ?AddrModeNone ? ?= 0, > - ? ?AddrMode1 ? ? ? = 1, > - ? ?AddrMode2 ? ? ? = 2, > - ? ?AddrMode3 ? ? ? = 3, > - ? ?AddrMode4 ? ? ? = 4, > - ? ?AddrMode5 ? ? ? = 5, > - ? ?AddrMode6 ? ? ? = 6, > - ? ?AddrModeT1_1 ? ?= 7, > - ? ?AddrModeT1_2 ? ?= 8, > - ? ?AddrModeT1_4 ? ?= 9, > - ? ?AddrModeT1_s ? ?= 10, // i8 * 4 for pc and sp relative data > - ? ?AddrModeT2_i12 ?= 11, > - ? ?AddrModeT2_i8 ? = 12, > - ? ?AddrModeT2_so ? = 13, > - ? ?AddrModeT2_pc ? = 14, // +/- i12 for pc relative data > - ? ?AddrModeT2_i8s4 = 15, // i8 * 4 > - ? ?AddrMode_i12 ? ?= 16 > - ?}; > - > - ?inline static const char *AddrModeToString(AddrMode addrmode) { > - ? ?switch (addrmode) { > - ? ?default: llvm_unreachable("Unknown memory operation"); > - ? ?case AddrModeNone: ? ?return "AddrModeNone"; > - ? ?case AddrMode1: ? ? ? return "AddrMode1"; > - ? ?case AddrMode2: ? ? ? return "AddrMode2"; > - ? ?case AddrMode3: ? ? ? return "AddrMode3"; > - ? ?case AddrMode4: ? ? ? return "AddrMode4"; > - ? ?case AddrMode5: ? ? ? return "AddrMode5"; > - ? ?case AddrMode6: ? ? ? return "AddrMode6"; > - ? ?case AddrModeT1_1: ? ?return "AddrModeT1_1"; > - ? ?case AddrModeT1_2: ? ?return "AddrModeT1_2"; > - ? ?case AddrModeT1_4: ? ?return "AddrModeT1_4"; > - ? ?case AddrModeT1_s: ? ?return "AddrModeT1_s"; > - ? ?case AddrModeT2_i12: ?return "AddrModeT2_i12"; > - ? ?case AddrModeT2_i8: ? return "AddrModeT2_i8"; > - ? ?case AddrModeT2_so: ? return "AddrModeT2_so"; > - ? ?case AddrModeT2_pc: ? return "AddrModeT2_pc"; > - ? ?case AddrModeT2_i8s4: return "AddrModeT2_i8s4"; > - ? ?case AddrMode_i12: ? ?return "AddrMode_i12"; > - ? ?} > - ?} > - > ? /// Target Operand Flag enum. > ? enum TOF { > ? ? //===------------------------------------------------------------------===// > > Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Thu Mar 31 10:54:36 2011 > @@ -34,7 +34,25 @@ > > ? ? //===------------------------------------------------------------------===// > ? ? // This four-bit field describes the addressing mode used. > - ? ?AddrModeMask ?= 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h > + > + ? ?AddrModeMask ?= 0x1f, > + ? ?AddrModeNone ? ?= 0, > + ? ?AddrMode1 ? ? ? = 1, > + ? ?AddrMode2 ? ? ? = 2, > + ? ?AddrMode3 ? ? ? = 3, > + ? ?AddrMode4 ? ? ? = 4, > + ? ?AddrMode5 ? ? ? = 5, > + ? ?AddrMode6 ? ? ? = 6, > + ? ?AddrModeT1_1 ? ?= 7, > + ? ?AddrModeT1_2 ? ?= 8, > + ? ?AddrModeT1_4 ? ?= 9, > + ? ?AddrModeT1_s ? ?= 10, // i8 * 4 for pc and sp relative data > + ? ?AddrModeT2_i12 ?= 11, > + ? ?AddrModeT2_i8 ? = 12, > + ? ?AddrModeT2_so ? = 13, > + ? ?AddrModeT2_pc ? = 14, // +/- i12 for pc relative data > + ? ?AddrModeT2_i8s4 = 15, // i8 * 4 > + ? ?AddrMode_i12 ? ?= 16, > > ? ? // Size* - Flags to keep track of the size of an instruction. > ? ? SizeShift ? ? = 5, > @@ -46,9 +64,11 @@ > > ? ? // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load > ? ? // and store ops only. ?Generic "updating" flag is used for ld/st multiple. > - ? ?// The index mode enums are declared in ARMBaseInfo.h > ? ? IndexModeShift = 8, > ? ? IndexModeMask ?= 3 << IndexModeShift, > + ? ?IndexModePre ? = 1, > + ? ?IndexModePost ?= 2, > + ? ?IndexModeUpd ? = 3, > > ? ? //===------------------------------------------------------------------===// > ? ? // Instruction encoding formats. > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu Mar 31 10:54:36 2011 > @@ -515,15 +515,15 @@ > ? : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, > ? ? ? ? ? ? ? ?pattern> { > ? // AM2 store w/ two operands: (GPR, am2offset) > - ?// {17-14} ?Rn > ? // {13} ? ? 1 == Rm, 0 == imm12 > ? // {12} ? ? isAdd > ? // {11-0} ? imm12/Rm > - ?bits<18> addr; > - ?let Inst{25} = addr{13}; > - ?let Inst{23} = addr{12}; > - ?let Inst{19-16} = addr{17-14}; > - ?let Inst{11-0} = addr{11-0}; > + ?bits<14> offset; > + ?bits<4> Rn; > + ?let Inst{25} = offset{13}; > + ?let Inst{23} = offset{12}; > + ?let Inst{19-16} = Rn; > + ?let Inst{11-0} = offset{11-0}; > ?} > > ?// addrmode3 instructions > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Mar 31 10:54:36 2011 > @@ -498,12 +498,6 @@ > ? let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); > ?} > > -def MemMode2AsmOperand : AsmOperandClass { > - ?let Name = "MemMode2"; > - ?let SuperClasses = []; > - ?let ParserMethod = "tryParseMemMode2Operand"; > -} > - > ?// addrmode2 := reg +/- imm12 > ?// ? ? ? ? ? := reg +/- reg shop imm > ?// > @@ -511,7 +505,6 @@ > ? ? ? ? ? ? ? ? ComplexPattern { > ? let EncoderMethod = "getAddrMode2OpValue"; > ? let PrintMethod = "printAddrMode2Operand"; > - ?let ParserMatchClass = MemMode2AsmOperand; > ? let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); > ?} > > @@ -1663,21 +1656,20 @@ > ? ? let Inst{23} = addr{12}; > ? ? let Inst{19-16} = addr{17-14}; > ? ? let Inst{11-0} = addr{11-0}; > - ? ?let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > ? } > ? def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), > - ? ? ? ? ? ? ? ? ? ? ?(ins addrmode2:$addr), IndexModePost, LdFrm, itin, > - ? ? ? ? ? ? ? ? ? ? ?opc, "\t$Rt, $addr", "$addr.base = $Rn_wb", []> { > - ? ?// {17-14} ?Rn > + ? ? ? ? ? ? ? ? ? ? ?(ins GPR:$Rn, am2offset:$offset), > + ? ? ? ? ? ? ? ? ? ? ?IndexModePost, LdFrm, itin, > + ? ? ? ? ? ? ? ? ? ? ?opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> { > ? ? // {13} ? ? 1 == Rm, 0 == imm12 > ? ? // {12} ? ? isAdd > ? ? // {11-0} ? imm12/Rm > - ? ?bits<18> addr; > - ? ?let Inst{25} = addr{13}; > - ? ?let Inst{23} = addr{12}; > - ? ?let Inst{19-16} = addr{17-14}; > - ? ?let Inst{11-0} = addr{11-0}; > - ? ?let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > + ? ?bits<14> offset; > + ? ?bits<4> Rn; > + ? ?let Inst{25} = offset{13}; > + ? ?let Inst{23} = offset{12}; > + ? ?let Inst{19-16} = Rn; > + ? ?let Inst{11-0} = offset{11-0}; > ? } > ?} > > @@ -1722,35 +1714,17 @@ > > ?// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. > ?let mayLoad = 1, neverHasSideEffects = 1 in { > -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb), > - ? ? ? ? ? ? ? ? ? (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru, > - ? ? ? ? ? ? ? ? ? "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { > - ?// {17-14} ?Rn > - ?// {13} ? ? 1 == Rm, 0 == imm12 > - ?// {12} ? ? isAdd > - ?// {11-0} ? imm12/Rm > - ?bits<18> addr; > - ?let Inst{25} = addr{13}; > - ?let Inst{23} = addr{12}; > +def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb), > + ? ? ? ? ? ? ? ? ? (ins GPR:$base, am2offset:$offset), IndexModePost, > + ? ? ? ? ? ? ? ? ? LdFrm, IIC_iLoad_ru, > + ? ? ? ? ? ? ? ? ? "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { > ? let Inst{21} = 1; // overwrite > - ?let Inst{19-16} = addr{17-14}; > - ?let Inst{11-0} = addr{11-0}; > - ?let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > -} > -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), > - ? ? ? ? ? ? ? ? ?(ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru, > - ? ? ? ? ? ? ? ? ?"ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { > - ?// {17-14} ?Rn > - ?// {13} ? ? 1 == Rm, 0 == imm12 > - ?// {12} ? ? isAdd > - ?// {11-0} ? imm12/Rm > - ?bits<18> addr; > - ?let Inst{25} = addr{13}; > - ?let Inst{23} = addr{12}; > +} > +def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb), > + ? ? ? ? ? ? ? ? ?(ins GPR:$base, am2offset:$offset), IndexModePost, > + ? ? ? ? ? ? ? ? ?LdFrm, IIC_iLoad_bh_ru, > + ? ? ? ? ? ? ? ? ?"ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { > ? let Inst{21} = 1; // overwrite > - ?let Inst{19-16} = addr{17-14}; > - ?let Inst{11-0} = addr{11-0}; > - ?let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; > ?} > ?def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb), > ? ? ? ? ? ? ? ? ?(ins GPR:$base, am3offset:$offset), IndexModePost, > @@ -1844,20 +1818,20 @@ > > ?// STRT, STRBT, and STRHT are for disassembly only. > > -def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), > +def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), > + ? ? ? ? ? ? ? ? ? ?(ins GPR:$Rt, GPR:$Rn,am2offset:$offset), > ? ? ? ? ? ? ? ? ? ? IndexModePost, StFrm, IIC_iStore_ru, > - ? ? ? ? ? ? ? ? ? ?"strt", "\t$Rt, $addr", "$addr.base = $Rn_wb", > + ? ? ? ? ? ? ? ? ? ?"strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", > ? ? ? ? ? ? ? ? ? ? [/* For disassembly only; pattern left blank */]> { > ? let Inst{21} = 1; // overwrite > - ?let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; > ?} > > -def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), > +def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), > + ? ? ? ? ? ? ? ? ? ? (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), > ? ? ? ? ? ? ? ? ? ? ?IndexModePost, StFrm, IIC_iStore_bh_ru, > - ? ? ? ? ? ? ? ? ? ? "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb", > + ? ? ? ? ? ? ? ? ? ? "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", > ? ? ? ? ? ? ? ? ? ? ?[/* For disassembly only; pattern left blank */]> { > ? let Inst{21} = 1; // overwrite > - ?let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; > ?} > > ?def STRHT: AI3sthpo<(outs GPR:$base_wb), > @@ -3417,9 +3391,8 @@ > ? let Inst{23-20} = opc1; > ?} > > -class ACI - ? ? ? ? ?IndexMode im = IndexModeNone> > - ?: I +class ACI > + ?: I ? ? ? opc, asm, "", [/* For disassembly only; pattern left blank */]> { > ? let Inst{27-25} = 0b110; > ?} > @@ -3438,7 +3411,7 @@ > > ? def _PRE : ACI<(outs), > ? ? ? (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - ? ? ?opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> { > + ? ? ?opc, "\tp$cop, cr$CRd, $addr!"> { > ? ? let Inst{31-28} = op31_28; > ? ? let Inst{24} = 1; // P = 1 > ? ? let Inst{21} = 1; // W = 1 > @@ -3447,8 +3420,8 @@ > ? } > > ? def _POST : ACI<(outs), > - ? ? ?(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - ? ? ?opc, "\tp$cop, cr$CRd, $addr", IndexModePost> { > + ? ? ?(ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), > + ? ? ?opc, "\tp$cop, cr$CRd, [$base], $offset"> { > ? ? let Inst{31-28} = op31_28; > ? ? let Inst{24} = 0; // P = 0 > ? ? let Inst{21} = 1; // W = 1 > @@ -3479,7 +3452,7 @@ > > ? def L_PRE : ACI<(outs), > ? ? ? (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - ? ? ?!strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> { > + ? ? ?!strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { > ? ? let Inst{31-28} = op31_28; > ? ? let Inst{24} = 1; // P = 1 > ? ? let Inst{21} = 1; // W = 1 > @@ -3488,8 +3461,8 @@ > ? } > > ? def L_POST : ACI<(outs), > - ? ? ?(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), > - ? ? ?!strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr", IndexModePost> { > + ? ? ?(ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), > + ? ? ?!strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> { > ? ? let Inst{31-28} = op31_28; > ? ? let Inst{24} = 0; // P = 0 > ? ? let Inst{21} = 1; // W = 1 > > Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) > +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Mar 31 10:54:36 2011 > @@ -48,8 +48,7 @@ > ? bool TryParseRegisterWithWriteBack(SmallVectorImpl &); > ? bool TryParseShiftRegister(SmallVectorImpl &); > ? bool ParseRegisterList(SmallVectorImpl &); > - ?bool ParseMemory(SmallVectorImpl &, > - ? ? ? ? ? ? ? ? ? ARMII::AddrMode AddrMode); > + ?bool ParseMemory(SmallVectorImpl &); > ? bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic); > ? bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); > ? const MCExpr *ApplyPrefixToExpr(const MCExpr *E, > @@ -96,14 +95,6 @@ > ? ? SmallVectorImpl&); > ? OperandMatchResultTy tryParseMSRMaskOperand( > ? ? SmallVectorImpl&); > - ?OperandMatchResultTy tryParseMemMode2Operand( > - ? ?SmallVectorImpl&); > - > - ?// Asm Match Converter Methods > - ?bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const SmallVectorImpl &); > - ?bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const SmallVectorImpl &); > > ?public: > ? ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) > @@ -181,7 +172,6 @@ > > ? ? /// Combined record for all forms of ARM address expressions. > ? ? struct { > - ? ? ?ARMII::AddrMode AddrMode; > ? ? ? unsigned BaseRegNum; > ? ? ? union { > ? ? ? ? unsigned RegNum; ? ? ///< Offset register num, when OffsetIsReg. > @@ -303,9 +293,7 @@ > > ? /// @name Memory Operand Accessors > ? /// @{ > - ?ARMII::AddrMode getMemAddrMode() const { > - ? ?return Mem.AddrMode; > - ?} > + > ? unsigned getMemBaseRegNum() const { > ? ? return Mem.BaseRegNum; > ? } > @@ -350,27 +338,6 @@ > ? bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } > ? bool isMemory() const { return Kind == Memory; } > ? bool isShifter() const { return Kind == Shifter; } > - ?bool isMemMode2() const { > - ? ?if (getMemAddrMode() != ARMII::AddrMode2) > - ? ? ?return false; > - > - ? ?if (getMemOffsetIsReg()) > - ? ? ?return true; > - > - ? ?if (getMemNegative() && > - ? ? ? ?!(getMemPostindexed() || getMemPreindexed())) > - ? ? ?return false; > - > - ? ?const MCConstantExpr *CE = dyn_cast(getMemOffset()); > - ? ?if (!CE) return false; > - ? ?int64_t Value = CE->getValue(); > - > - ? ?// The offset must be in the range 0-4095 (imm12). > - ? ?if (Value > 4095 || Value < -4095) > - ? ? ?return false; > - > - ? ?return true; > - ?} > ? bool isMemMode5() const { > ? ? if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || > ? ? ? ? getMemNegative()) > @@ -498,47 +465,6 @@ > ? ? ? ? ? ?"No offset operand support in mode 7"); > ? } > > - ?void addMemMode2Operands(MCInst &Inst, unsigned N) const { > - ? ?assert(isMemMode2() && "Invalid mode or number of operands!"); > - ? ?Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); > - ? ?unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); > - > - ? ?if (getMemOffsetIsReg()) { > - ? ? ?Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); > - > - ? ? ?ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; > - ? ? ?ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; > - ? ? ?int64_t ShiftAmount = 0; > - > - ? ? ?if (getMemOffsetRegShifted()) { > - ? ? ? ?ShOpc = getMemShiftType(); > - ? ? ? ?const MCConstantExpr *CE = > - ? ? ? ? ? ? ? ? ? dyn_cast(getMemShiftAmount()); > - ? ? ? ?ShiftAmount = CE->getValue(); > - ? ? ?} > - > - ? ? ?Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ShOpc, IdxMode))); > - ? ? ?return; > - ? ?} > - > - ? ?// Create a operand placeholder to always yield the same number of operands. > - ? ?Inst.addOperand(MCOperand::CreateReg(0)); > - > - ? ?// FIXME: #-0 is encoded differently than #0. Does the parser preserve > - ? ?// the difference? > - ? ?const MCConstantExpr *CE = dyn_cast(getMemOffset()); > - ? ?assert(CE && "Non-constant mode 2 offset operand!"); > - ? ?int64_t Offset = CE->getValue(); > - > - ? ?if (Offset >= 0) > - ? ? ?Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Offset, ARM_AM::no_shift, IdxMode))); > - ? ?else > - ? ? ?Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-Offset, ARM_AM::no_shift, IdxMode))); > - ?} > - > ? void addMemMode5Operands(MCInst &Inst, unsigned N) const { > ? ? assert(N == 2 && isMemMode5() && "Invalid number of operands!"); > > @@ -673,9 +599,9 @@ > ? ? return Op; > ? } > > - ?static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? bool OffsetIsReg, const MCExpr *Offset, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int OffsetRegNum, bool OffsetRegShifted, > + ?static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const MCExpr *Offset, int OffsetRegNum, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? bool OffsetRegShifted, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?enum ARM_AM::ShiftOpc ShiftType, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const MCExpr *ShiftAmount, bool Preindexed, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?bool Postindexed, bool Negative, bool Writeback, > @@ -692,7 +618,6 @@ > ? ? ? ? ? ?"Cannot have expression offset and register offset!"); > > ? ? ARMOperand *Op = new ARMOperand(Memory); > - ? ?Op->Mem.AddrMode = AddrMode; > ? ? Op->Mem.BaseRegNum = BaseRegNum; > ? ? Op->Mem.OffsetIsReg = OffsetIsReg; > ? ? if (OffsetIsReg) > @@ -764,8 +689,7 @@ > ? ? break; > ? case Memory: > ? ? OS << " - ? ? ? << "am:" << ARMII::AddrModeToString(getMemAddrMode()) > - ? ? ? << " base:" << getMemBaseRegNum(); > + ? ? ? << "base:" << getMemBaseRegNum(); > ? ? if (getMemOffsetIsReg()) { > ? ? ? OS << " offset: ? ? ? if (getMemOffsetRegShifted()) { > @@ -1208,57 +1132,13 @@ > ? return MatchOperand_Success; > ?} > > -/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand. > -ARMAsmParser::OperandMatchResultTy ARMAsmParser:: > -tryParseMemMode2Operand(SmallVectorImpl &Operands) { > - ?SMLoc S = Parser.getTok().getLoc(); > - ?const AsmToken &Tok = Parser.getTok(); > - ?assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\""); > - > - ?if (ParseMemory(Operands, ARMII::AddrMode2)) > - ? ?return MatchOperand_NoMatch; > - > - ?return MatchOperand_Success; > -} > - > -/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. > -/// Needed here because the Asm Gen Matcher can't handle properly tied operands > -/// when they refer multiple MIOperands inside a single one. > -bool ARMAsmParser:: > -CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > - ? ? ? ? ? ? ? ? ? ? ? ? const SmallVectorImpl &Operands) { > - ?((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); > - > - ?// Create a writeback register dummy placeholder. > - ?Inst.addOperand(MCOperand::CreateImm(0)); > - > - ?((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); > - ?((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); > - ?return true; > -} > - > -/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. > -/// Needed here because the Asm Gen Matcher can't handle properly tied operands > -/// when they refer multiple MIOperands inside a single one. > -bool ARMAsmParser:: > -CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, > - ? ? ? ? ? ? ? ? ? ? ? ? const SmallVectorImpl &Operands) { > - ?// Create a writeback register dummy placeholder. > - ?Inst.addOperand(MCOperand::CreateImm(0)); > - ?((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); > - ?((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); > - ?((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); > - ?return true; > -} > - > ?/// Parse an ARM memory expression, return false if successful else return true > ?/// or an error. ?The first token must be a '[' when called. > ?/// > ?/// TODO Only preindexing and postindexing addressing are started, unindexed > ?/// with option, etc are still to do. > ?bool ARMAsmParser:: > -ParseMemory(SmallVectorImpl &Operands, > - ? ? ? ? ? ?ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { > +ParseMemory(SmallVectorImpl &Operands) { > ? SMLoc S, E; > ? assert(Parser.getTok().is(AsmToken::LBrac) && > ? ? ? ? ?"Token is not a Left Bracket"); > @@ -1316,9 +1196,6 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ExclaimTok.getLoc()); > ? ? ? Writeback = true; > ? ? ? Parser.Lex(); // Eat exclaim token > - ? ?} else { // In addressing mode 2, pre-indexed mode always end with "!" > - ? ? ?if (AddrMode == ARMII::AddrMode2) > - ? ? ? ?Preindexed = false; > ? ? } > ? } else { > ? ? // The "[Rn" we have so far was not followed by a comma. > @@ -1354,10 +1231,11 @@ > ? ? ? Offset = MCConstantExpr::Create(0, getContext()); > ? } > > - ?Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Offset, OffsetRegNum, OffsetRegShifted, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ShiftType, ShiftAmount, Preindexed, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Postindexed, Negative, Writeback, S, E)); > + ?Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OffsetRegNum, OffsetRegShifted, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ShiftType, ShiftAmount, Preindexed, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Postindexed, Negative, Writeback, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? S, E)); > ? if (WBOp) > ? ? Operands.push_back(WBOp); > > > Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) > +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Thu Mar 31 10:54:36 2011 > @@ -643,11 +643,8 @@ > ? ? if (PW) { > ? ? ? MI.addOperand(MCOperand::CreateReg(0)); > ? ? ? ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; > - ? ? ?const TargetInstrDesc &TID = ARMInsts[Opcode]; > - ? ? ?unsigned IndexMode = > - ? ? ? ? ? ? ? ? ?(TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; > ? ? ? unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << 2, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ARM_AM::no_shift, IndexMode); > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ARM_AM::no_shift); > ? ? ? MI.addOperand(MCOperand::CreateImm(Offset)); > ? ? ? OpIdx = 5; > ? ? } else { > @@ -1076,8 +1073,6 @@ > ? ? return false; > > ? ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; > - ?unsigned IndexMode = > - ? ? ? ? ? ? ? (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; > ? if (getIBit(insn) == 0) { > ? ? // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2). > ? ? // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already > @@ -1089,8 +1084,7 @@ > > ? ? // Disassemble the 12-bit immediate offset. > ? ? unsigned Imm12 = slice(insn, 11, 0); > - ? ?unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IndexMode); > + ? ?unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift); > ? ? MI.addOperand(MCOperand::CreateImm(Offset)); > ? ? OpIdx += 1; > ? } else { > @@ -1105,7 +1099,7 @@ > ? ? // A8.4.1. ?Possible rrx or shift amount of 32... > ? ? getImmShiftSE(ShOp, ShImm); > ? ? MI.addOperand(MCOperand::CreateImm( > - ? ? ? ? ? ? ? ? ? ?ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, IndexMode))); > + ? ? ? ? ? ? ? ? ? ?ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp))); > ? ? OpIdx += 2; > ? } > > > Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original) > +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Thu Mar 31 10:54:36 2011 > @@ -181,12 +181,18 @@ > ? } > ?} > > -void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &O) { > + > +void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? raw_ostream &O) { > ? const MCOperand &MO1 = MI->getOperand(Op); > ? const MCOperand &MO2 = MI->getOperand(Op+1); > ? const MCOperand &MO3 = MI->getOperand(Op+2); > > + ?if (!MO1.isReg()) { ? // FIXME: This is for CP entries, but isn't right. > + ? ?printOperand(MI, Op, O); > + ? ?return; > + ?} > + > ? O << "[" << getRegisterName(MO1.getReg()); > > ? if (!MO2.getReg()) { > @@ -209,50 +215,6 @@ > ? O << "]"; > ?} > > -void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? raw_ostream &O) { > - ?const MCOperand &MO1 = MI->getOperand(Op); > - ?const MCOperand &MO2 = MI->getOperand(Op+1); > - ?const MCOperand &MO3 = MI->getOperand(Op+2); > - > - ?O << "[" << getRegisterName(MO1.getReg()) << "], "; > - > - ?if (!MO2.getReg()) { > - ? ?unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); > - ? ?O << '#' > - ? ? ?<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) > - ? ? ?<< ImmOffs; > - ? ?return; > - ?} > - > - ?O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) > - ? ?<< getRegisterName(MO2.getReg()); > - > - ?if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) > - ? ?O << ", " > - ? ?<< ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) > - ? ?<< " #" << ShImm; > -} > - > -void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? raw_ostream &O) { > - ?const MCOperand &MO1 = MI->getOperand(Op); > - > - ?if (!MO1.isReg()) { ? // FIXME: This is for CP entries, but isn't right. > - ? ?printOperand(MI, Op, O); > - ? ?return; > - ?} > - > - ?const MCOperand &MO3 = MI->getOperand(Op+2); > - ?unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm()); > - > - ?if (IdxMode == ARMII::IndexModePost) { > - ? ?printAM2PostIndexOp(MI, Op, O); > - ? ?return; > - ?} > - ?printAM2PreOrOffsetIndexOp(MI, Op, O); > -} > - > ?void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned OpNum, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &O) { > > Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original) > +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Thu Mar 31 10:54:36 2011 > @@ -42,11 +42,7 @@ > ? void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > > ? void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > - > ? void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > - ?void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O); > - ?void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &O); > ? void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &O); > ? void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); > > Modified: llvm/trunk/test/MC/ARM/arm_addrmode2.s > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128635&r1=128634&r2=128635&view=diff > ============================================================================== > --- llvm/trunk/test/MC/ARM/arm_addrmode2.s (original) > +++ llvm/trunk/test/MC/ARM/arm_addrmode2.s Thu Mar 31 10:54:36 2011 > @@ -1,38 +0,0 @@ > -@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | FileCheck %s > - > -@ Post-indexed > -@ CHECK: ldrt ?r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6] > -@ CHECK: ldrt ?r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6] > -@ CHECK: ldrt ?r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4] > -@ CHECK: ldrbt ?r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6] > -@ CHECK: ldrbt ?r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6] > -@ CHECK: ldrbt ?r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4] > -@ CHECK: strt ?r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6] > -@ CHECK: strt ?r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6] > -@ CHECK: strt ?r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4] > -@ CHECK: strbt ?r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6] > -@ CHECK: strbt ?r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6] > -@ CHECK: strbt ?r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4] > -@ CHECK: ldr ?r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0x90,0xe6] > -@ CHECK: ldrb ?r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xd0,0xe6] > - ? ? ? ?ldrt ?r1, [r0], r2 > - ? ? ? ?ldrt ?r1, [r0], r2, lsr #3 > - ? ? ? ?ldrt ?r1, [r0], #4 > - ? ? ? ?ldrbt ?r1, [r0], r2 > - ? ? ? ?ldrbt ?r1, [r0], r2, lsr #3 > - ? ? ? ?ldrbt ?r1, [r0], #4 > - ? ? ? ?strt ?r1, [r0], r2 > - ? ? ? ?strt ?r1, [r0], r2, lsr #3 > - ? ? ? ?strt ?r1, [r0], #4 > - ? ? ? ?strbt ?r1, [r0], r2 > - ? ? ? ?strbt ?r1, [r0], r2, lsr #3 > - ? ? ? ?strbt ?r1, [r0], #4 > - ? ? ? ?ldr ?r1, [r0], r2, lsr #3 > - ? ? ? ?ldrb ?r1, [r0], r2, lsr #3 > - > -@ Pre-indexed > -@ CHECK: ldr ?r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7] > -@ CHECK: ldrb ?r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7] > - ? ? ? ?ldr ?r1, [r0, r2, lsr #3]! > - ? ? ? ?ldrb ?r1, [r0, r2, lsr #3]! > - > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From stoklund at 2pi.dk Thu Mar 31 12:23:26 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 31 Mar 2011 17:23:26 -0000 Subject: [llvm-commits] [llvm] r128642 - in /llvm/trunk: lib/CodeGen/MachineVerifier.cpp lib/CodeGen/SimpleRegisterCoalescing.cpp lib/CodeGen/SimpleRegisterCoalescing.h test/CodeGen/X86/2009-04-20-LinearScanOpt.ll Message-ID: <20110331172326.2AB2E2A6C12C@llvm.org> Author: stoklund Date: Thu Mar 31 12:23:25 2011 New Revision: 128642 URL: http://llvm.org/viewvc/llvm-project?rev=128642&view=rev Log: Mark all uses as when joining a copy. This way, shrinkToUses() will ignore the instruction that is about to be deleted, and we avoid leaving invalid live ranges that SplitKit doesn't like. Fix a misunderstanding in MachineVerifier about operands. The flag is valid on def operands where it has the same meaning as on a use operand. It only applies to sub-register defines which also read the full register. Modified: llvm/trunk/lib/CodeGen/MachineVerifier.cpp llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h llvm/trunk/test/CodeGen/X86/2009-04-20-LinearScanOpt.ll Modified: llvm/trunk/lib/CodeGen/MachineVerifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineVerifier.cpp?rev=128642&r1=128641&r2=128642&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineVerifier.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineVerifier.cpp Thu Mar 31 12:23:25 2011 @@ -602,9 +602,7 @@ // Check Live Variables. if (MI->isDebugValue()) { // Liveness checks are not valid for debug values. - } else if (MO->isUndef()) { - // An doesn't refer to any register, so just skip it. - } else if (MO->isUse()) { + } else if (MO->isUse() && !MO->isUndef()) { regsLiveInButUnused.erase(Reg); bool isKill = false; @@ -675,8 +673,7 @@ MInfo.vregsLiveIn.insert(std::make_pair(Reg, MI)); } } - } else { - assert(MO->isDef()); + } else if (MO->isDef()) { // Register defined. // TODO: verify that earlyclobber ops are not used. if (MO->isDead()) Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=128642&r1=128641&r2=128642&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Thu Mar 31 12:23:25 2011 @@ -104,6 +104,18 @@ MachineFunctionPass::getAnalysisUsage(AU); } +void SimpleRegisterCoalescing::markAsJoined(MachineInstr *CopyMI) { + /// Joined copies are not deleted immediately, but kept in JoinedCopies. + JoinedCopies.insert(CopyMI); + + /// Mark all register operands of CopyMI as so they won't affect dead + /// code elimination. + for (MachineInstr::mop_iterator I = CopyMI->operands_begin(), + E = CopyMI->operands_end(); I != E; ++I) + if (I->isReg()) + I->setIsUndef(true); +} + /// AdjustCopiesBackFrom - We found a non-trivially-coalescable copy with IntA /// being the source and IntB being the dest, thus this defines a value number /// in IntB. If the source value number (in IntA) is defined by a copy from B, @@ -471,7 +483,7 @@ DEBUG(dbgs() << "\t\tnoop: " << DefIdx << '\t' << *UseMI); assert(DVNI->def == DefIdx); BValNo = IntB.MergeValueNumberInto(BValNo, DVNI); - JoinedCopies.insert(UseMI); + markAsJoined(UseMI); } // Extend BValNo by merging in IntA live ranges of AValNo. Val# definition @@ -1070,7 +1082,7 @@ if (!CP.isPartial()) { if (AdjustCopiesBackFrom(CP, CopyMI) || RemoveCopyByCommutingDef(CP, CopyMI)) { - JoinedCopies.insert(CopyMI); + markAsJoined(CopyMI); DEBUG(dbgs() << "\tTrivial!\n"); return true; } @@ -1090,7 +1102,7 @@ } // Remember to delete the copy instruction. - JoinedCopies.insert(CopyMI); + markAsJoined(CopyMI); UpdateRegDefsUses(CP); Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h?rev=128642&r1=128641&r2=128642&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h Thu Mar 31 12:23:25 2011 @@ -176,6 +176,9 @@ /// cycles Start and End or NULL if there are no uses. MachineOperand *lastRegisterUse(SlotIndex Start, SlotIndex End, unsigned Reg, SlotIndex &LastUseIdx) const; + + /// markAsJoined - Remember that CopyMI has already been joined. + void markAsJoined(MachineInstr *CopyMI); }; } // End llvm namespace Modified: llvm/trunk/test/CodeGen/X86/2009-04-20-LinearScanOpt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-04-20-LinearScanOpt.ll?rev=128642&r1=128641&r2=128642&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-04-20-LinearScanOpt.ll (original) +++ llvm/trunk/test/CodeGen/X86/2009-04-20-LinearScanOpt.ll Thu Mar 31 12:23:25 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-apple-darwin10.0 -relocation-model=pic -disable-fp-elim -stats |& grep asm-printer | grep 79 +; RUN: llc < %s -mtriple=x86_64-apple-darwin10.0 -relocation-model=pic -disable-fp-elim -stats |& grep asm-printer | grep 77 ; rdar://6802189 ; Test if linearscan is unfavoring registers for allocation to allow more reuse From stoklund at 2pi.dk Thu Mar 31 12:52:42 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 31 Mar 2011 17:52:42 -0000 Subject: [llvm-commits] [llvm] r128643 - /llvm/trunk/lib/CodeGen/MachineVerifier.cpp Message-ID: <20110331175242.0B3242A6C12C@llvm.org> Author: stoklund Date: Thu Mar 31 12:52:41 2011 New Revision: 128643 URL: http://llvm.org/viewvc/llvm-project?rev=128643&view=rev Log: Allow kill flags on two-address instructions. They are harmless. Modified: llvm/trunk/lib/CodeGen/MachineVerifier.cpp Modified: llvm/trunk/lib/CodeGen/MachineVerifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineVerifier.cpp?rev=128643&r1=128642&r2=128643&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineVerifier.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineVerifier.cpp Thu Mar 31 12:52:41 2011 @@ -610,13 +610,9 @@ if (MI->isRegTiedToDefOperand(MONum, &defIdx)) { // A two-addr use counts as a kill if use and def are the same. unsigned DefReg = MI->getOperand(defIdx).getReg(); - if (Reg == DefReg) { + if (Reg == DefReg) isKill = true; - // And in that case an explicit kill flag is not allowed. - if (MO->isKill()) - report("Illegal kill flag on two-address instruction operand", - MO, MONum); - } else if (TargetRegisterInfo::isPhysicalRegister(Reg)) { + else if (TargetRegisterInfo::isPhysicalRegister(Reg)) { report("Two-address instruction operands must be identical", MO, MONum); } From johnny.chen at apple.com Thu Mar 31 12:53:50 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 31 Mar 2011 17:53:50 -0000 Subject: [llvm-commits] [llvm] r128644 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp test/MC/Disassembler/ARM/arm-tests.txt Message-ID: <20110331175350.E399D2A6C12C@llvm.org> Author: johnny Date: Thu Mar 31 12:53:50 2011 New Revision: 128644 URL: http://llvm.org/viewvc/llvm-project?rev=128644&view=rev Log: Add BLXi to the instruction table for disassembly purpose. A8.6.23 BLX (immediate) rdar://problem/9212921 Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128644&r1=128643&r2=128644&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Mar 31 12:53:50 2011 @@ -1528,6 +1528,16 @@ } } +// BLX (immediate) -- for disassembly only +def BLXi : AXI<(outs), (ins br_target:$target), BrMiscFrm, NoItinerary, + "blx\t$target", [/* pattern left blank */]>, + Requires<[IsARM, HasV5T]> { + let Inst{31-25} = 0b1111101; + bits<25> target; + let Inst{23-0} = target{24-1}; + let Inst{24} = target{0}; +} + // Branch and Exchange Jazelle -- for disassembly only def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func", [/* For disassembly only; pattern left blank */]> { Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128644&r1=128643&r2=128644&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Thu Mar 31 12:53:50 2011 @@ -764,7 +764,7 @@ || Opcode == ARM::SMC || Opcode == ARM::SVC) && "Unexpected Opcode"); - assert(NumOps >= 1 && OpInfo[0].RegClass < 0 && "Reg operand expected"); + assert(NumOps >= 1 && OpInfo[0].RegClass < 0 && "Imm operand expected"); int Imm32 = 0; if (Opcode == ARM::SMC) { @@ -787,7 +787,7 @@ } // Misc. Branch Instructions. -// BLX, BX +// BLX, BLXi, BX // BX, BX_RET static bool DisassembleBrMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) { @@ -814,6 +814,17 @@ return true; } + // BLXi takes imm32 (the PC offset). + if (Opcode == ARM::BLXi) { + assert(NumOps >= 1 && OpInfo[0].RegClass < 0 && "Imm operand expected"); + // SignExtend(imm24:H:'0', 32) where imm24 = Inst{23-0} and H = Inst{24}. + unsigned Imm26 = slice(insn, 23, 0) << 2 | slice(insn, 24, 24) << 1; + int Imm32 = SignExtend32<26>(Imm26); + MI.addOperand(MCOperand::CreateImm(Imm32)); + OpIdx = 1; + return true; + } + return false; } Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=128644&r1=128643&r2=128644&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Thu Mar 31 12:53:50 2011 @@ -211,3 +211,6 @@ # CHECK: stc2 p2, cr4, [r9], {157} 0x9d 0x42 0x89 0xfc + +# CHECK: blx #60 +0x0f 0x00 0x00 0xfa From stoklund at 2pi.dk Thu Mar 31 12:55:25 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 31 Mar 2011 17:55:25 -0000 Subject: [llvm-commits] [llvm] r128645 - in /llvm/trunk: lib/CodeGen/VirtRegMap.cpp test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll Message-ID: <20110331175525.E81CC2A6C12C@llvm.org> Author: stoklund Date: Thu Mar 31 12:55:25 2011 New Revision: 128645 URL: http://llvm.org/viewvc/llvm-project?rev=128645&view=rev Log: Don't completely eliminate identity copies that also modify super register liveness. Turn them into noop KILL instructions instead. This lets the scavenger know when super-registers are killed and defined. Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp llvm/trunk/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=128645&r1=128644&r2=128645&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Thu Mar 31 12:55:25 2011 @@ -309,12 +309,18 @@ // Finally, remove any identity copies. if (MI->isIdentityCopy()) { - DEBUG(dbgs() << "Deleting identity copy.\n"); - RemoveMachineInstrFromMaps(MI); - if (Indexes) - Indexes->removeMachineInstrFromMaps(MI); - // It's safe to erase MI because MII has already been incremented. - MI->eraseFromParent(); + if (MI->getNumOperands() == 2) { + DEBUG(dbgs() << "Deleting identity copy.\n"); + RemoveMachineInstrFromMaps(MI); + if (Indexes) + Indexes->removeMachineInstrFromMaps(MI); + // It's safe to erase MI because MII has already been incremented. + MI->eraseFromParent(); + } else { + // Transform identity copy to a KILL to deal with subregisters. + MI->setDesc(TII->get(TargetOpcode::KILL)); + DEBUG(dbgs() << "Identity copy: " << *MI); + } } } } Modified: llvm/trunk/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll?rev=128645&r1=128644&r2=128645&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll (original) +++ llvm/trunk/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll Thu Mar 31 12:55:25 2011 @@ -1,4 +1,5 @@ ; RUN: llc < %s -march=bfin -join-liveintervals=0 -verify-machineinstrs +; RUN: llc < %s -march=bfin -join-liveintervals=0 -verify-machineinstrs -regalloc=greedy ; Provoke an error in LowerSubregsPass::LowerExtract where the live range of a ; super-register is illegally extended. From nicholas at mxc.ca Thu Mar 31 13:20:20 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 31 Mar 2011 18:20:20 -0000 Subject: [llvm-commits] [llvm] r128647 - /llvm/trunk/docs/LangRef.html Message-ID: <20110331182020.4BE422A6C12C@llvm.org> Author: nicholas Date: Thu Mar 31 13:20:19 2011 New Revision: 128647 URL: http://llvm.org/viewvc/llvm-project?rev=128647&view=rev Log: Pick better examples. "fpext float 3.1415 to double" won't parse because 3.1415 isn't an exact float. Also "fpext float 1.0 to float" is invalid IR because it's not performing an extension. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=128647&r1=128646&r2=128647&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Thu Mar 31 13:20:19 2011 @@ -4751,8 +4751,8 @@
        Example:
        -  %X = fpext float 3.1415 to double        ; yields double:3.1415
        -  %Y = fpext float 1.0 to float            ; yields float:1.0 (no-op)
        +  %X = fpext float 3.125 to double         ; yields double:3.125000e+00
        +  %Y = fpext double %X to fp128            ; yields fp128:0xL00000000000000004000900000000000
         
        From aggarwa4 at illinois.edu Thu Mar 31 13:21:54 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 31 Mar 2011 18:21:54 -0000 Subject: [llvm-commits] [poolalloc] r128648 - /poolalloc/trunk/lib/AssistDS/ArgCast.cpp Message-ID: <20110331182154.E56AA2A6C12C@llvm.org> Author: aggarwa4 Date: Thu Mar 31 13:21:54 2011 New Revision: 128648 URL: http://llvm.org/viewvc/llvm-project?rev=128648&view=rev Log: convert calls, that cast the function pointer to satisfy the argument types, to call the function, by casting the arguments. Added: poolalloc/trunk/lib/AssistDS/ArgCast.cpp Added: poolalloc/trunk/lib/AssistDS/ArgCast.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/ArgCast.cpp?rev=128648&view=auto ============================================================================== --- poolalloc/trunk/lib/AssistDS/ArgCast.cpp (added) +++ poolalloc/trunk/lib/AssistDS/ArgCast.cpp Thu Mar 31 13:21:54 2011 @@ -0,0 +1,109 @@ +//===-- ArgSimplify.cpp - Special case for conditional ptr args ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#define DEBUG_TYPE "argcast" + +#include "llvm/Instructions.h" +#include "llvm/Module.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/Debug.h" + +#include +#include +#include + +using namespace llvm; + +STATISTIC(numChanged, "Number of Args bitcasted"); + +namespace { + + class ArgCast : public ModulePass { + public: + static char ID; + ArgCast() : ModulePass(&ID) {} + + bool runOnModule(Module& M) { + + std::vector worklist; + for (Module::iterator I = M.begin(); I != M.end(); ++I) + if (!I->isDeclaration() && !I->mayBeOverridden()) { + if(I->getNameStr() == "main") + continue; + for(Value::use_iterator ui = I->use_begin(), ue = I->use_end(); ui != ue; ++ui) + if (Constant *C = dyn_cast(ui)) + if (ConstantExpr *CE = dyn_cast(C)) + if (CE->getOpcode() == Instruction::BitCast) + if(CE->getOperand(0) == I) + if(const FunctionType *FTy = dyn_cast + ((cast(CE->getType()))->getElementType())) { + //casting to a varargs funtion + if(FTy->isVarArg()){ + for(Value::use_iterator uii = CE->use_begin(), + uee = CE->use_end(); uii != uee; ++uii) + if (CallInst* CI = dyn_cast(uii)) { + if(CI->getNumOperands() != I->arg_size() + 1) + continue; + if(CI->getCalledValue() == CE) + worklist.push_back(CI); + } + } + } + } + while(!worklist.empty()) { + CallInst *CI = worklist.back(); + worklist.pop_back(); + Function *F = cast(CI->getCalledValue()->stripPointerCasts()); + const FunctionType *FTy = F->getFunctionType(); + if(F->getReturnType() != CI->getType()) { + continue; + } + + SmallVector Args; + unsigned i =0; + for(i =0; i< FTy->getNumParams(); ++i) { + const Type *ArgType = CI->getOperand(i+1)->getType(); + const Type *FormalType = FTy->getParamType(i); + if(ArgType == FormalType) + Args.push_back(CI->getOperand(i+1)); + + else if(ArgType->isPointerTy() && FormalType->isPointerTy()){ + BitCastInst *BI = new BitCastInst(CI->getOperand(i+1), FormalType, "", CI); + Args.push_back(BI); + } else if (ArgType->isIntegerTy() && FormalType->isIntegerTy()) { + CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1), FormalType, true, "", CI); + Args.push_back(CastI); + } else { + ArgType->dump(); + FormalType->dump(); + break; + } + + } + if(i != FTy->getNumParams()) + continue; + + + CallInst *CINew = CallInst::Create(F, Args.begin(), Args.end(), "", CI); + CINew->setCallingConv(CI->getCallingConv()); + CINew->setAttributes(CI->getAttributes()); + CI->replaceAllUsesWith(CINew); + CI->eraseFromParent(); + numChanged++; + } + return true; + } + }; +} + +char ArgCast::ID = 0; +static RegisterPass +X("arg-cast", "Cast Arguments"); From aggarwa4 at illinois.edu Thu Mar 31 13:23:12 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 31 Mar 2011 18:23:12 -0000 Subject: [llvm-commits] [poolalloc] r128649 - /poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Message-ID: <20110331182312.321732A6C12C@llvm.org> Author: aggarwa4 Date: Thu Mar 31 13:23:12 2011 New Revision: 128649 URL: http://llvm.org/viewvc/llvm-project?rev=128649&view=rev Log: Move to DSA. Removed: poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Removed: poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp?rev=128648&view=auto ============================================================================== --- poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp (original) +++ poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp (removed) @@ -1,201 +0,0 @@ -//===-- AllocatorIdentification.cpp - Identify wrappers to allocators -----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// A pass to identify functions that act as wrappers to malloc and other -// allocators. -//===----------------------------------------------------------------------===// -#define DEBUG_TYPE "allocator-identify" - -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/Pass.h" -#include "llvm/Analysis/LoopInfo.h" -#include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/Debug.h" - -#include -#include -#include -#include - -using namespace llvm; - -STATISTIC(numAllocators, "Number of malloc-like allocators"); -STATISTIC(numDeallocators, "Number of free-like deallocators"); - -namespace { - class AllocIdentify : public ModulePass { - - bool flowsFrom(Value *Dest,Value *Src) { - if(Dest == Src) - return true; - if(ReturnInst *Ret = dyn_cast(Dest)) { - return flowsFrom(Ret->getReturnValue(), Src); - } - if(PHINode *PN = dyn_cast(Dest)) { - Function *F = PN->getParent()->getParent(); - LoopInfo &LI = getAnalysis(*F); - // If this is a loop phi, ignore. - if(LI.isLoopHeader(PN->getParent())) - return false; - bool ret = true; - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { - ret = ret && flowsFrom(PN->getIncomingValue(i), Src); - } - return ret; - } - if(BitCastInst *BI = dyn_cast(Dest)) { - return flowsFrom(BI->getOperand(0), Src); - } - if(isa(Dest)) - return true; - return false; - } - - bool isNotStored(Value *V) { - // check that V is not stroed to a location taht is accessible outside this fn - for(Value::use_iterator ui = V->use_begin(), ue = V->use_end(); - ui != ue; ++ui) { - if(isa(ui)) - return false; - if(isa(ui)) - continue; - if(isa(ui)) - continue; - if(BitCastInst *BI = dyn_cast(ui)) { - if(isNotStored(BI)) - continue; - else - return false; - } - if(PHINode *PN = dyn_cast(ui)) { - if(isNotStored(PN)) - continue; - else - return false; - } - - return false; - } - return true; - } - - protected: - std::set allocators; - std::set deallocators; - public: - static char ID; - AllocIdentify() : ModulePass(&ID) {} - bool runOnModule(Module& M) { - - allocators.insert("malloc"); - allocators.insert("calloc"); - allocators.insert("realloc"); - allocators.insert("memset"); - deallocators.insert("free"); - deallocators.insert("cfree"); - - bool changed; - do { - changed = false; - std::set TempAllocators; - TempAllocators.insert( allocators.begin(), allocators.end()); - std::set::iterator it; - for(it = TempAllocators.begin(); it != TempAllocators.end(); ++it) { - Function* F = M.getFunction(*it); - if(!F) - continue; - for(Value::use_iterator ui = F->use_begin(), ue = F->use_end(); - ui != ue; ++ui) { - // iterate though all calls to malloc - if (CallInst* CI = dyn_cast(ui)) { - // The function that calls malloc could be a potential allocator - Function *WrapperF = CI->getParent()->getParent(); - if(WrapperF->doesNotReturn()) - continue; - if(!(WrapperF->getReturnType()->isPointerTy())) - continue; - bool isWrapper = true; - for (Function::iterator BBI = WrapperF->begin(), E = WrapperF->end(); BBI != E; ) { - BasicBlock &BB = *BBI++; - - // Only look at return blocks. - ReturnInst *Ret = dyn_cast(BB.getTerminator()); - if (Ret == 0) continue; - - //check for ALL return values - if(flowsFrom(Ret, CI)) { - continue; - } else { - isWrapper = false; - break; - } - // if true for all return add to list of allocators - } - if(isWrapper) - isWrapper = isWrapper && isNotStored(CI); - if(isWrapper) { - changed = (allocators.find(WrapperF->getName()) == allocators.end()); - if(changed) { - ++numAllocators; - allocators.insert(WrapperF->getName()); - DEBUG(errs() << WrapperF->getNameStr() << "\n"); - } - } - } - } - } - } while(changed); - - do { - changed = false; - std::set TempDeallocators; - TempDeallocators.insert( deallocators.begin(), deallocators.end()); - std::set::iterator it; - for(it = TempDeallocators.begin(); it != TempDeallocators.end(); ++it) { - Function* F = M.getFunction(*it); - - if(!F) - continue; - for(Value::use_iterator ui = F->use_begin(), ue = F->use_end(); - ui != ue; ++ui) { - // iterate though all calls to malloc - if (CallInst* CI = dyn_cast(ui)) { - // The function that calls malloc could be a potential allocator - Function *WrapperF = CI->getParent()->getParent(); - - if(WrapperF->arg_size() != 1) - continue; - if(!WrapperF->arg_begin()->getType()->isPointerTy()) - continue; - Argument *arg = dyn_cast(WrapperF->arg_begin()); - if(flowsFrom(CI->getOperand(1), arg)) { - changed = (deallocators.find(WrapperF->getName()) == deallocators.end()); - if(changed) { - ++numDeallocators; - deallocators.insert(WrapperF->getName()); - DEBUG(errs() << WrapperF->getNameStr() << "\n"); - } - } - } - } - } - } while(changed); - return false; - } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredTransitive(); - } - }; -} - -char AllocIdentify::ID = 0; -static RegisterPass -X("alloc-identify", "Identify allocator wrapper functions"); From ahatanak at gmail.com Thu Mar 31 13:26:17 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Thu, 31 Mar 2011 18:26:17 -0000 Subject: [llvm-commits] [llvm] r128650 - in /llvm/trunk: lib/Target/Mips/MipsISelLowering.cpp lib/Target/Mips/MipsISelLowering.h lib/Target/Mips/MipsInstrFPU.td lib/Target/Mips/MipsInstrFormats.td lib/Target/Mips/MipsInstrInfo.cpp lib/Target/Mips/MipsInstrInfo.h lib/Target/Mips/MipsInstrInfo.td test/CodeGen/Mips/2008-07-23-fpcmp.ll test/CodeGen/Mips/2008-07-29-icmp.ll test/CodeGen/Mips/2010-07-20-Select.ll test/CodeGen/Mips/fpbr.ll test/CodeGen/Mips/fpcmp.ll test/CodeGen/Mips/select.ll Message-ID: <20110331182617.9BF4D2A6C12C@llvm.org> Author: ahatanak Date: Thu Mar 31 13:26:17 2011 New Revision: 128650 URL: http://llvm.org/viewvc/llvm-project?rev=128650&view=rev Log: Added support for FP conditional move instructions and fixed bugs in handling of FP comparisons. Added: llvm/trunk/test/CodeGen/Mips/fpbr.ll llvm/trunk/test/CodeGen/Mips/fpcmp.ll llvm/trunk/test/CodeGen/Mips/select.ll Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.h llvm/trunk/lib/Target/Mips/MipsInstrFPU.td llvm/trunk/lib/Target/Mips/MipsInstrFormats.td llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp llvm/trunk/lib/Target/Mips/MipsInstrInfo.h llvm/trunk/lib/Target/Mips/MipsInstrInfo.td llvm/trunk/test/CodeGen/Mips/2008-07-23-fpcmp.ll llvm/trunk/test/CodeGen/Mips/2008-07-29-icmp.ll llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=128650&r1=128649&r2=128650&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Thu Mar 31 13:26:17 2011 @@ -41,10 +41,10 @@ case MipsISD::Lo : return "MipsISD::Lo"; case MipsISD::GPRel : return "MipsISD::GPRel"; case MipsISD::Ret : return "MipsISD::Ret"; - case MipsISD::SelectCC : return "MipsISD::SelectCC"; - case MipsISD::FPSelectCC : return "MipsISD::FPSelectCC"; case MipsISD::FPBrcond : return "MipsISD::FPBrcond"; case MipsISD::FPCmp : return "MipsISD::FPCmp"; + case MipsISD::CMovFP_T : return "MipsISD::CMovFP_T"; + case MipsISD::CMovFP_F : return "MipsISD::CMovFP_F"; case MipsISD::FPRound : return "MipsISD::FPRound"; case MipsISD::MAdd : return "MipsISD::MAdd"; case MipsISD::MAddu : return "MipsISD::MAddu"; @@ -98,20 +98,11 @@ setOperationAction(ISD::SELECT, MVT::f32, Custom); setOperationAction(ISD::SELECT, MVT::f64, Custom); setOperationAction(ISD::SELECT, MVT::i32, Custom); - setOperationAction(ISD::SETCC, MVT::f32, Custom); - setOperationAction(ISD::SETCC, MVT::f64, Custom); setOperationAction(ISD::BRCOND, MVT::Other, Custom); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom); setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); setOperationAction(ISD::VASTART, MVT::Other, Custom); - - // We custom lower AND/OR to handle the case where the DAG contain 'ands/ors' - // with operands comming from setcc fp comparions. This is necessary since - // the result from these setcc are in a flag registers (FCR31). - setOperationAction(ISD::AND, MVT::i32, Custom); - setOperationAction(ISD::OR, MVT::i32, Custom); - setOperationAction(ISD::SDIV, MVT::i32, Expand); setOperationAction(ISD::SREM, MVT::i32, Expand); setOperationAction(ISD::UDIV, MVT::i32, Expand); @@ -176,6 +167,7 @@ setTargetDAGCombine(ISD::SUBE); setTargetDAGCombine(ISD::SDIVREM); setTargetDAGCombine(ISD::UDIVREM); + setTargetDAGCombine(ISD::SETCC); setStackPointerRegisterToSaveRestore(Mips::SP); computeRegisterProperties(); @@ -396,6 +388,96 @@ return SDValue(); } +static Mips::CondCode FPCondCCodeToFCC(ISD::CondCode CC) { + switch (CC) { + default: llvm_unreachable("Unknown fp condition code!"); + case ISD::SETEQ: + case ISD::SETOEQ: return Mips::FCOND_OEQ; + case ISD::SETUNE: return Mips::FCOND_UNE; + case ISD::SETLT: + case ISD::SETOLT: return Mips::FCOND_OLT; + case ISD::SETGT: + case ISD::SETOGT: return Mips::FCOND_OGT; + case ISD::SETLE: + case ISD::SETOLE: return Mips::FCOND_OLE; + case ISD::SETGE: + case ISD::SETOGE: return Mips::FCOND_OGE; + case ISD::SETULT: return Mips::FCOND_ULT; + case ISD::SETULE: return Mips::FCOND_ULE; + case ISD::SETUGT: return Mips::FCOND_UGT; + case ISD::SETUGE: return Mips::FCOND_UGE; + case ISD::SETUO: return Mips::FCOND_UN; + case ISD::SETO: return Mips::FCOND_OR; + case ISD::SETNE: + case ISD::SETONE: return Mips::FCOND_ONE; + case ISD::SETUEQ: return Mips::FCOND_UEQ; + } +} + + +// Returns true if condition code has to be inverted. +static bool InvertFPCondCode(Mips::CondCode CC) { + if (CC >= Mips::FCOND_F && CC <= Mips::FCOND_NGT) + return false; + + if (CC >= Mips::FCOND_T && CC <= Mips::FCOND_GT) + return true; + + assert(false && "Illegal Condition Code"); + return false; +} + +// Creates and returns an FPCmp node from a setcc node. +// Returns Op if setcc is not a floating point comparison. +static SDValue CreateFPCmp(SelectionDAG& DAG, const SDValue& Op) { + // must be a SETCC node + if (Op.getOpcode() != ISD::SETCC) + return Op; + + SDValue LHS = Op.getOperand(0); + + if (!LHS.getValueType().isFloatingPoint()) + return Op; + + SDValue RHS = Op.getOperand(1); + DebugLoc dl = Op.getDebugLoc(); + + // Assume the 3rd operand is a CondCodeSDNode. Add code to check the type of node + // if necessary. + ISD::CondCode CC = cast(Op.getOperand(2))->get(); + + return DAG.getNode(MipsISD::FPCmp, dl, MVT::Glue, LHS, RHS, + DAG.getConstant(FPCondCCodeToFCC(CC), MVT::i32)); +} + +// Creates and returns a CMovFPT/F node. +static SDValue CreateCMovFP(SelectionDAG& DAG, SDValue Cond, SDValue True, + SDValue False, DebugLoc DL) { + bool invert = InvertFPCondCode((Mips::CondCode) + cast(Cond.getOperand(2)) + ->getSExtValue()); + + return DAG.getNode((invert ? MipsISD::CMovFP_F : MipsISD::CMovFP_T), DL, + True.getValueType(), True, False, Cond); +} + +static SDValue PerformSETCCCombine(SDNode *N, SelectionDAG& DAG, + TargetLowering::DAGCombinerInfo &DCI, + const MipsSubtarget* Subtarget) { + if (DCI.isBeforeLegalizeOps()) + return SDValue(); + + SDValue Cond = CreateFPCmp(DAG, SDValue(N, 0)); + + if (Cond.getOpcode() != MipsISD::FPCmp) + return SDValue(); + + SDValue True = DAG.getConstant(1, MVT::i32); + SDValue False = DAG.getConstant(0, MVT::i32); + + return CreateCMovFP(DAG, Cond, True, False, N->getDebugLoc()); +} + SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; @@ -410,6 +492,8 @@ case ISD::SDIVREM: case ISD::UDIVREM: return PerformDivRemCombine(N, DAG, DCI, Subtarget); + case ISD::SETCC: + return PerformSETCCCombine(N, DAG, DCI, Subtarget); } return SDValue(); @@ -420,7 +504,6 @@ { switch (Op.getOpcode()) { - case ISD::AND: return LowerANDOR(Op, DAG); case ISD::BRCOND: return LowerBRCOND(Op, DAG); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); @@ -429,9 +512,7 @@ case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); - case ISD::OR: return LowerANDOR(Op, DAG); case ISD::SELECT: return LowerSELECT(Op, DAG); - case ISD::SETCC: return LowerSETCC(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG); } return SDValue(); @@ -464,122 +545,110 @@ return Mips::BRANCH_INVALID; } -static unsigned FPBranchCodeToOpc(Mips::FPBranchCode BC) { - switch(BC) { - default: - llvm_unreachable("Unknown branch code"); - case Mips::BRANCH_T : return Mips::BC1T; - case Mips::BRANCH_F : return Mips::BC1F; - case Mips::BRANCH_TL : return Mips::BC1TL; - case Mips::BRANCH_FL : return Mips::BC1FL; - } -} - -static Mips::CondCode FPCondCCodeToFCC(ISD::CondCode CC) { - switch (CC) { - default: llvm_unreachable("Unknown fp condition code!"); - case ISD::SETEQ: - case ISD::SETOEQ: return Mips::FCOND_EQ; - case ISD::SETUNE: return Mips::FCOND_OGL; - case ISD::SETLT: - case ISD::SETOLT: return Mips::FCOND_OLT; - case ISD::SETGT: - case ISD::SETOGT: return Mips::FCOND_OGT; - case ISD::SETLE: - case ISD::SETOLE: return Mips::FCOND_OLE; - case ISD::SETGE: - case ISD::SETOGE: return Mips::FCOND_OGE; - case ISD::SETULT: return Mips::FCOND_ULT; - case ISD::SETULE: return Mips::FCOND_ULE; - case ISD::SETUGT: return Mips::FCOND_UGT; - case ISD::SETUGE: return Mips::FCOND_UGE; - case ISD::SETUO: return Mips::FCOND_UN; - case ISD::SETO: return Mips::FCOND_OR; - case ISD::SETNE: - case ISD::SETONE: return Mips::FCOND_NEQ; - case ISD::SETUEQ: return Mips::FCOND_UEQ; - } -} - MachineBasicBlock * MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { + // There is no need to expand CMov instructions if target has + // conditional moves. + if (Subtarget->hasCondMov()) + return BB; + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); bool isFPCmp = false; DebugLoc dl = MI->getDebugLoc(); + unsigned Opc; switch (MI->getOpcode()) { default: assert(false && "Unexpected instr type to insert"); - case Mips::Select_FCC: - case Mips::Select_FCC_S32: - case Mips::Select_FCC_D32: - isFPCmp = true; // FALL THROUGH - case Mips::Select_CC: - case Mips::Select_CC_S32: - case Mips::Select_CC_D32: { - // To "insert" a SELECT_CC instruction, we actually have to insert the - // diamond control-flow pattern. The incoming instruction knows the - // destination vreg to set, the condition code register to branch on, the - // true/false values to select between, and a branch opcode to use. - const BasicBlock *LLVM_BB = BB->getBasicBlock(); - MachineFunction::iterator It = BB; - ++It; - - // thisMBB: - // ... - // TrueVal = ... - // setcc r1, r2, r3 - // bNE r1, r0, copy1MBB - // fallthrough --> copy0MBB - MachineBasicBlock *thisMBB = BB; - MachineFunction *F = BB->getParent(); - MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); - MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); - F->insert(It, copy0MBB); - F->insert(It, sinkMBB); - - // Transfer the remainder of BB and its successor edges to sinkMBB. - sinkMBB->splice(sinkMBB->begin(), BB, - llvm::next(MachineBasicBlock::iterator(MI)), - BB->end()); - sinkMBB->transferSuccessorsAndUpdatePHIs(BB); - - // Next, add the true and fallthrough blocks as its successors. - BB->addSuccessor(copy0MBB); - BB->addSuccessor(sinkMBB); - - // Emit the right instruction according to the type of the operands compared - if (isFPCmp) { - // Find the condiction code present in the setcc operation. - Mips::CondCode CC = (Mips::CondCode)MI->getOperand(4).getImm(); - // Get the branch opcode from the branch code. - unsigned Opc = FPBranchCodeToOpc(GetFPBranchCodeFromCond(CC)); - BuildMI(BB, dl, TII->get(Opc)).addMBB(sinkMBB); - } else - BuildMI(BB, dl, TII->get(Mips::BNE)).addReg(MI->getOperand(1).getReg()) - .addReg(Mips::ZERO).addMBB(sinkMBB); - - // copy0MBB: - // %FalseValue = ... - // # fallthrough to sinkMBB - BB = copy0MBB; - - // Update machine-CFG edges - BB->addSuccessor(sinkMBB); - - // sinkMBB: - // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ] - // ... - BB = sinkMBB; + case Mips::MOVT: + case Mips::MOVT_S: + case Mips::MOVT_D: + isFPCmp = true; + Opc = Mips::BC1F; + break; + case Mips::MOVF: + case Mips::MOVF_S: + case Mips::MOVF_D: + isFPCmp = true; + Opc = Mips::BC1T; + break; + case Mips::MOVZ_I: + case Mips::MOVZ_S: + case Mips::MOVZ_D: + Opc = Mips::BNE; + break; + case Mips::MOVN_I: + case Mips::MOVN_S: + case Mips::MOVN_D: + Opc = Mips::BEQ; + break; + } + + // To "insert" a SELECT_CC instruction, we actually have to insert the + // diamond control-flow pattern. The incoming instruction knows the + // destination vreg to set, the condition code register to branch on, the + // true/false values to select between, and a branch opcode to use. + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineFunction::iterator It = BB; + ++It; + + // thisMBB: + // ... + // TrueVal = ... + // setcc r1, r2, r3 + // bNE r1, r0, copy1MBB + // fallthrough --> copy0MBB + MachineBasicBlock *thisMBB = BB; + MachineFunction *F = BB->getParent(); + MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); + F->insert(It, copy0MBB); + F->insert(It, sinkMBB); + + // Transfer the remainder of BB and its successor edges to sinkMBB. + sinkMBB->splice(sinkMBB->begin(), BB, + llvm::next(MachineBasicBlock::iterator(MI)), + BB->end()); + sinkMBB->transferSuccessorsAndUpdatePHIs(BB); + + // Next, add the true and fallthrough blocks as its successors. + BB->addSuccessor(copy0MBB); + BB->addSuccessor(sinkMBB); + + // Emit the right instruction according to the type of the operands compared + if (isFPCmp) + BuildMI(BB, dl, TII->get(Opc)).addMBB(sinkMBB); + else + BuildMI(BB, dl, TII->get(Opc)).addReg(MI->getOperand(2).getReg()) + .addReg(Mips::ZERO).addMBB(sinkMBB); + + + // copy0MBB: + // %FalseValue = ... + // # fallthrough to sinkMBB + BB = copy0MBB; + + // Update machine-CFG edges + BB->addSuccessor(sinkMBB); + + // sinkMBB: + // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ] + // ... + BB = sinkMBB; + + if (isFPCmp) BuildMI(*BB, BB->begin(), dl, TII->get(Mips::PHI), MI->getOperand(0).getReg()) .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB) - .addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB); + .addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB); + else + BuildMI(*BB, BB->begin(), dl, + TII->get(Mips::PHI), MI->getOperand(0).getReg()) + .addReg(MI->getOperand(3).getReg()).addMBB(thisMBB) + .addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB); - MI->eraseFromParent(); // The pseudo instruction is gone now. - return BB; - } - } + MI->eraseFromParent(); // The pseudo instruction is gone now. + return BB; } //===----------------------------------------------------------------------===// @@ -644,27 +713,6 @@ } SDValue MipsTargetLowering:: -LowerANDOR(SDValue Op, SelectionDAG &DAG) const -{ - SDValue LHS = Op.getOperand(0); - SDValue RHS = Op.getOperand(1); - DebugLoc dl = Op.getDebugLoc(); - - if (LHS.getOpcode() != MipsISD::FPCmp || RHS.getOpcode() != MipsISD::FPCmp) - return Op; - - SDValue True = DAG.getConstant(1, MVT::i32); - SDValue False = DAG.getConstant(0, MVT::i32); - - SDValue LSEL = DAG.getNode(MipsISD::FPSelectCC, dl, True.getValueType(), - LHS, True, False, LHS.getOperand(2)); - SDValue RSEL = DAG.getNode(MipsISD::FPSelectCC, dl, True.getValueType(), - RHS, True, False, RHS.getOperand(2)); - - return DAG.getNode(Op.getOpcode(), dl, MVT::i32, LSEL, RSEL); -} - -SDValue MipsTargetLowering:: LowerBRCOND(SDValue Op, SelectionDAG &DAG) const { // The first operand is the chain, the second is the condition, the third is @@ -673,58 +721,32 @@ SDValue Dest = Op.getOperand(2); DebugLoc dl = Op.getDebugLoc(); - if (Op.getOperand(1).getOpcode() != MipsISD::FPCmp) + SDValue CondRes = CreateFPCmp(DAG, Op.getOperand(1)); + + // Return if flag is not set by a floating point comparision. + if (CondRes.getOpcode() != MipsISD::FPCmp) return Op; - SDValue CondRes = Op.getOperand(1); SDValue CCNode = CondRes.getOperand(2); Mips::CondCode CC = (Mips::CondCode)cast(CCNode)->getZExtValue(); SDValue BrCode = DAG.getConstant(GetFPBranchCodeFromCond(CC), MVT::i32); return DAG.getNode(MipsISD::FPBrcond, dl, Op.getValueType(), Chain, BrCode, - Dest, CondRes); -} - -SDValue MipsTargetLowering:: -LowerSETCC(SDValue Op, SelectionDAG &DAG) const -{ - // The operands to this are the left and right operands to compare (ops #0, - // and #1) and the condition code to compare them with (op #2) as a - // CondCodeSDNode. - SDValue LHS = Op.getOperand(0); - SDValue RHS = Op.getOperand(1); - DebugLoc dl = Op.getDebugLoc(); - - ISD::CondCode CC = cast(Op.getOperand(2))->get(); - - return DAG.getNode(MipsISD::FPCmp, dl, Op.getValueType(), LHS, RHS, - DAG.getConstant(FPCondCCodeToFCC(CC), MVT::i32)); + Dest, CondRes); } SDValue MipsTargetLowering:: LowerSELECT(SDValue Op, SelectionDAG &DAG) const { - SDValue Cond = Op.getOperand(0); - SDValue True = Op.getOperand(1); - SDValue False = Op.getOperand(2); - DebugLoc dl = Op.getDebugLoc(); + SDValue Cond = CreateFPCmp(DAG, Op.getOperand(0)); - // if the incomming condition comes from a integer compare, the select - // operation must be SelectCC or a conditional move if the subtarget - // supports it. - if (Cond.getOpcode() != MipsISD::FPCmp) { - if (Subtarget->hasCondMov() && !True.getValueType().isFloatingPoint()) - return Op; - return DAG.getNode(MipsISD::SelectCC, dl, True.getValueType(), - Cond, True, False); - } + // Return if flag is not set by a floating point comparision. + if (Cond.getOpcode() != MipsISD::FPCmp) + return Op; - // if the incomming condition comes from fpcmp, the select - // operation must use FPSelectCC. - SDValue CCNode = Cond.getOperand(2); - return DAG.getNode(MipsISD::FPSelectCC, dl, True.getValueType(), - Cond, True, False, CCNode); + return CreateCMovFP(DAG, Cond, Op.getOperand(1), Op.getOperand(2), + Op.getDebugLoc()); } SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=128650&r1=128649&r2=128650&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Thu Mar 31 13:26:17 2011 @@ -40,18 +40,16 @@ // Handle gp_rel (small data/bss sections) relocation. GPRel, - // Select CC Pseudo Instruction - SelectCC, - - // Floating Point Select CC Pseudo Instruction - FPSelectCC, - // Floating Point Branch Conditional FPBrcond, // Floating Point Compare FPCmp, + // Floating Point Conditional Moves + CMovFP_T, + CMovFP_F, + // Floating Point Rounding FPRound, @@ -105,7 +103,6 @@ SmallVectorImpl &InVals) const; // Lower Operand specifics - SDValue LowerANDOR(SDValue Op, SelectionDAG &DAG) const; SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const; SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; @@ -115,7 +112,6 @@ SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; virtual SDValue Modified: llvm/trunk/lib/Target/Mips/MipsInstrFPU.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFPU.td?rev=128650&r1=128649&r2=128650&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrFPU.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrFPU.td Thu Mar 31 13:26:17 2011 @@ -24,19 +24,19 @@ //===----------------------------------------------------------------------===// // Floating Point Compare and Branch -def SDT_MipsFPBrcond : SDTypeProfile<0, 3, [SDTCisSameAs<0, 2>, SDTCisInt<0>, - SDTCisVT<1, OtherVT>]>; -def SDT_MipsFPCmp : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, - SDTCisSameAs<1, 2>, SDTCisFP<1>, - SDTCisInt<3>]>; -def SDT_MipsFPSelectCC : SDTypeProfile<1, 4, [SDTCisInt<1>, SDTCisInt<4>, - SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>]>; - +def SDT_MipsFPBrcond : SDTypeProfile<0, 2, [SDTCisInt<0>, + SDTCisVT<1, OtherVT>]>; +def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<1>, + SDTCisInt<2>]>; +def SDT_MipsCMovFP : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, + SDTCisSameAs<1, 2>]>; + +def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp, [SDNPOutGlue]>; +def MipsCMovFP_T : SDNode<"MipsISD::CMovFP_T", SDT_MipsCMovFP, [SDNPInGlue]>; +def MipsCMovFP_F : SDNode<"MipsISD::CMovFP_F", SDT_MipsCMovFP, [SDNPInGlue]>; def MipsFPRound : SDNode<"MipsISD::FPRound", SDTFPRoundOp, [SDNPOptInGlue]>; def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond, - [SDNPHasChain]>; -def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp>; -def MipsFPSelectCC : SDNode<"MipsISD::FPSelectCC", SDT_MipsFPSelectCC>; + [SDNPHasChain, SDNPOptInGlue]>; // Operand for printing out a condition code. let PrintMethod = "printFCCOperand" in @@ -210,11 +210,11 @@ def MIPS_BRANCH_TL : PatLeaf<(i32 3)>; /// Floating Point Branch of False/True (Likely) -let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in { +let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in class FBRANCH : FFI<0x11, (outs), (ins brtarget:$dst), !strconcat(asmstr, " $dst"), - [(MipsFPBrcond op, bb:$dst, FCR31)]>; -} + [(MipsFPBrcond op, bb:$dst)]>; + def BC1F : FBRANCH; def BC1T : FBRANCH; def BC1FL : FBRANCH; @@ -227,7 +227,7 @@ // They must be kept in synch. def MIPS_FCOND_F : PatLeaf<(i32 0)>; def MIPS_FCOND_UN : PatLeaf<(i32 1)>; -def MIPS_FCOND_EQ : PatLeaf<(i32 2)>; +def MIPS_FCOND_OEQ : PatLeaf<(i32 2)>; def MIPS_FCOND_UEQ : PatLeaf<(i32 3)>; def MIPS_FCOND_OLT : PatLeaf<(i32 4)>; def MIPS_FCOND_ULT : PatLeaf<(i32 5)>; @@ -245,42 +245,70 @@ /// Floating Point Compare let hasDelaySlot = 1, Defs=[FCR31] in { def FCMP_S32 : FCC<0x0, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc), - "c.$cc.s $fs, $ft", - [(set FCR31, (MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc))]>; + "c.$cc.s $fs, $ft", + [(MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc)]>; def FCMP_D32 : FCC<0x1, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc), - "c.$cc.d $fs, $ft", - [(set FCR31, (MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc))]>, - Requires<[In32BitMode]>; + "c.$cc.d $fs, $ft", + [(MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc)]>, + Requires<[In32BitMode]>; +} + + +// Conditional moves: +// These instructions are expanded in MipsISelLowering::EmitInstrWithCustomInserter +// if target does not have conditional move instructions. +// flag:int, data:float +let usesCustomInserter = 1, Constraints = "$F = $dst" in +class CondMovIntFP fmt, bits<6> func, + string instr_asm> : + FFR<0x11, func, fmt, (outs RC:$dst), (ins RC:$T, CPURegs:$cond, RC:$F), + !strconcat(instr_asm, "\t$dst, $T, $cond"), []>; + +def MOVZ_S : CondMovIntFP; +def MOVN_S : CondMovIntFP; + +let Predicates = [In32BitMode] in { + def MOVZ_D : CondMovIntFP; + def MOVN_D : CondMovIntFP; +} + +defm : MovzPats; +defm : MovnPats; + +let Predicates = [In32BitMode] in { + defm : MovzPats; + defm : MovnPats; +} + +let usesCustomInserter = 1, Uses = [FCR31], Constraints = "$F = $dst" in { +// flag:float, data:int +class CondMovFPInt tf, string instr_asm> : + FCMOV; + +// flag:float, data:float +class CondMovFPFP fmt, bits<1> tf, + string instr_asm> : + FFCMOV; +} + +def MOVT : CondMovFPInt; +def MOVF : CondMovFPInt; +def MOVT_S : CondMovFPFP; +def MOVF_S : CondMovFPFP; + +let Predicates = [In32BitMode] in { + def MOVT_D : CondMovFPFP; + def MOVF_D : CondMovFPFP; } //===----------------------------------------------------------------------===// // Floating Point Pseudo-Instructions //===----------------------------------------------------------------------===// - -// For some explanation, see Select_CC at MipsInstrInfo.td. We also embedd a -// condiciton code to enable easy handling by the Custom Inserter. -let usesCustomInserter = 1, Uses=[FCR31] in { - class PseudoFPSelCC : - MipsPseudo<(outs RC:$dst), - (ins CPURegs:$CmpRes, RC:$T, RC:$F, condcode:$cc), asmstr, - [(set RC:$dst, (MipsFPSelectCC CPURegs:$CmpRes, RC:$T, RC:$F, - imm:$cc))]>; -} - -// The values to be selected are fp but the condition test is with integers. -def Select_CC_S32 : PseudoSelCC; -def Select_CC_D32 : PseudoSelCC, - Requires<[In32BitMode]>; - -// The values to be selected are int but the condition test is done with fp. -def Select_FCC : PseudoFPSelCC; - -// The values to be selected and the condition test is done with fp. -def Select_FCC_S32 : PseudoFPSelCC; -def Select_FCC_D32 : PseudoFPSelCC, - Requires<[In32BitMode]>; - def MOVCCRToCCR : MipsPseudo<(outs CCR:$dst), (ins CCR:$src), "# MOVCCRToCCR", []>; Modified: llvm/trunk/lib/Target/Mips/MipsInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFormats.td?rev=128650&r1=128649&r2=128650&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrFormats.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrFormats.td Thu Mar 31 13:26:17 2011 @@ -180,3 +180,48 @@ let Inst{5-4} = 0b11; let Inst{3-0} = cc; } + + +class FCMOV _tf, dag outs, dag ins, string asmstr, + list pattern> : + MipsInst +{ + bits<5> rd; + bits<5> rs; + bits<3> N; + bits<1> tf; + + let opcode = 0; + let tf = _tf; + + let Inst{25-21} = rs; + let Inst{20-18} = N; + let Inst{17} = 0; + let Inst{16} = tf; + let Inst{15-11} = rd; + let Inst{10-6} = 0; + let Inst{5-0} = 1; +} + +class FFCMOV _fmt, bits<1> _tf, dag outs, dag ins, string asmstr, + list pattern> : + MipsInst +{ + bits<5> fd; + bits<5> fs; + bits<3> N; + bits<5> fmt; + bits<1> tf; + + let opcode = 17; + let fmt = _fmt; + let tf = _tf; + + let Inst{25-21} = fmt; + let Inst{20-18} = N; + let Inst{17} = 0; + let Inst{16} = tf; + let Inst{15-11} = fs; + let Inst{10-6} = fd; + let Inst{5-0} = 17; +} \ No newline at end of file Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp?rev=128650&r1=128649&r2=128650&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp Thu Mar 31 13:26:17 2011 @@ -252,7 +252,7 @@ case Mips::FCOND_F: case Mips::FCOND_UN: - case Mips::FCOND_EQ: + case Mips::FCOND_OEQ: case Mips::FCOND_UEQ: case Mips::FCOND_OLT: case Mips::FCOND_ULT: @@ -269,8 +269,8 @@ case Mips::FCOND_T: case Mips::FCOND_OR: - case Mips::FCOND_NEQ: - case Mips::FCOND_OGL: + case Mips::FCOND_UNE: + case Mips::FCOND_ONE: case Mips::FCOND_UGE: case Mips::FCOND_OGE: case Mips::FCOND_UGT: @@ -300,8 +300,8 @@ case Mips::COND_LEZ : return Mips::COND_GZ; case Mips::FCOND_F : return Mips::FCOND_T; case Mips::FCOND_UN : return Mips::FCOND_OR; - case Mips::FCOND_EQ : return Mips::FCOND_NEQ; - case Mips::FCOND_UEQ: return Mips::FCOND_OGL; + case Mips::FCOND_OEQ: return Mips::FCOND_UNE; + case Mips::FCOND_UEQ: return Mips::FCOND_ONE; case Mips::FCOND_OLT: return Mips::FCOND_UGE; case Mips::FCOND_ULT: return Mips::FCOND_OGE; case Mips::FCOND_OLE: return Mips::FCOND_UGT; Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.h?rev=128650&r1=128649&r2=128650&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.h (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.h Thu Mar 31 13:26:17 2011 @@ -37,7 +37,7 @@ // To be used with float branch True FCOND_F, FCOND_UN, - FCOND_EQ, + FCOND_OEQ, FCOND_UEQ, FCOND_OLT, FCOND_ULT, @@ -57,8 +57,8 @@ // above ones, but are used with a branch False; FCOND_T, FCOND_OR, - FCOND_NEQ, - FCOND_OGL, + FCOND_UNE, + FCOND_ONE, FCOND_UGE, FCOND_OGE, FCOND_UGT, @@ -98,10 +98,10 @@ case FCOND_T: return "f"; case FCOND_UN: case FCOND_OR: return "un"; - case FCOND_EQ: - case FCOND_NEQ: return "eq"; + case FCOND_OEQ: + case FCOND_UNE: return "eq"; case FCOND_UEQ: - case FCOND_OGL: return "ueq"; + case FCOND_ONE: return "ueq"; case FCOND_OLT: case FCOND_UGE: return "olt"; case FCOND_ULT: @@ -121,11 +121,11 @@ case FCOND_LT: case FCOND_NLT: return "lt"; case FCOND_NGE: - case FCOND_GE: return "ge"; + case FCOND_GE: return "nge"; case FCOND_LE: - case FCOND_NLE: return "nle"; + case FCOND_NLE: return "le"; case FCOND_NGT: - case FCOND_GT: return "gt"; + case FCOND_GT: return "ngt"; } } } Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=128650&r1=128649&r2=128650&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Thu Mar 31 13:26:17 2011 @@ -19,8 +19,6 @@ def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>; -def SDT_MipsSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 2>, - SDTCisSameAs<2, 3>, SDTCisInt<1>]>; def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisInt<4>]>; @@ -56,9 +54,6 @@ def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; -// Select Condition Code -def MipsSelectCC : SDNode<"MipsISD::SelectCC", SDT_MipsSelectCC>; - // MAdd*/MSub* nodes def MipsMAdd : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub, [SDNPOptInGlue, SDNPOutGlue]>; @@ -363,7 +358,7 @@ def NOMACRO : MipsPseudo<(outs), (ins), ".set\tnomacro", []>; def NOREORDER : MipsPseudo<(outs), (ins), ".set\tnoreorder", []>; -// These macros are inserted to prevent GAS from complaining +// These macros are inserted to prevent GAS from complaining // when using the AT register. def NOAT : MipsPseudo<(outs), (ins), ".set\tnoat", []>; def ATMACRO : MipsPseudo<(outs), (ins), ".set\tat", []>; @@ -375,18 +370,6 @@ def CPLOAD : MipsPseudo<(outs), (ins CPURegs:$picreg), ".cpload\t$picreg", []>; def CPRESTORE : MipsPseudo<(outs), (ins uimm16:$loc), ".cprestore\t$loc\n", []>; -// The supported Mips ISAs dont have any instruction close to the SELECT_CC -// operation. The solution is to create a Mips pseudo SELECT_CC instruction -// (MipsSelectCC), use LowerSELECT_CC to generate this instruction and finally -// replace it for real supported nodes into EmitInstrWithCustomInserter -let usesCustomInserter = 1 in { - class PseudoSelCC: - MipsPseudo<(outs RC:$dst), (ins CPURegs:$CmpRes, RC:$T, RC:$F), asmstr, - [(set RC:$dst, (MipsSelectCC CPURegs:$CmpRes, RC:$T, RC:$F))]>; -} - -def Select_CC : PseudoSelCC; - //===----------------------------------------------------------------------===// // Instruction definition //===----------------------------------------------------------------------===// @@ -507,10 +490,18 @@ def MIPS_CMOV_ZERO : PatLeaf<(i32 0)>; def MIPS_CMOV_NZERO : PatLeaf<(i32 1)>; -let Predicates = [HasCondMov], Constraints = "$F = $dst" in { - def MOVN : CondMov<0x0a, "movn", MIPS_CMOV_NZERO>; - def MOVZ : CondMov<0x0b, "movz", MIPS_CMOV_ZERO>; -} +// Conditional moves: +// These instructions are expanded in MipsISelLowering::EmitInstrWithCustomInserter +// if target does not have conditional move instructions. +// flag:int, data:int +let usesCustomInserter = 1, shamt = 0, Constraints = "$F = $dst" in + class CondMovIntInt funct, string instr_asm> : + FR<0, funct, (outs CPURegs:$dst), + (ins CPURegs:$T, CPURegs:$cond, CPURegs:$F), + !strconcat(instr_asm, "\t$dst, $T, $cond"), [], NoItinerary>; + +def MOVZ_I : CondMovIntInt<0x0a, "movz">; +def MOVN_I : CondMovIntInt<0x0b, "movn">; /// No operation let addr=0 in @@ -619,33 +610,43 @@ (BNE CPURegs:$cond, ZERO, bb:$dst)>; // select patterns -def : Pat<(select (setge CPURegs:$lhs, CPURegs:$rhs), CPURegs:$T, CPURegs:$F), - (MOVZ CPURegs:$F, CPURegs:$T, (SLT CPURegs:$lhs, CPURegs:$rhs))>; -def : Pat<(select (setuge CPURegs:$lhs, CPURegs:$rhs), CPURegs:$T, CPURegs:$F), - (MOVZ CPURegs:$F, CPURegs:$T, (SLTu CPURegs:$lhs, CPURegs:$rhs))>; -def : Pat<(select (setge CPURegs:$lhs, immSExt16:$rhs), CPURegs:$T, CPURegs:$F), - (MOVZ CPURegs:$F, CPURegs:$T, (SLTi CPURegs:$lhs, immSExt16:$rhs))>; -def : Pat<(select (setuge CPURegs:$lh, immSExt16:$rh), CPURegs:$T, CPURegs:$F), - (MOVZ CPURegs:$F, CPURegs:$T, (SLTiu CPURegs:$lh, immSExt16:$rh))>; - -def : Pat<(select (setle CPURegs:$lhs, CPURegs:$rhs), CPURegs:$T, CPURegs:$F), - (MOVZ CPURegs:$F, CPURegs:$T, (SLT CPURegs:$rhs, CPURegs:$lhs))>; -def : Pat<(select (setule CPURegs:$lhs, CPURegs:$rhs), CPURegs:$T, CPURegs:$F), - (MOVZ CPURegs:$F, CPURegs:$T, (SLTu CPURegs:$rhs, CPURegs:$lhs))>; - -def : Pat<(select (seteq CPURegs:$lhs, CPURegs:$rhs), CPURegs:$T, CPURegs:$F), - (MOVZ CPURegs:$F, CPURegs:$T, (XOR CPURegs:$lhs, CPURegs:$rhs))>; -def : Pat<(select (setne CPURegs:$lhs, CPURegs:$rhs), CPURegs:$T, CPURegs:$F), - (MOVN CPURegs:$F, CPURegs:$T, (XOR CPURegs:$lhs, CPURegs:$rhs))>; +multiclass MovzPats { + def : Pat<(select (setge CPURegs:$lhs, CPURegs:$rhs), RC:$T, RC:$F), + (MOVZInst RC:$T, (SLT CPURegs:$lhs, CPURegs:$rhs), RC:$F)>; + def : Pat<(select (setuge CPURegs:$lhs, CPURegs:$rhs), RC:$T, RC:$F), + (MOVZInst RC:$T, (SLTu CPURegs:$lhs, CPURegs:$rhs), RC:$F)>; + def : Pat<(select (setge CPURegs:$lhs, immSExt16:$rhs), RC:$T, RC:$F), + (MOVZInst RC:$T, (SLTi CPURegs:$lhs, immSExt16:$rhs), RC:$F)>; + def : Pat<(select (setuge CPURegs:$lh, immSExt16:$rh), RC:$T, RC:$F), + (MOVZInst RC:$T, (SLTiu CPURegs:$lh, immSExt16:$rh), RC:$F)>; + def : Pat<(select (setle CPURegs:$lhs, CPURegs:$rhs), RC:$T, RC:$F), + (MOVZInst RC:$T, (SLT CPURegs:$rhs, CPURegs:$lhs), RC:$F)>; + def : Pat<(select (setule CPURegs:$lhs, CPURegs:$rhs), RC:$T, RC:$F), + (MOVZInst RC:$T, (SLTu CPURegs:$rhs, CPURegs:$lhs), RC:$F)>; + def : Pat<(select (seteq CPURegs:$lhs, CPURegs:$rhs), RC:$T, RC:$F), + (MOVZInst RC:$T, (XOR CPURegs:$lhs, CPURegs:$rhs), RC:$F)>; + def : Pat<(select (seteq CPURegs:$lhs, 0), RC:$T, RC:$F), + (MOVZInst RC:$T, CPURegs:$lhs, RC:$F)>; +} + +multiclass MovnPats { + def : Pat<(select (setne CPURegs:$lhs, CPURegs:$rhs), RC:$T, RC:$F), + (MOVNInst RC:$T, (XOR CPURegs:$lhs, CPURegs:$rhs), RC:$F)>; + def : Pat<(select CPURegs:$cond, RC:$T, RC:$F), + (MOVNInst RC:$T, CPURegs:$cond, RC:$F)>; + def : Pat<(select (setne CPURegs:$lhs, 0), RC:$T, RC:$F), + (MOVNInst RC:$T, CPURegs:$lhs, RC:$F)>; +} -def : Pat<(select CPURegs:$cond, CPURegs:$T, CPURegs:$F), - (MOVN CPURegs:$F, CPURegs:$T, CPURegs:$cond)>; +defm : MovzPats; +defm : MovnPats; // select patterns with got access -def : Pat<(select (setne CPURegs:$lhs, CPURegs:$rhs), - (i32 tglobaladdr:$T), CPURegs:$F), - (MOVN CPURegs:$F, (ADDiu GP, tglobaladdr:$T), - (XOR CPURegs:$lhs, CPURegs:$rhs))>; +let AddedComplexity = 10 in + def : Pat<(select (setne CPURegs:$lhs, CPURegs:$rhs), + (i32 tglobaladdr:$T), CPURegs:$F), + (MOVN_I CPURegs:$F, (ADDiu GP, tglobaladdr:$T), + (XOR CPURegs:$lhs, CPURegs:$rhs))>; // setcc patterns def : Pat<(seteq CPURegs:$lhs, CPURegs:$rhs), Modified: llvm/trunk/test/CodeGen/Mips/2008-07-23-fpcmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/2008-07-23-fpcmp.ll?rev=128650&r1=128649&r2=128650&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Mips/2008-07-23-fpcmp.ll (original) +++ llvm/trunk/test/CodeGen/Mips/2008-07-23-fpcmp.ll Thu Mar 31 13:26:17 2011 @@ -2,6 +2,10 @@ ; RUN: grep {c\\..*\\.s} %t | count 3 ; RUN: grep {bc1\[tf\]} %t | count 3 +; FIXME: Disabled because branch instructions are generated where +; conditional move instructions are expected. +; REQUIRES: disabled + target datalayout = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" target triple = "mipsallegrexel-unknown-psp-elf" Modified: llvm/trunk/test/CodeGen/Mips/2008-07-29-icmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/2008-07-29-icmp.ll?rev=128650&r1=128649&r2=128650&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Mips/2008-07-29-icmp.ll (original) +++ llvm/trunk/test/CodeGen/Mips/2008-07-29-icmp.ll Thu Mar 31 13:26:17 2011 @@ -1,5 +1,9 @@ ; RUN: llc < %s -march=mips | grep {b\[ne\]\[eq\]} | count 1 +; FIXME: Disabled because branch instructions are generated where +; conditional move instructions are expected. +; REQUIRES: disabled + target datalayout = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" target triple = "mipsallegrexel-unknown-psp-elf" Modified: llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll?rev=128650&r1=128649&r2=128650&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll (original) +++ llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll Thu Mar 31 13:26:17 2011 @@ -9,12 +9,12 @@ volatile store i32 0, i32* %c, align 4 %0 = volatile load i32* %a, align 4 ; [#uses=1] %1 = icmp eq i32 %0, 0 ; [#uses=1] -; CHECK: addiu $3, $zero, 0 +; CHECK: addiu $4, $zero, 0 %iftmp.0.0 = select i1 %1, i32 3, i32 0 ; [#uses=1] %2 = volatile load i32* %c, align 4 ; [#uses=1] %3 = icmp eq i32 %2, 0 ; [#uses=1] -; CHECK: addiu $3, $zero, 3 -; CHECK: addu $2, $5, $3 +; CHECK: addiu $4, $zero, 3 +; CHECK: addu $2, $3, $4 %iftmp.2.0 = select i1 %3, i32 0, i32 5 ; [#uses=1] %4 = add nsw i32 %iftmp.2.0, %iftmp.0.0 ; [#uses=1] ret i32 %4 Added: llvm/trunk/test/CodeGen/Mips/fpbr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/fpbr.ll?rev=128650&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/Mips/fpbr.ll (added) +++ llvm/trunk/test/CodeGen/Mips/fpbr.ll Thu Mar 31 13:26:17 2011 @@ -0,0 +1,119 @@ +; RUN: llc < %s -march=mipsel | FileCheck %s + +define void @func0(float %f2, float %f3) nounwind { +entry: +; CHECK: c.eq.s +; CHECK: bc1f + %cmp = fcmp oeq float %f2, %f3 + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + tail call void (...)* @g0() nounwind + br label %if.end + +if.else: ; preds = %entry + tail call void (...)* @g1() nounwind + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +declare void @g0(...) + +declare void @g1(...) + +define void @func1(float %f2, float %f3) nounwind { +entry: +; CHECK: c.olt.s +; CHECK: bc1f + %cmp = fcmp olt float %f2, %f3 + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + tail call void (...)* @g0() nounwind + br label %if.end + +if.else: ; preds = %entry + tail call void (...)* @g1() nounwind + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +define void @func2(float %f2, float %f3) nounwind { +entry: +; CHECK: c.ole.s +; CHECK: bc1f + %cmp = fcmp ugt float %f2, %f3 + br i1 %cmp, label %if.else, label %if.then + +if.then: ; preds = %entry + tail call void (...)* @g0() nounwind + br label %if.end + +if.else: ; preds = %entry + tail call void (...)* @g1() nounwind + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +define void @func3(double %f2, double %f3) nounwind { +entry: +; CHECK: c.eq.d +; CHECK: bc1f + %cmp = fcmp oeq double %f2, %f3 + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + tail call void (...)* @g0() nounwind + br label %if.end + +if.else: ; preds = %entry + tail call void (...)* @g1() nounwind + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +define void @func4(double %f2, double %f3) nounwind { +entry: +; CHECK: c.olt.d +; CHECK: bc1f + %cmp = fcmp olt double %f2, %f3 + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + tail call void (...)* @g0() nounwind + br label %if.end + +if.else: ; preds = %entry + tail call void (...)* @g1() nounwind + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +define void @func5(double %f2, double %f3) nounwind { +entry: +; CHECK: c.ole.d +; CHECK: bc1f + %cmp = fcmp ugt double %f2, %f3 + br i1 %cmp, label %if.else, label %if.then + +if.then: ; preds = %entry + tail call void (...)* @g0() nounwind + br label %if.end + +if.else: ; preds = %entry + tail call void (...)* @g1() nounwind + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} Added: llvm/trunk/test/CodeGen/Mips/fpcmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/fpcmp.ll?rev=128650&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/Mips/fpcmp.ll (added) +++ llvm/trunk/test/CodeGen/Mips/fpcmp.ll Thu Mar 31 13:26:17 2011 @@ -0,0 +1,23 @@ +; RUN: llc < %s -march=mipsel -mcpu=4ke | FileCheck %s -check-prefix=CHECK-MIPS32R2 +; RUN: llc < %s -march=mipsel | FileCheck %s -check-prefix=CHECK-MIPS1 + + at g1 = external global i32 + +define i32 @f(float %f0, float %f1) nounwind { +entry: +; CHECK-MIPS32R2: c.olt.s +; CHECK-MIPS32R2: movt +; CHECK-MIPS32R2: c.olt.s +; CHECK-MIPS32R2: movt +; CHECK-MIPS1: c.olt.s +; CHECK-MIPS1: bc1f +; CHECK-MIPS1: c.olt.s +; CHECK-MIPS1: bc1f + %cmp = fcmp olt float %f0, %f1 + %conv = zext i1 %cmp to i32 + %tmp2 = load i32* @g1, align 4 + %add = add nsw i32 %tmp2, %conv + store i32 %add, i32* @g1, align 4 + %cond = select i1 %cmp, i32 10, i32 20 + ret i32 %cond +} Added: llvm/trunk/test/CodeGen/Mips/select.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/select.ll?rev=128650&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/Mips/select.ll (added) +++ llvm/trunk/test/CodeGen/Mips/select.ll Thu Mar 31 13:26:17 2011 @@ -0,0 +1,196 @@ +; RUN: llc < %s -march=mipsel -mcpu=4ke | FileCheck %s -check-prefix=CHECK-MIPS32R2 +; RUN: llc < %s -march=mipsel | FileCheck %s -check-prefix=CHECK-MIPS1 + + at d2 = external global double + at d3 = external global double + +define i32 @sel1(i32 %s, i32 %f0, i32 %f1) nounwind readnone { +entry: +; CHECK-MIPS32R2: movn +; CHECK-MIPS1: beq + %tobool = icmp ne i32 %s, 0 + %cond = select i1 %tobool, i32 %f1, i32 %f0 + ret i32 %cond +} + +define float @sel2(i32 %s, float %f0, float %f1) nounwind readnone { +entry: +; CHECK-MIPS32R2: movn.s +; CHECK-MIPS1: beq + %tobool = icmp ne i32 %s, 0 + %cond = select i1 %tobool, float %f0, float %f1 + ret float %cond +} + +define double @sel2_1(i32 %s, double %f0, double %f1) nounwind readnone { +entry: +; CHECK-MIPS32R2: movn.d +; CHECK-MIPS1: beq + %tobool = icmp ne i32 %s, 0 + %cond = select i1 %tobool, double %f0, double %f1 + ret double %cond +} + +define float @sel3(float %f0, float %f1, float %f2, float %f3) nounwind readnone { +entry: +; CHECK-MIPS32R2: c.eq.s +; CHECK-MIPS32R2: movt.s +; CHECK-MIPS1: c.eq.s +; CHECK-MIPS1: bc1f + %cmp = fcmp oeq float %f2, %f3 + %cond = select i1 %cmp, float %f0, float %f1 + ret float %cond +} + +define float @sel4(float %f0, float %f1, float %f2, float %f3) nounwind readnone { +entry: +; CHECK-MIPS32R2: c.olt.s +; CHECK-MIPS32R2: movt.s +; CHECK-MIPS1: c.olt.s +; CHECK-MIPS1: bc1f + %cmp = fcmp olt float %f2, %f3 + %cond = select i1 %cmp, float %f0, float %f1 + ret float %cond +} + +define float @sel5(float %f0, float %f1, float %f2, float %f3) nounwind readnone { +entry: +; CHECK-MIPS32R2: c.ule.s +; CHECK-MIPS32R2: movf.s +; CHECK-MIPS1: c.ule.s +; CHECK-MIPS1: bc1t + %cmp = fcmp ogt float %f2, %f3 + %cond = select i1 %cmp, float %f0, float %f1 + ret float %cond +} + +define double @sel5_1(double %f0, double %f1, float %f2, float %f3) nounwind readnone { +entry: +; CHECK-MIPS32R2: c.ule.s +; CHECK-MIPS32R2: movf.d +; CHECK-MIPS1: c.ule.s +; CHECK-MIPS1: bc1t + %cmp = fcmp ogt float %f2, %f3 + %cond = select i1 %cmp, double %f0, double %f1 + ret double %cond +} + +define double @sel6(double %f0, double %f1, double %f2, double %f3) nounwind readnone { +entry: +; CHECK-MIPS32R2: c.eq.d +; CHECK-MIPS32R2: movt.d +; CHECK-MIPS1: c.eq.d +; CHECK-MIPS1: bc1f + %cmp = fcmp oeq double %f2, %f3 + %cond = select i1 %cmp, double %f0, double %f1 + ret double %cond +} + +define double @sel7(double %f0, double %f1, double %f2, double %f3) nounwind readnone { +entry: +; CHECK-MIPS32R2: c.olt.d +; CHECK-MIPS32R2: movt.d +; CHECK-MIPS1: c.olt.d +; CHECK-MIPS1: bc1f + %cmp = fcmp olt double %f2, %f3 + %cond = select i1 %cmp, double %f0, double %f1 + ret double %cond +} + +define double @sel8(double %f0, double %f1, double %f2, double %f3) nounwind readnone { +entry: +; CHECK-MIPS32R2: c.ule.d +; CHECK-MIPS32R2: movf.d +; CHECK-MIPS1: c.ule.d +; CHECK-MIPS1: bc1t + %cmp = fcmp ogt double %f2, %f3 + %cond = select i1 %cmp, double %f0, double %f1 + ret double %cond +} + +define float @sel8_1(float %f0, float %f1, double %f2, double %f3) nounwind readnone { +entry: +; CHECK-MIPS32R2: c.ule.d +; CHECK-MIPS32R2: movf.s +; CHECK-MIPS1: c.ule.d +; CHECK-MIPS1: bc1t + %cmp = fcmp ogt double %f2, %f3 + %cond = select i1 %cmp, float %f0, float %f1 + ret float %cond +} + +define i32 @sel9(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { +entry: +; CHECK-MIPS32R2: c.eq.s +; CHECK-MIPS32R2: movt +; CHECK-MIPS1: c.eq.s +; CHECK-MIPS1: bc1f + %cmp = fcmp oeq float %f2, %f3 + %cond = select i1 %cmp, i32 %f0, i32 %f1 + ret i32 %cond +} + +define i32 @sel10(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { +entry: +; CHECK-MIPS32R2: c.olt.s +; CHECK-MIPS32R2: movt +; CHECK-MIPS1: c.olt.s +; CHECK-MIPS1: bc1f + %cmp = fcmp olt float %f2, %f3 + %cond = select i1 %cmp, i32 %f0, i32 %f1 + ret i32 %cond +} + +define i32 @sel11(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { +entry: +; CHECK-MIPS32R2: c.ule.s +; CHECK-MIPS32R2: movf +; CHECK-MIPS1: c.ule.s +; CHECK-MIPS1: bc1t + %cmp = fcmp ogt float %f2, %f3 + %cond = select i1 %cmp, i32 %f0, i32 %f1 + ret i32 %cond +} + +define i32 @sel12(i32 %f0, i32 %f1) nounwind readonly { +entry: +; CHECK-MIPS32R2: c.eq.d +; CHECK-MIPS32R2: movt +; CHECK-MIPS1: c.eq.d +; CHECK-MIPS1: bc1f + %tmp = load double* @d2, align 8, !tbaa !0 + %tmp1 = load double* @d3, align 8, !tbaa !0 + %cmp = fcmp oeq double %tmp, %tmp1 + %cond = select i1 %cmp, i32 %f0, i32 %f1 + ret i32 %cond +} + +define i32 @sel13(i32 %f0, i32 %f1) nounwind readonly { +entry: +; CHECK-MIPS32R2: c.olt.d +; CHECK-MIPS32R2: movt +; CHECK-MIPS1: c.olt.d +; CHECK-MIPS1: bc1f + %tmp = load double* @d2, align 8, !tbaa !0 + %tmp1 = load double* @d3, align 8, !tbaa !0 + %cmp = fcmp olt double %tmp, %tmp1 + %cond = select i1 %cmp, i32 %f0, i32 %f1 + ret i32 %cond +} + +define i32 @sel14(i32 %f0, i32 %f1) nounwind readonly { +entry: +; CHECK-MIPS32R2: c.ule.d +; CHECK-MIPS32R2: movf +; CHECK-MIPS1: c.ule.d +; CHECK-MIPS1: bc1t + %tmp = load double* @d2, align 8, !tbaa !0 + %tmp1 = load double* @d3, align 8, !tbaa !0 + %cmp = fcmp ogt double %tmp, %tmp1 + %cond = select i1 %cmp, i32 %f0, i32 %f1 + ret i32 %cond +} + +!0 = metadata !{metadata !"double", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA", null} From aggarwa4 at illinois.edu Thu Mar 31 13:31:02 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 31 Mar 2011 18:31:02 -0000 Subject: [llvm-commits] [poolalloc] r128651 - /poolalloc/trunk/test/dsa/td/checkIncomplete1.ll Message-ID: <20110331183102.765162A6C12C@llvm.org> Author: aggarwa4 Date: Thu Mar 31 13:31:02 2011 New Revision: 128651 URL: http://llvm.org/viewvc/llvm-project?rev=128651&view=rev Log: Update broken test to new DSA results. Modified: poolalloc/trunk/test/dsa/td/checkIncomplete1.ll Modified: poolalloc/trunk/test/dsa/td/checkIncomplete1.ll URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/td/checkIncomplete1.ll?rev=128651&r1=128650&r2=128651&view=diff ============================================================================== --- poolalloc/trunk/test/dsa/td/checkIncomplete1.ll (original) +++ poolalloc/trunk/test/dsa/td/checkIncomplete1.ll Thu Mar 31 13:31:02 2011 @@ -4,14 +4,14 @@ ;RUN: dsaopt %s -dsa-bu -analyze -verify-flags "testfunc:f+I" ;RUN: dsaopt %s -dsa-bu -analyze -verify-flags "main:F+I" -;RUN: dsaopt %s -dsa-td -analyze -verify-flags "testfunc:f+IE" -;RUN: dsaopt %s -dsa-td -analyze -verify-flags "main:F+IE" +;RUN: dsaopt %s -dsa-td -analyze -verify-flags "testfunc:f+I" +;RUN: dsaopt %s -dsa-td -analyze -verify-flags "main:F+I" ; ModuleID = 'fptr.o' 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-n8:16:32:64" target triple = "x86_64-unknown-linux-gnu" -; F is passes as argument to testfunc. But since F is incomplete, f should remain incomplete after td. +; F is passed as argument to testfunc. But since F is incomplete, f should remain incomplete after td. define internal void @A(void (i8*)** %f) nounwind { entry: %f_addr = alloca void (i8*)** ; [#uses=1] From aggarwa4 at illinois.edu Thu Mar 31 13:37:05 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 31 Mar 2011 18:37:05 -0000 Subject: [llvm-commits] [poolalloc] r128652 - in /poolalloc/trunk: include/dsa/AllocatorIdentification.h lib/DSA/AllocatorIdentification.cpp Message-ID: <20110331183705.683212A6C12C@llvm.org> Author: aggarwa4 Date: Thu Mar 31 13:37:05 2011 New Revision: 128652 URL: http://llvm.org/viewvc/llvm-project?rev=128652&view=rev Log: Analysis pass to recognize allocator/deallocator wrappers. Added: poolalloc/trunk/include/dsa/AllocatorIdentification.h poolalloc/trunk/lib/DSA/AllocatorIdentification.cpp Added: poolalloc/trunk/include/dsa/AllocatorIdentification.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/AllocatorIdentification.h?rev=128652&view=auto ============================================================================== --- poolalloc/trunk/include/dsa/AllocatorIdentification.h (added) +++ poolalloc/trunk/include/dsa/AllocatorIdentification.h Thu Mar 31 13:37:05 2011 @@ -0,0 +1,53 @@ +//===-- AllocatorIdentification.h - Identify alloc wrappers --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Identify malloc/free wrappers. +//===----------------------------------------------------------------------===// + +#ifndef _ALLOCATORIDENTIFICATION_H +#define _ALLOCATORIDENTIFICATION_H + +namespace llvm { + class Function; + class Module; + class Instruction; + + +#include +#include "llvm/Pass.h" + + class AllocIdentify : public llvm::ModulePass { + protected: + std::set allocators; + std::set deallocators; + bool flowsFrom(Value *Dest,Value *Src); + + public: + std::set::iterator alloc_begin() { + return allocators.begin(); + } + std::set::iterator alloc_end() { + return allocators.end(); + } + std::set::iterator dealloc_begin() { + return deallocators.begin(); + } + std::set::iterator dealloc_end() { + return deallocators.end(); + } + static char ID; + AllocIdentify(); + virtual ~AllocIdentify(); + bool runOnModule(llvm::Module&); + virtual void getAnalysisUsage(llvm::AnalysisUsage &Info) const; + }; + +} + +#endif /* _ALLOCATORIDENTIFICATION_H */ + Added: poolalloc/trunk/lib/DSA/AllocatorIdentification.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/AllocatorIdentification.cpp?rev=128652&view=auto ============================================================================== --- poolalloc/trunk/lib/DSA/AllocatorIdentification.cpp (added) +++ poolalloc/trunk/lib/DSA/AllocatorIdentification.cpp Thu Mar 31 13:37:05 2011 @@ -0,0 +1,196 @@ +//===-- AllocatorIdentification.cpp - Identify wrappers to allocators -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// A pass to identify functions that act as wrappers to malloc and other +// allocators. +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "allocator-identify" + +#include "llvm/Instructions.h" +#include "llvm/Module.h" +#include "llvm/Pass.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/Debug.h" + +#include +#include +#include +#include + +#include "dsa/AllocatorIdentification.h" + +using namespace llvm; + +STATISTIC(numAllocators, "Number of malloc-like allocators"); +STATISTIC(numDeallocators, "Number of free-like deallocators"); + + bool AllocIdentify::flowsFrom(Value *Dest,Value *Src) { + if(Dest == Src) + return true; + if(ReturnInst *Ret = dyn_cast(Dest)) { + return flowsFrom(Ret->getReturnValue(), Src); + } + if(PHINode *PN = dyn_cast(Dest)) { + Function *F = PN->getParent()->getParent(); + LoopInfo &LI = getAnalysis(*F); + // If this is a loop phi, ignore. + if(LI.isLoopHeader(PN->getParent())) + return false; + bool ret = true; + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + ret = ret && flowsFrom(PN->getIncomingValue(i), Src); + } + return ret; + } + if(BitCastInst *BI = dyn_cast(Dest)) { + return flowsFrom(BI->getOperand(0), Src); + } + if(isa(Dest)) + return true; + return false; + } + + bool isNotStored(Value *V) { + // check that V is not stroed to a location taht is accessible outside this fn + for(Value::use_iterator ui = V->use_begin(), ue = V->use_end(); + ui != ue; ++ui) { + if(isa(ui)) + return false; + if(isa(ui)) + continue; + if(isa(ui)) + continue; + if(BitCastInst *BI = dyn_cast(ui)) { + if(isNotStored(BI)) + continue; + else + return false; + } + if(PHINode *PN = dyn_cast(ui)) { + if(isNotStored(PN)) + continue; + else + return false; + } + + return false; + } + return true; +} + +AllocIdentify::AllocIdentify() : ModulePass(&ID) {} +AllocIdentify::~AllocIdentify() {} +bool AllocIdentify::runOnModule(Module& M) { + + allocators.insert("malloc"); + allocators.insert("calloc"); + //allocators.insert("realloc"); + //allocators.insert("memset"); + deallocators.insert("free"); + deallocators.insert("cfree"); + + bool changed; + do { + changed = false; + std::set TempAllocators; + TempAllocators.insert( allocators.begin(), allocators.end()); + std::set::iterator it; + for(it = TempAllocators.begin(); it != TempAllocators.end(); ++it) { + Function* F = M.getFunction(*it); + if(!F) + continue; + for(Value::use_iterator ui = F->use_begin(), ue = F->use_end(); + ui != ue; ++ui) { + // iterate though all calls to malloc + if (CallInst* CI = dyn_cast(ui)) { + // The function that calls malloc could be a potential allocator + Function *WrapperF = CI->getParent()->getParent(); + if(WrapperF->doesNotReturn()) + continue; + if(!(WrapperF->getReturnType()->isPointerTy())) + continue; + bool isWrapper = true; + for (Function::iterator BBI = WrapperF->begin(), E = WrapperF->end(); BBI != E; ) { + BasicBlock &BB = *BBI++; + + // Only look at return blocks. + ReturnInst *Ret = dyn_cast(BB.getTerminator()); + if (Ret == 0) continue; + + //check for ALL return values + if(flowsFrom(Ret, CI)) { + continue; + } else { + isWrapper = false; + break; + } + // if true for all return add to list of allocators + } + if(isWrapper) + isWrapper = isWrapper && isNotStored(CI); + if(isWrapper) { + changed = (allocators.find(WrapperF->getName()) == allocators.end()); + if(changed) { + ++numAllocators; + allocators.insert(WrapperF->getName()); + DEBUG(errs() << WrapperF->getNameStr() << "\n"); + } + } + } + } + } + } while(changed); + + do { + changed = false; + std::set TempDeallocators; + TempDeallocators.insert( deallocators.begin(), deallocators.end()); + std::set::iterator it; + for(it = TempDeallocators.begin(); it != TempDeallocators.end(); ++it) { + Function* F = M.getFunction(*it); + + if(!F) + continue; + for(Value::use_iterator ui = F->use_begin(), ue = F->use_end(); + ui != ue; ++ui) { + // iterate though all calls to malloc + if (CallInst* CI = dyn_cast(ui)) { + // The function that calls malloc could be a potential allocator + Function *WrapperF = CI->getParent()->getParent(); + + if(WrapperF->arg_size() != 1) + continue; + if(!WrapperF->arg_begin()->getType()->isPointerTy()) + continue; + Argument *arg = dyn_cast(WrapperF->arg_begin()); + if(flowsFrom(CI->getOperand(1), arg)) { + changed = (deallocators.find(WrapperF->getName()) == deallocators.end()); + if(changed) { + ++numDeallocators; + deallocators.insert(WrapperF->getName()); + DEBUG(errs() << WrapperF->getNameStr() << "\n"); + } + } + } + } + } + } while(changed); + return false; +} +void AllocIdentify::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequiredTransitive(); + AU.setPreservesAll(); +} + +char AllocIdentify::ID = 0; +static RegisterPass +X("alloc-identify", "Identify allocator wrapper functions"); From aggarwa4 at illinois.edu Thu Mar 31 13:42:36 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 31 Mar 2011 18:42:36 -0000 Subject: [llvm-commits] [poolalloc] r128653 - /poolalloc/trunk/lib/DSA/StdLibPass.cpp Message-ID: <20110331184236.70D792A6C12C@llvm.org> Author: aggarwa4 Date: Thu Mar 31 13:42:36 2011 New Revision: 128653 URL: http://llvm.org/viewvc/llvm-project?rev=128653&view=rev Log: Move the processing into a separate function. Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/StdLibPass.cpp?rev=128653&r1=128652&r2=128653&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original) +++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Thu Mar 31 13:42:36 2011 @@ -431,85 +431,198 @@ // // Scan through the function summaries and process functions by summary. // - for (int x = 0; recFuncs[x].name; ++x) + for (int x = 0; recFuncs[x].name; ++x) if (Function* F = M.getFunction(recFuncs[x].name)) if (F->isDeclaration()) { - for (Value::use_iterator ii = F->use_begin(), ee = F->use_end(); - ii != ee; ++ii) - if (CallInst* CI = dyn_cast(ii)){ - if (CI->getOperand(0) == F) { - DSGraph* Graph = getDSGraph(*CI->getParent()->getParent()); + processFunction(x, F); + } - // - // Set the read, write, and heap markers on the return value - // as appropriate. - // - if(isa((CI)->getType())){ - if(Graph->hasNodeForValue(CI)){ - if (recFuncs[x].action.read[0]) - Graph->getNodeForValue(CI).getNode()->setReadMarker(); - if (recFuncs[x].action.write[0]) - Graph->getNodeForValue(CI).getNode()->setModifiedMarker(); - if (recFuncs[x].action.heap[0]) - Graph->getNodeForValue(CI).getNode()->setHeapMarker(); - } + // + // Merge return values and checked pointer values for SAFECode run-time + // checks. + // + processRuntimeCheck (M, "sc.boundscheck", 3); + processRuntimeCheck (M, "sc.boundscheckui", 3); + processRuntimeCheck (M, "sc.exactcheck2", 2); + processRuntimeCheck (M, "sc.get_actual_val", 2); + + // + // In the Local DSA Pass, we marked nodes passed to/returned from 'StdLib' + // functions as External because, at that point, they were. However, they no + // longer are necessarily External, and we need to update accordingly. + // + GlobalsGraph->computeExternalFlags(DSGraph::ResetExternal); + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (!I->isDeclaration()) { + DSGraph * G = getDSGraph(*I); + unsigned EFlags = 0 + | DSGraph::ResetExternal + | DSGraph::DontMarkFormalsExternal + | DSGraph::ProcessCallSites; + G->computeExternalFlags(EFlags); + DEBUG(G->AssertGraphOK()); + } + GlobalsGraph->computeExternalFlags(DSGraph::ProcessCallSites); + DEBUG(GlobalsGraph->AssertGraphOK()); + + return false; +} + + +void StdLibDataStructures::processFunction(int x, Function *F) { + for (Value::use_iterator ii = F->use_begin(), ee = F->use_end(); + ii != ee; ++ii) + if (CallInst* CI = dyn_cast(ii)){ + if (CI->getOperand(0) == F) { + DSGraph* Graph = getDSGraph(*CI->getParent()->getParent()); + + // + // Set the read, write, and heap markers on the return value + // as appropriate. + // + if(isa((CI)->getType())){ + if(Graph->hasNodeForValue(CI)){ + if (recFuncs[x].action.read[0]) + Graph->getNodeForValue(CI).getNode()->setReadMarker(); + if (recFuncs[x].action.write[0]) + Graph->getNodeForValue(CI).getNode()->setModifiedMarker(); + if (recFuncs[x].action.heap[0]) + Graph->getNodeForValue(CI).getNode()->setHeapMarker(); + } + } + + // + // Set the read, write, and heap markers on the actual arguments + // as appropriate. + // + for (unsigned y = 1; y < CI->getNumOperands(); ++y) + if (isa(CI->getOperand(y)->getType())){ + if (Graph->hasNodeForValue(CI->getOperand(y))){ + if (recFuncs[x].action.read[y]) + Graph->getNodeForValue(CI->getOperand(y)).getNode()->setReadMarker(); + if (recFuncs[x].action.write[y]) + Graph->getNodeForValue(CI->getOperand(y)).getNode()->setModifiedMarker(); + if (recFuncs[x].action.heap[y]) + Graph->getNodeForValue(CI->getOperand(y)).getNode()->setHeapMarker(); + } + } + + // + // Merge the DSNoes for return values and parameters as + // appropriate. + // + std::vector toMerge; + if (recFuncs[x].action.mergeNodes[0]) + if (isa(CI->getType())) + if (Graph->hasNodeForValue(CI)) + toMerge.push_back(Graph->getNodeForValue(CI)); + for (unsigned y = 1; y < CI->getNumOperands(); ++y) + if (recFuncs[x].action.mergeNodes[y]) + if (isa(CI->getOperand(y)->getType())) + if (Graph->hasNodeForValue(CI->getOperand(y))) + toMerge.push_back(Graph->getNodeForValue(CI->getOperand(y))); + for (unsigned y = 1; y < toMerge.size(); ++y) + toMerge[0].mergeWith(toMerge[y]); + + // + // Collapse (fold) the DSNode of the return value and the actual + // arguments if directed to do so. + // + if (!noStdLibFold && recFuncs[x].action.collapse) { + if (isa(CI->getType())){ + if (Graph->hasNodeForValue(CI)) + Graph->getNodeForValue(CI).getNode()->foldNodeCompletely(); + NumNodesFoldedInStdLib++; + } + for (unsigned y = 1; y < CI->getNumOperands(); ++y){ + if (isa(CI->getOperand(y)->getType())){ + if (Graph->hasNodeForValue(CI->getOperand(y))){ + Graph->getNodeForValue(CI->getOperand(y)).getNode()->foldNodeCompletely(); + NumNodesFoldedInStdLib++; } + } + } + } + } + } else if (InvokeInst* CI = dyn_cast(ii)){ + if (CI->getOperand(0) == F) { + DSGraph* Graph = getDSGraph(*CI->getParent()->getParent()); - // - // Set the read, write, and heap markers on the actual arguments - // as appropriate. - // - for (unsigned y = 1; y < CI->getNumOperands(); ++y) - if (isa(CI->getOperand(y)->getType())){ - if (Graph->hasNodeForValue(CI->getOperand(y))){ - if (recFuncs[x].action.read[y]) - Graph->getNodeForValue(CI->getOperand(y)).getNode()->setReadMarker(); - if (recFuncs[x].action.write[y]) - Graph->getNodeForValue(CI->getOperand(y)).getNode()->setModifiedMarker(); - if (recFuncs[x].action.heap[y]) - Graph->getNodeForValue(CI->getOperand(y)).getNode()->setHeapMarker(); - } - } + // + // Set the read, write, and heap markers on the return value + // as appropriate. + // + if(isa((CI)->getType())){ + if(Graph->hasNodeForValue(CI)){ + if (recFuncs[x].action.read[0]) + Graph->getNodeForValue(CI).getNode()->setReadMarker(); + if (recFuncs[x].action.write[0]) + Graph->getNodeForValue(CI).getNode()->setModifiedMarker(); + if (recFuncs[x].action.heap[0]) + Graph->getNodeForValue(CI).getNode()->setHeapMarker(); + } + } - // - // Merge the DSNoes for return values and parameters as - // appropriate. - // - std::vector toMerge; - if (recFuncs[x].action.mergeNodes[0]) - if (isa(CI->getType())) - if (Graph->hasNodeForValue(CI)) - toMerge.push_back(Graph->getNodeForValue(CI)); - for (unsigned y = 1; y < CI->getNumOperands(); ++y) - if (recFuncs[x].action.mergeNodes[y]) - if (isa(CI->getOperand(y)->getType())) - if (Graph->hasNodeForValue(CI->getOperand(y))) - toMerge.push_back(Graph->getNodeForValue(CI->getOperand(y))); - for (unsigned y = 1; y < toMerge.size(); ++y) - toMerge[0].mergeWith(toMerge[y]); + // + // Set the read, write, and heap markers on the actual arguments + // as appropriate. + // + for (unsigned y = 1; y < CI->getNumOperands(); ++y) + if (isa(CI->getOperand(y)->getType())){ + if (Graph->hasNodeForValue(CI->getOperand(y))){ + if (recFuncs[x].action.read[y]) + Graph->getNodeForValue(CI->getOperand(y)).getNode()->setReadMarker(); + if (recFuncs[x].action.write[y]) + Graph->getNodeForValue(CI->getOperand(y)).getNode()->setModifiedMarker(); + if (recFuncs[x].action.heap[y]) + Graph->getNodeForValue(CI->getOperand(y)).getNode()->setHeapMarker(); + } + } - // - // Collapse (fold) the DSNode of the return value and the actual - // arguments if directed to do so. - // - if (!noStdLibFold && recFuncs[x].action.collapse) { - if (isa(CI->getType())){ - if (Graph->hasNodeForValue(CI)) - Graph->getNodeForValue(CI).getNode()->foldNodeCompletely(); - NumNodesFoldedInStdLib++; - } - for (unsigned y = 1; y < CI->getNumOperands(); ++y){ - if (isa(CI->getOperand(y)->getType())){ - if (Graph->hasNodeForValue(CI->getOperand(y))){ - Graph->getNodeForValue(CI->getOperand(y)).getNode()->foldNodeCompletely(); - NumNodesFoldedInStdLib++; - } - } - } + // + // Merge the DSNoes for return values and parameters as + // appropriate. + // + std::vector toMerge; + if (recFuncs[x].action.mergeNodes[0]) + if (isa(CI->getType())) + if (Graph->hasNodeForValue(CI)) + toMerge.push_back(Graph->getNodeForValue(CI)); + for (unsigned y = 1; y < CI->getNumOperands(); ++y) + if (recFuncs[x].action.mergeNodes[y]) + if (isa(CI->getOperand(y)->getType())) + if (Graph->hasNodeForValue(CI->getOperand(y))) + toMerge.push_back(Graph->getNodeForValue(CI->getOperand(y))); + for (unsigned y = 1; y < toMerge.size(); ++y) + toMerge[0].mergeWith(toMerge[y]); + + // + // Collapse (fold) the DSNode of the return value and the actual + // arguments if directed to do so. + // + if (!noStdLibFold && recFuncs[x].action.collapse) { + if (isa(CI->getType())){ + if (Graph->hasNodeForValue(CI)) + Graph->getNodeForValue(CI).getNode()->foldNodeCompletely(); + NumNodesFoldedInStdLib++; + } + for (unsigned y = 1; y < CI->getNumOperands(); ++y){ + if (isa(CI->getOperand(y)->getType())){ + if (Graph->hasNodeForValue(CI->getOperand(y))){ + Graph->getNodeForValue(CI->getOperand(y)).getNode()->foldNodeCompletely(); + NumNodesFoldedInStdLib++; } } - } else if (InvokeInst* CI = dyn_cast(ii)){ - if (CI->getOperand(0) == F) { + } + } + } + } else if(ConstantExpr *CE = dyn_cast(ii)) { + if(CE->isCast()) + for (Value::use_iterator ci = CE->use_begin(), ce = CE->use_end(); + ci != ce; ++ci) { + + if (CallInst* CI = dyn_cast(ci)){ + if (CI->getOperand(0) == CE) { DSGraph* Graph = getDSGraph(*CI->getParent()->getParent()); // @@ -532,13 +645,13 @@ // as appropriate. // for (unsigned y = 1; y < CI->getNumOperands(); ++y) - if (isa(CI->getOperand(y)->getType())){ - if (Graph->hasNodeForValue(CI->getOperand(y))){ - if (recFuncs[x].action.read[y]) + if (recFuncs[x].action.read[y]){ + if (isa(CI->getOperand(y)->getType())){ + if (Graph->hasNodeForValue(CI->getOperand(y))) Graph->getNodeForValue(CI->getOperand(y)).getNode()->setReadMarker(); - if (recFuncs[x].action.write[y]) + if (Graph->hasNodeForValue(CI->getOperand(y))) Graph->getNodeForValue(CI->getOperand(y)).getNode()->setModifiedMarker(); - if (recFuncs[x].action.heap[y]) + if (Graph->hasNodeForValue(CI->getOperand(y))) Graph->getNodeForValue(CI->getOperand(y)).getNode()->setHeapMarker(); } } @@ -551,9 +664,9 @@ if (recFuncs[x].action.mergeNodes[0]) if (isa(CI->getType())) if (Graph->hasNodeForValue(CI)) - toMerge.push_back(Graph->getNodeForValue(CI)); - for (unsigned y = 1; y < CI->getNumOperands(); ++y) - if (recFuncs[x].action.mergeNodes[y]) + toMerge.push_back(Graph->getNodeForValue(CI)); + for (unsigned y = 1; y < CI->getNumOperands(); ++y) + if (recFuncs[x].action.mergeNodes[y]) if (isa(CI->getOperand(y)->getType())) if (Graph->hasNodeForValue(CI->getOperand(y))) toMerge.push_back(Graph->getNodeForValue(CI->getOperand(y))); @@ -570,142 +683,33 @@ Graph->getNodeForValue(CI).getNode()->foldNodeCompletely(); NumNodesFoldedInStdLib++; } - for (unsigned y = 1; y < CI->getNumOperands(); ++y){ + for (unsigned y = 1; y < CI->getNumOperands(); ++y) if (isa(CI->getOperand(y)->getType())){ if (Graph->hasNodeForValue(CI->getOperand(y))){ - Graph->getNodeForValue(CI->getOperand(y)).getNode()->foldNodeCompletely(); + DSNode * Node=Graph->getNodeForValue(CI->getOperand(y)).getNode(); + Node->foldNodeCompletely(); NumNodesFoldedInStdLib++; } } - } } } - } else if(ConstantExpr *CE = dyn_cast(ii)) { - if(CE->isCast()) - for (Value::use_iterator ci = CE->use_begin(), ce = CE->use_end(); - ci != ce; ++ci) { - - if (CallInst* CI = dyn_cast(ci)){ - if (CI->getOperand(0) == CE) { - DSGraph* Graph = getDSGraph(*CI->getParent()->getParent()); - - // - // Set the read, write, and heap markers on the return value - // as appropriate. - // - if(isa((CI)->getType())){ - if(Graph->hasNodeForValue(CI)){ - if (recFuncs[x].action.read[0]) - Graph->getNodeForValue(CI).getNode()->setReadMarker(); - if (recFuncs[x].action.write[0]) - Graph->getNodeForValue(CI).getNode()->setModifiedMarker(); - if (recFuncs[x].action.heap[0]) - Graph->getNodeForValue(CI).getNode()->setHeapMarker(); - } - } - - // - // Set the read, write, and heap markers on the actual arguments - // as appropriate. - // - for (unsigned y = 1; y < CI->getNumOperands(); ++y) - if (recFuncs[x].action.read[y]){ - if (isa(CI->getOperand(y)->getType())){ - if (Graph->hasNodeForValue(CI->getOperand(y))) - Graph->getNodeForValue(CI->getOperand(y)).getNode()->setReadMarker(); - if (Graph->hasNodeForValue(CI->getOperand(y))) - Graph->getNodeForValue(CI->getOperand(y)).getNode()->setModifiedMarker(); - if (Graph->hasNodeForValue(CI->getOperand(y))) - Graph->getNodeForValue(CI->getOperand(y)).getNode()->setHeapMarker(); - } - } - - // - // Merge the DSNoes for return values and parameters as - // appropriate. - // - std::vector toMerge; - if (recFuncs[x].action.mergeNodes[0]) - if (isa(CI->getType())) - if (Graph->hasNodeForValue(CI)) - toMerge.push_back(Graph->getNodeForValue(CI)); - for (unsigned y = 1; y < CI->getNumOperands(); ++y) - if (recFuncs[x].action.mergeNodes[y]) - if (isa(CI->getOperand(y)->getType())) - if (Graph->hasNodeForValue(CI->getOperand(y))) - toMerge.push_back(Graph->getNodeForValue(CI->getOperand(y))); - for (unsigned y = 1; y < toMerge.size(); ++y) - toMerge[0].mergeWith(toMerge[y]); - - // - // Collapse (fold) the DSNode of the return value and the actual - // arguments if directed to do so. - // - if (!noStdLibFold && recFuncs[x].action.collapse) { - if (isa(CI->getType())){ - if (Graph->hasNodeForValue(CI)) - Graph->getNodeForValue(CI).getNode()->foldNodeCompletely(); - NumNodesFoldedInStdLib++; - } - for (unsigned y = 1; y < CI->getNumOperands(); ++y) - if (isa(CI->getOperand(y)->getType())){ - if (Graph->hasNodeForValue(CI->getOperand(y))){ - DSNode * Node=Graph->getNodeForValue(CI->getOperand(y)).getNode(); - Node->foldNodeCompletely(); - NumNodesFoldedInStdLib++; - } - } - } - } - } - } } - - // - // Pretend that this call site does not call this function anymore. - // - eraseCallsTo(F); - } - - // - // Merge return values and checked pointer values for SAFECode run-time - // checks. - // - processRuntimeCheck (M, "sc.boundscheck", 3); - processRuntimeCheck (M, "sc.boundscheckui", 3); - processRuntimeCheck (M, "sc.exactcheck2", 2); - processRuntimeCheck (M, "sc.get_actual_val", 2); + } + } // - // In the Local DSA Pass, we marked nodes passed to/returned from 'StdLib' - // functions as External because, at that point, they were. However, they no - // longer are necessarily External, and we need to update accordingly. + // Pretend that this call site does not call this function anymore. // - GlobalsGraph->computeExternalFlags(DSGraph::ResetExternal); - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (!I->isDeclaration()) { - DSGraph * G = getDSGraph(*I); - unsigned EFlags = 0 - | DSGraph::ResetExternal - | DSGraph::DontMarkFormalsExternal - | DSGraph::ProcessCallSites; - G->computeExternalFlags(EFlags); - DEBUG(G->AssertGraphOK()); - } - GlobalsGraph->computeExternalFlags(DSGraph::ProcessCallSites); - DEBUG(GlobalsGraph->AssertGraphOK()); - - return false; + eraseCallsTo(F); } - /* - functions to add - freopen - strftime - strtoul - strtol - strtoll - ctype family - open64/fopen64/lseek64 - */ + functions to add + freopen + strftime + strtoul + strtol + strtoll + ctype family + open64/fopen64/lseek64 + */ From stoklund at 2pi.dk Thu Mar 31 13:42:43 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 31 Mar 2011 18:42:43 -0000 Subject: [llvm-commits] [llvm] r128654 - in /llvm/trunk/test/CodeGen: Mips/2008-08-06-Alloca.ll Mips/2010-07-20-Select.ll Mips/cmov.ll Mips/o32_cc_vararg.ll SPARC/2011-01-11-FrameAddr.ll XCore/mul64.ll Message-ID: <20110331184243.D20752A6C12C@llvm.org> Author: stoklund Date: Thu Mar 31 13:42:43 2011 New Revision: 128654 URL: http://llvm.org/viewvc/llvm-project?rev=128654&view=rev Log: Fix Mips, Sparc, and XCore tests that were dependent on register allocation. Add an extra run with -regalloc=basic to keep them honest. Modified: llvm/trunk/test/CodeGen/Mips/2008-08-06-Alloca.ll llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll llvm/trunk/test/CodeGen/Mips/cmov.ll llvm/trunk/test/CodeGen/Mips/o32_cc_vararg.ll llvm/trunk/test/CodeGen/SPARC/2011-01-11-FrameAddr.ll llvm/trunk/test/CodeGen/XCore/mul64.ll Modified: llvm/trunk/test/CodeGen/Mips/2008-08-06-Alloca.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/2008-08-06-Alloca.ll?rev=128654&r1=128653&r2=128654&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Mips/2008-08-06-Alloca.ll (original) +++ llvm/trunk/test/CodeGen/Mips/2008-08-06-Alloca.ll Thu Mar 31 13:42:43 2011 @@ -1,4 +1,9 @@ -; RUN: llc < %s -march=mips | grep {subu.*sp} | count 2 +; RUN: llc < %s -march=mips -regalloc=linearscan | grep {subu.*sp} | count 2 + +; This test depends on a linearscan optimization, joining copies from reserved +; registers. +; After coalescing, copies from %SP remain. +; They are handled by RALinScan::attemptTrivialCoalescing target datalayout = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" target triple = "mipsallegrexel-unknown-psp-elf" Modified: llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll?rev=128654&r1=128653&r2=128654&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll (original) +++ llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll Thu Mar 31 13:42:43 2011 @@ -1,4 +1,5 @@ ; RUN: llc < %s -march=mips -relocation-model=static | FileCheck %s +; RUN: llc < %s -march=mips -relocation-model=static -regalloc=basic | FileCheck %s ; Fix PR7473 define i32 @main() nounwind readnone { @@ -9,12 +10,12 @@ volatile store i32 0, i32* %c, align 4 %0 = volatile load i32* %a, align 4 ; [#uses=1] %1 = icmp eq i32 %0, 0 ; [#uses=1] -; CHECK: addiu $4, $zero, 0 +; CHECK: addiu $[[R1:[0-9]+]], $zero, 0 %iftmp.0.0 = select i1 %1, i32 3, i32 0 ; [#uses=1] %2 = volatile load i32* %c, align 4 ; [#uses=1] %3 = icmp eq i32 %2, 0 ; [#uses=1] -; CHECK: addiu $4, $zero, 3 -; CHECK: addu $2, $3, $4 +; CHECK: addiu $[[R1]], $zero, 3 +; CHECK: addu $2, ${{.}}, $[[R1]] %iftmp.2.0 = select i1 %3, i32 0, i32 5 ; [#uses=1] %4 = add nsw i32 %iftmp.2.0, %iftmp.0.0 ; [#uses=1] ret i32 %4 Modified: llvm/trunk/test/CodeGen/Mips/cmov.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/cmov.ll?rev=128654&r1=128653&r2=128654&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Mips/cmov.ll (original) +++ llvm/trunk/test/CodeGen/Mips/cmov.ll Thu Mar 31 13:42:43 2011 @@ -1,10 +1,11 @@ ; RUN: llc -march=mips -mcpu=4ke < %s | FileCheck %s +; RUN: llc -march=mips -mcpu=4ke -regalloc=basic < %s | FileCheck %s @i1 = global [3 x i32] [i32 1, i32 2, i32 3], align 4 @i3 = common global i32* null, align 4 -; CHECK: lw $3, %got(i3)($gp) -; CHECK: addiu $5, $gp, %got(i1) +; CHECK: lw ${{[0-9]+}}, %got(i3)($gp) +; CHECK: addiu ${{[0-9]+}}, $gp, %got(i1) define i32* @cmov1(i32 %s) nounwind readonly { entry: %tobool = icmp ne i32 %s, 0 Modified: llvm/trunk/test/CodeGen/Mips/o32_cc_vararg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/o32_cc_vararg.ll?rev=128654&r1=128653&r2=128654&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Mips/o32_cc_vararg.ll (original) +++ llvm/trunk/test/CodeGen/Mips/o32_cc_vararg.ll Thu Mar 31 13:42:43 2011 @@ -1,4 +1,5 @@ ; RUN: llc -march=mipsel -mcpu=mips2 < %s | FileCheck %s +; RUN: llc -march=mipsel -mcpu=mips2 < %s -regalloc=basic | FileCheck %s ; All test functions do the same thing - they return the first variable @@ -56,14 +57,14 @@ ; CHECK: va2: ; CHECK: addiu $sp, $sp, -40 -; CHECK: addiu $2, $sp, 44 +; CHECK: addiu $[[R0:[0-9]+]], $sp, 44 ; CHECK: sw $5, 44($sp) ; CHECK: sw $6, 48($sp) ; CHECK: sw $7, 52($sp) -; CHECK: addiu $3, $2, 7 -; CHECK: addiu $5, $zero, -8 -; CHECK: and $3, $3, $5 -; CHECK: ldc1 $f0, 0($3) +; CHECK: addiu $[[R1:[0-9]+]], $[[R0]], 7 +; CHECK: addiu $[[R2:[0-9]+]], $zero, -8 +; CHECK: and $[[R3:[0-9]+]], $[[R1]], $[[R2]] +; CHECK: ldc1 $f0, 0($[[R3]]) } ; int @@ -109,11 +110,11 @@ ; CHECK: addiu $sp, $sp, -48 ; CHECK: sw $6, 56($sp) ; CHECK: sw $7, 60($sp) -; CHECK: addiu $3, $sp, 56 -; CHECK: addiu $6, $3, 7 -; CHECK: addiu $7, $zero, -8 -; CHECK: and $2, $6, $7 -; CHECK: ldc1 $f0, 0($2) +; CHECK: addiu $[[R0:[0-9]+]], $sp, 56 +; CHECK: addiu $[[R1:[0-9]+]], $[[R0]], 7 +; CHECK: addiu $[[R2:[0-9]+]], $zero, -8 +; CHECK: and $[[R3:[0-9]+]], $[[R1]], $[[R2]] +; CHECK: ldc1 $f0, 0($[[R3]]) } ; int @@ -165,11 +166,11 @@ ; CHECK: va6: ; CHECK: addiu $sp, $sp, -48 ; CHECK: sw $7, 60($sp) -; CHECK: addiu $2, $sp, 60 -; CHECK: addiu $3, $2, 7 -; CHECK: addiu $4, $zero, -8 -; CHECK: and $3, $3, $4 -; CHECK: ldc1 $f0, 0($3) +; CHECK: addiu $[[R0:[0-9]+]], $sp, 60 +; CHECK: addiu $[[R1:[0-9]+]], $[[R0]], 7 +; CHECK: addiu $[[R2:[0-9]+]], $zero, -8 +; CHECK: and $[[R3:[0-9]+]], $[[R1]], $[[R2]] +; CHECK: ldc1 $f0, 0($[[R3]]) } ; int @@ -215,11 +216,11 @@ ; CHECK: va8: ; CHECK: addiu $sp, $sp, -48 -; CHECK: addiu $3, $sp, 64 -; CHECK: addiu $4, $3, 7 -; CHECK: addiu $5, $zero, -8 -; CHECK: and $2, $4, $5 -; CHECK: ldc1 $f0, 0($2) +; CHECK: addiu $[[R0:[0-9]+]], $sp, 64 +; CHECK: addiu $[[R1:[0-9]+]], $[[R0]], 7 +; CHECK: addiu $[[R2:[0-9]+]], $zero, -8 +; CHECK: and $[[R3:[0-9]+]], $[[R1]], $[[R2]] +; CHECK: ldc1 $f0, 0($[[R3]]) } ; int @@ -269,9 +270,9 @@ ; CHECK: va10: ; CHECK: addiu $sp, $sp, -56 -; CHECK: addiu $3, $sp, 76 -; CHECK: addiu $2, $3, 7 -; CHECK: addiu $4, $zero, -8 -; CHECK: and $2, $2, $4 -; CHECK: ldc1 $f0, 0($2) +; CHECK: addiu $[[R0:[0-9]+]], $sp, 76 +; CHECK: addiu $[[R1:[0-9]+]], $[[R0]], 7 +; CHECK: addiu $[[R2:[0-9]+]], $zero, -8 +; CHECK: and $[[R3:[0-9]+]], $[[R1]], $[[R2]] +; CHECK: ldc1 $f0, 0($[[R3]]) } Modified: llvm/trunk/test/CodeGen/SPARC/2011-01-11-FrameAddr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SPARC/2011-01-11-FrameAddr.ll?rev=128654&r1=128653&r2=128654&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/SPARC/2011-01-11-FrameAddr.ll (original) +++ llvm/trunk/test/CodeGen/SPARC/2011-01-11-FrameAddr.ll Thu Mar 31 13:42:43 2011 @@ -1,5 +1,7 @@ -;RUN: llc -march=sparc < %s | FileCheck %s -check-prefix=V8 -;RUN: llc -march=sparc -mattr=v9 < %s | FileCheck %s -check-prefix=V9 +;RUN: llc -march=sparc -regalloc=linearscan < %s | FileCheck %s -check-prefix=V8 +;RUN: llc -march=sparc -regalloc=linearscan -mattr=v9 < %s | FileCheck %s -check-prefix=V9 + +; These tests depend on linear scan's trivial coalescer for reserved registers. define i8* @frameaddr() nounwind readnone { entry: Modified: llvm/trunk/test/CodeGen/XCore/mul64.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/mul64.ll?rev=128654&r1=128653&r2=128654&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/mul64.ll (original) +++ llvm/trunk/test/CodeGen/XCore/mul64.ll Thu Mar 31 13:42:43 2011 @@ -1,4 +1,5 @@ ; RUN: llc < %s -march=xcore | FileCheck %s +; RUN: llc < %s -march=xcore -regalloc=basic | FileCheck %s define i64 @umul_lohi(i32 %a, i32 %b) { entry: %0 = zext i32 %a to i64 @@ -7,8 +8,8 @@ ret i64 %2 } ; CHECK: umul_lohi: -; CHECK: ldc r2, 0 -; CHECK-NEXT: lmul r1, r0, r1, r0, r2, r2 +; CHECK: ldc [[REG:r[0-9]+]], 0 +; CHECK-NEXT: lmul r1, r0, r1, r0, [[REG]], [[REG]] ; CHECK-NEXT: retsp 0 define i64 @smul_lohi(i32 %a, i32 %b) { @@ -19,11 +20,11 @@ ret i64 %2 } ; CHECK: smul_lohi: -; CHECK: ldc r2, 0 -; CHECK-NEXT: mov r3, r2 -; CHECK-NEXT: maccs r2, r3, r1, r0 -; CHECK-NEXT: mov r0, r3 -; CHECK-NEXT: mov r1, r2 +; CHECK: ldc +; CHECK-NEXT: mov +; CHECK-NEXT: maccs +; CHECK-NEXT: mov r0, +; CHECK-NEXT: mov r1, ; CHECK-NEXT: retsp 0 define i64 @mul64(i64 %a, i64 %b) { @@ -32,11 +33,11 @@ ret i64 %0 } ; CHECK: mul64: -; CHECK: ldc r11, 0 -; CHECK-NEXT: lmul r11, r4, r0, r2, r11, r11 -; CHECK-NEXT: mul r0, r0, r3 -; CHECK-NEXT: lmul r0, r1, r1, r2, r11, r0 -; CHECK-NEXT: mov r0, r4 +; CHECK: ldc +; CHECK-NEXT: lmul +; CHECK-NEXT: mul +; CHECK-NEXT: lmul +; CHECK-NEXT: mov r0, define i64 @mul64_2(i64 %a, i32 %b) { entry: @@ -45,8 +46,8 @@ ret i64 %1 } ; CHECK: mul64_2: -; CHECK: ldc r3, 0 -; CHECK-NEXT: lmul r3, r0, r0, r2, r3, r3 -; CHECK-NEXT: mul r1, r1, r2 -; CHECK-NEXT: add r1, r3, r1 +; CHECK: ldc +; CHECK-NEXT: lmul +; CHECK-NEXT: mul +; CHECK-NEXT: add r1, ; CHECK-NEXT: retsp 0 From aggarwa4 at illinois.edu Thu Mar 31 13:43:44 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 31 Mar 2011 18:43:44 -0000 Subject: [llvm-commits] [poolalloc] r128655 - in /poolalloc/trunk: include/dsa/DataStructure.h lib/DSA/StdLibPass.cpp Message-ID: <20110331184344.32B592A6C12C@llvm.org> Author: aggarwa4 Date: Thu Mar 31 13:43:43 2011 New Revision: 128655 URL: http://llvm.org/viewvc/llvm-project?rev=128655&view=rev Log: Make stdLib pass use the allocator wrapper info. Modified: poolalloc/trunk/include/dsa/DataStructure.h poolalloc/trunk/lib/DSA/StdLibPass.cpp Modified: poolalloc/trunk/include/dsa/DataStructure.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DataStructure.h?rev=128655&r1=128654&r2=128655&view=diff ============================================================================== --- poolalloc/trunk/include/dsa/DataStructure.h (original) +++ poolalloc/trunk/include/dsa/DataStructure.h Thu Mar 31 13:43:43 2011 @@ -23,6 +23,7 @@ #include "dsa/svset.h" #include "dsa/super_set.h" #include "dsa/AddressTakenAnalysis.h" +#include "dsa/AllocatorIdentification.h" #include @@ -197,6 +198,8 @@ class StdLibDataStructures : public DataStructures { void eraseCallsTo(Function* F); void processRuntimeCheck (Module & M, std::string name, unsigned arg); + void processFunction(int x, Function *F); + AllocIdentify *AllocWrappersAnalysis; public: static char ID; StdLibDataStructures() : DataStructures((intptr_t)&ID, "stdlib.") {} @@ -208,6 +211,7 @@ /// virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); + AU.addRequired(); AU.setPreservesAll(); } }; Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/StdLibPass.cpp?rev=128655&r1=128654&r2=128655&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original) +++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Thu Mar 31 13:43:43 2011 @@ -12,6 +12,7 @@ #include "llvm/ADT/Statistic.h" #include "dsa/DataStructure.h" +#include "dsa/AllocatorIdentification.h" #include "dsa/DSGraph.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" @@ -392,6 +393,7 @@ // Get the results from the local pass. // init (&getAnalysis(), true, true, false, false); + AllocWrappersAnalysis = &getAnalysis(); // // Fetch the DSGraphs for all defined functions within the module. @@ -437,6 +439,32 @@ processFunction(x, F); } + std::set::iterator ai = AllocWrappersAnalysis->alloc_begin(); + std::set::iterator ae = AllocWrappersAnalysis->alloc_end(); + int x; + for (x = 0; recFuncs[x].name; ++x) { + if(recFuncs[x].name == "malloc") + break; + } + + for(;ai != ae; ++ai) { + if(Function* F = M.getFunction(*ai)) + processFunction(x, F); + } + + ai = AllocWrappersAnalysis->dealloc_begin(); + ae = AllocWrappersAnalysis->dealloc_end(); + for (x = 0; recFuncs[x].name; ++x) { + if(recFuncs[x].name == "free") + break; + } + + for(;ai != ae; ++ai) { + errs() << *ai << "\n"; + if(Function* F = M.getFunction(*ai)) + processFunction(x, F); + } + // // Merge return values and checked pointer values for SAFECode run-time // checks. From stoklund at 2pi.dk Thu Mar 31 13:48:41 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 31 Mar 2011 11:48:41 -0700 Subject: [llvm-commits] [llvm] r128650 - in /llvm/trunk: lib/Target/Mips/MipsISelLowering.cpp lib/Target/Mips/MipsISelLowering.h lib/Target/Mips/MipsInstrFPU.td lib/Target/Mips/MipsInstrFormats.td lib/Target/Mips/MipsInstrInfo.cpp lib/Target/Mips/MipsInstrInfo.h lib/Target/Mips/MipsInstrInfo.td test/CodeGen/Mips/2008-07-23-fpcmp.ll test/CodeGen/Mips/2008-07-29-icmp.ll test/CodeGen/Mips/2010-07-20-Select.ll test/CodeGen/Mips/fpbr.ll test/CodeGen/Mips/fpcmp.ll test/CodeGen/Mips/select.ll In-Reply-To: <20110331182617.9BF4D2A6C12C@llvm.org> References: <20110331182617.9BF4D2A6C12C@llvm.org> Message-ID: On Mar 31, 2011, at 11:26 AM, Akira Hatanaka wrote: > Modified: llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll?rev=128650&r1=128649&r2=128650&view=diff > ============================================================================== > --- llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll (original) > +++ llvm/trunk/test/CodeGen/Mips/2010-07-20-Select.ll Thu Mar 31 13:26:17 2011 > @@ -9,12 +9,12 @@ > volatile store i32 0, i32* %c, align 4 > %0 = volatile load i32* %a, align 4 ; [#uses=1] > %1 = icmp eq i32 %0, 0 ; [#uses=1] > -; CHECK: addiu $3, $zero, 0 > +; CHECK: addiu $4, $zero, 0 > %iftmp.0.0 = select i1 %1, i32 3, i32 0 ; [#uses=1] > %2 = volatile load i32* %c, align 4 ; [#uses=1] > %3 = icmp eq i32 %2, 0 ; [#uses=1] > -; CHECK: addiu $3, $zero, 3 > -; CHECK: addu $2, $5, $3 > +; CHECK: addiu $4, $zero, 3 > +; CHECK: addu $2, $3, $4 > %iftmp.2.0 = select i1 %3, i32 0, i32 5 ; [#uses=1] > %4 = add nsw i32 %iftmp.2.0, %iftmp.0.0 ; [#uses=1] > ret i32 %4 Please don't write tests that depend on arbitrary register allocation choices. Use FileCheck patterns instead. I just fixed this one in r128654. /jakob From aggarwa4 at illinois.edu Thu Mar 31 13:44:35 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 31 Mar 2011 18:44:35 -0000 Subject: [llvm-commits] [poolalloc] r128657 - /poolalloc/trunk/include/dsa/DSNode.h Message-ID: <20110331184435.E83BC2A6C12C@llvm.org> Author: aggarwa4 Date: Thu Mar 31 13:44:35 2011 New Revision: 128657 URL: http://llvm.org/viewvc/llvm-project?rev=128657&view=rev Log: Consistently name DSNodeHandles as NH Modified: poolalloc/trunk/include/dsa/DSNode.h Modified: poolalloc/trunk/include/dsa/DSNode.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSNode.h?rev=128657&r1=128656&r2=128657&view=diff ============================================================================== --- poolalloc/trunk/include/dsa/DSNode.h (original) +++ poolalloc/trunk/include/dsa/DSNode.h Thu Mar 31 13:44:35 2011 @@ -14,16 +14,18 @@ #ifndef LLVM_ANALYSIS_DSNODE_H #define LLVM_ANALYSIS_DSNODE_H -#include "dsa/DSSupport.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/ilist_node.h" - -#include -#include +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" #include "dsa/svset.h" #include "dsa/super_set.h" #include "dsa/keyiterator.h" #include "dsa/DSGraph.h" +#include "dsa/DSSupport.h" + +#include +#include namespace llvm { @@ -237,7 +239,6 @@ /// completely (and return true) if the information is incompatible with what /// is already known. /// - /// FIXME: description void mergeTypeInfo(const Type *Ty, unsigned Offset); void mergeTypeInfo(const TyMapTy::mapped_type TyIt, unsigned Offset); void mergeTypeInfo(const DSNode* D, unsigned Offset); @@ -495,21 +496,21 @@ /// addEdgeTo - Add an edge from the current node to the specified node. This /// can cause merging of nodes in the graph. /// -inline void DSNodeHandle::addEdgeTo(unsigned Off, const DSNodeHandle &Node) { +inline void DSNodeHandle::addEdgeTo(unsigned Off, const DSNodeHandle &NH) { assert(N && "DSNodeHandle does not point to a node yet!"); - getNode()->addEdgeTo(Off+Offset, Node); + getNode()->addEdgeTo(Off+Offset, NH); } /// mergeWith - Merge the logical node pointed to by 'this' with the node /// pointed to by 'N'. /// -inline void DSNodeHandle::mergeWith(const DSNodeHandle &Node) const { +inline void DSNodeHandle::mergeWith(const DSNodeHandle &NH) const { if (!isNull()) - getNode()->mergeWith(Node, Offset); + getNode()->mergeWith(NH, Offset); else { // No node to merge with, so just point to Node Offset = 0; - DSNode *NN = Node.getNode(); - setTo(NN, Node.getOffset()); + DSNode *N = NH.getNode(); + setTo(N, NH.getOffset()); } } From wdietz2 at illinois.edu Thu Mar 31 13:53:37 2011 From: wdietz2 at illinois.edu (Will Dietz) Date: Thu, 31 Mar 2011 18:53:37 -0000 Subject: [llvm-commits] [poolalloc] r128658 - /poolalloc/trunk/lib/DSA/StdLibPass.cpp Message-ID: <20110331185337.AAB752A6C12C@llvm.org> Author: wdietz2 Date: Thu Mar 31 13:53:37 2011 New Revision: 128658 URL: http://llvm.org/viewvc/llvm-project?rev=128658&view=rev Log: Fix comparison on string literals by converting to std::string first. Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/StdLibPass.cpp?rev=128658&r1=128657&r2=128658&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original) +++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Thu Mar 31 13:53:37 2011 @@ -443,7 +443,7 @@ std::set::iterator ae = AllocWrappersAnalysis->alloc_end(); int x; for (x = 0; recFuncs[x].name; ++x) { - if(recFuncs[x].name == "malloc") + if(recFuncs[x].name == std::string("malloc")) break; } @@ -455,7 +455,7 @@ ai = AllocWrappersAnalysis->dealloc_begin(); ae = AllocWrappersAnalysis->dealloc_end(); for (x = 0; recFuncs[x].name; ++x) { - if(recFuncs[x].name == "free") + if(recFuncs[x].name == std::string("free")) break; } From wdietz2 at illinois.edu Thu Mar 31 13:54:07 2011 From: wdietz2 at illinois.edu (Will Dietz) Date: Thu, 31 Mar 2011 18:54:07 -0000 Subject: [llvm-commits] [poolalloc] r128659 - /poolalloc/trunk/lib/DSA/StdLibPass.cpp Message-ID: <20110331185407.C85E42A6C12C@llvm.org> Author: wdietz2 Date: Thu Mar 31 13:54:07 2011 New Revision: 128659 URL: http://llvm.org/viewvc/llvm-project?rev=128659&view=rev Log: Remove debugging line. Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/StdLibPass.cpp?rev=128659&r1=128658&r2=128659&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original) +++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Thu Mar 31 13:54:07 2011 @@ -451,7 +451,7 @@ if(Function* F = M.getFunction(*ai)) processFunction(x, F); } - + ai = AllocWrappersAnalysis->dealloc_begin(); ae = AllocWrappersAnalysis->dealloc_end(); for (x = 0; recFuncs[x].name; ++x) { @@ -460,7 +460,6 @@ } for(;ai != ae; ++ai) { - errs() << *ai << "\n"; if(Function* F = M.getFunction(*ai)) processFunction(x, F); } From bruno.cardoso at gmail.com Thu Mar 31 14:17:22 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Thu, 31 Mar 2011 16:17:22 -0300 Subject: [llvm-commits] [llvm] r128635 - in /llvm/trunk: lib/Target/ARM/ARMAddressingModes.h lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmPar In-Reply-To: References: Message-ID: Hi Jim, > I'm glad to see you're looking at this. Hopefully the bugs won't be too hard to track down. Also really nice to hear back from you. > If you're feeling ambitious, addrmode2 is on its way out in favor of addrmode_imm12 and ldst_so_reg. Specifically, addrmode2 conflates the immediate and register addressing and modally indicates which of the two it's defining by the second register operand being zero. This, as I'm sure you've encountered, gives the asm parser all sorts of fun to deal with, as there are operands that aren't part of the assembly syntax and aren't easily inferable without custom handling. Splitting the operand into parts has two major benefits. First, it helps with the above by making the instruction definition only have machine operands which are actually part of the real instructions. Second, the different addressing modes typically have a different scheduling itinerary, and that's not expressive with a combined addressing mode construct. The AI_ldr1 multiclass, used by the base LDR instructions, has an example of how this works. Interesting. It's indeed a good idea. > When you get to doing parsing for the _PRE/_POST instructions that do have associated patterns, there's some complications due to the writeback tied register constraint. The best way we have to represent that right now, albeit kinda ugly, is to use a pseudo-instruction for the code-gen that has the writeback output operand tied to the source base reg, and an assembler-only real instruction (which has the encoding information) that doesn't have an explicit output writeback operand, just the source base operand. The ARMAsmPrinter MC lowering pseudo-expansion would lower the former to the latter. Ok. I see it now. I'll try to leave the LDR instructions for a next patch if that is possible, so I can address them better. Thanks for the explanation. -- Bruno Cardoso Lopes http://www.brunocardoso.cc From bruno.cardoso at gmail.com Thu Mar 31 14:18:18 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Thu, 31 Mar 2011 16:18:18 -0300 Subject: [llvm-commits] [llvm] r128635 - in /llvm/trunk: lib/Target/ARM/ARMAddressingModes.h lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmPar In-Reply-To: References: Message-ID: Hi Daniel, > FYI, you removed all the contents of arm_addrmode2.s, but didn't > remove the file. This means the test will fail, because it is empty. Thank you, and sorry for the noise! :) -- Bruno Cardoso Lopes http://www.brunocardoso.cc From jan_sjodin at yahoo.com Thu Mar 31 14:25:37 2011 From: jan_sjodin at yahoo.com (Jan Sjodin) Date: Thu, 31 Mar 2011 12:25:37 -0700 (PDT) Subject: [llvm-commits] Fw: Change DwarfUsesAbsoluteLabelForStmtList to false for X86ELFMCAsmInfo. In-Reply-To: References: <504570.72198.qm@web55608.mail.re4.yahoo.com> <687867.19021.qm@web55607.mail.re4.yahoo.com> <201822.31535.qm@web55606.mail.re4.yahoo.com> Message-ID: <701472.85253.qm@web55604.mail.re4.yahoo.com> Forgot to add llvm-commits. ----- Forwarded Message ---- > From: Jan Sjodin > To: Devang Patel ; Renato Golin > Cc: Anton Korobeynikov > Sent: Thu, March 31, 2011 3:06:55 PM > Subject: Re: [llvm-commits] Change DwarfUsesAbsoluteLabelForStmtList to false >for X86ELFMCAsmInfo. > > Here is the patch to rename the flag. > > I will follow up with a few patches to clean up the code. IMO > isBaseAddressKnownZero() method in MCSection should be removed and the single > use in EmitSectionOffset should be replaced with a check against > doesDwarfUsesAbsoluteLabelForSectionOffset(). > > - Jan > > > ----- Original Message ---- > > From: Devang Patel > > To: Renato Golin > > Cc: Jan Sjodin ; Anton Korobeynikov > > > > Sent: Mon, March 28, 2011 11:58:05 AM > > Subject: Re: [llvm-commits] Change DwarfUsesAbsoluteLabelForStmtList to >false > > >for X86ELFMCAsmInfo. > > > > > > On Mar 28, 2011, at 1:25 AM, Renato Golin wrote: > > > > > 2. Set DwarfUsesAbsoluteLabelForStmtList = true and do the check here. > > > > I'd use this approach, Feel free to rename the flag appropriately. > > - > > Devang > > -------------- next part -------------- A non-text attachment was scrubbed... Name: 0049_absolutlabelrename.patch Type: application/octet-stream Size: 3036 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110331/5b385473/attachment.obj From johnny.chen at apple.com Thu Mar 31 14:28:35 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 31 Mar 2011 19:28:35 -0000 Subject: [llvm-commits] [llvm] r128662 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td test/MC/Disassembler/ARM/invalid-LDRrs-arm.txt Message-ID: <20110331192836.0D8842A6C12C@llvm.org> Author: johnny Date: Thu Mar 31 14:28:35 2011 New Revision: 128662 URL: http://llvm.org/viewvc/llvm-project?rev=128662&view=rev Log: Fix single word and unsigned byte data transfer instruction encodings so that Inst{4} = 0. rdar://problem/9213022 Added: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRrs-arm.txt Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128662&r1=128661&r2=128662&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Mar 31 14:28:35 2011 @@ -991,6 +991,7 @@ [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> { bits<4> Rt; bits<17> shift; + let shift{4} = 0; // Inst{4} = 0 let Inst{23} = shift{12}; // U (add = ('U' == 1)) let Inst{19-16} = shift{16-13}; // Rn let Inst{15-12} = Rt; @@ -1020,6 +1021,7 @@ [(opnode GPR:$Rt, ldst_so_reg:$shift)]> { bits<4> Rt; bits<17> shift; + let shift{4} = 0; // Inst{4} = 0 let Inst{23} = shift{12}; // U (add = ('U' == 1)) let Inst{19-16} = shift{16-13}; // Rn let Inst{15-12} = Rt; Added: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRrs-arm.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRrs-arm.txt?rev=128662&view=auto ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRrs-arm.txt (added) +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRrs-arm.txt Thu Mar 31 14:28:35 2011 @@ -0,0 +1,4 @@ +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} + +# LDR (register) has encoding Inst{4} = 0. +0xba 0xae 0x9f 0x57 From evan.cheng at apple.com Thu Mar 31 14:38:48 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 31 Mar 2011 19:38:48 -0000 Subject: [llvm-commits] [llvm] r128665 - in /llvm/trunk: lib/Target/ARM/ARM.td lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMSubtarget.h test/CodeGen/ARM/vmul.ll Message-ID: <20110331193848.D9AB92A6C12C@llvm.org> Author: evancheng Date: Thu Mar 31 14:38:48 2011 New Revision: 128665 URL: http://llvm.org/viewvc/llvm-project?rev=128665&view=rev Log: Distribute (A + B) * C to (A * C) + (B * C) to make use of NEON multiplier accumulator forwarding: vadd d3, d0, d1 vmul d3, d3, d2 => vmul d3, d0, d2 vmla d3, d1, d2 Modified: llvm/trunk/lib/Target/ARM/ARM.td llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMSubtarget.h llvm/trunk/test/CodeGen/ARM/vmul.ll Modified: llvm/trunk/lib/Target/ARM/ARM.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARM.td?rev=128665&r1=128664&r2=128665&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARM.td (original) +++ llvm/trunk/lib/Target/ARM/ARM.td Thu Mar 31 14:38:48 2011 @@ -51,6 +51,12 @@ // to just not use them. def FeatureHasSlowFPVMLx : SubtargetFeature<"slowfpvmlx", "SlowFPVMLx", "true", "Disable VFP / NEON MAC instructions">; + +// Cortex-A8 / A9 Advanced SIMD has multiplier accumulator forwarding. +def FeatureVMLxForwarding : SubtargetFeature<"vmlx-forwarding", + "HasVMLxForwarding", "true", + "Has multiplier accumulator forwarding">; + // Some processors benefit from using NEON instructions for scalar // single-precision FP operations. def FeatureNEONForFP : SubtargetFeature<"neonfp", "UseNEONForSinglePrecisionFP", @@ -100,11 +106,12 @@ def ProcA8 : SubtargetFeature<"a8", "ARMProcFamily", "CortexA8", "Cortex-A8 ARM processors", [FeatureSlowFPBrcc, FeatureNEONForFP, - FeatureHasSlowFPVMLx, FeatureT2XtPk]>; + FeatureHasSlowFPVMLx, FeatureVMLxForwarding, + FeatureT2XtPk]>; def ProcA9 : SubtargetFeature<"a9", "ARMProcFamily", "CortexA9", "Cortex-A9 ARM processors", - [FeatureHasSlowFPVMLx, FeatureT2XtPk, - FeatureFP16]>; + [FeatureHasSlowFPVMLx, FeatureVMLxForwarding, + FeatureT2XtPk, FeatureFP16]>; class ProcNoItin Features> : Processor; Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=128665&r1=128664&r2=128665&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu Mar 31 14:38:48 2011 @@ -5224,6 +5224,42 @@ return SDValue(); } +/// PerformVMULCombine +/// Distribute (A + B) * C to (A * C) + (B * C) to take advantage of the +/// special multiplier accumulator forwarding. +/// vmul d3, d0, d2 +/// vmla d3, d1, d2 +/// is faster than +/// vadd d3, d0, d1 +/// vmul d3, d3, d2 +static SDValue PerformVMULCombine(SDNode *N, + TargetLowering::DAGCombinerInfo &DCI, + const ARMSubtarget *Subtarget) { + if (!Subtarget->hasVMLxForwarding()) + return SDValue(); + + SelectionDAG &DAG = DCI.DAG; + SDValue N0 = N->getOperand(0); + SDValue N1 = N->getOperand(1); + unsigned Opcode = N0.getOpcode(); + if (Opcode != ISD::ADD && Opcode != ISD::SUB && + Opcode != ISD::FADD && Opcode != ISD::FSUB) { + Opcode = N0.getOpcode(); + if (Opcode != ISD::ADD && Opcode != ISD::SUB && + Opcode != ISD::FADD && Opcode != ISD::FSUB) + return SDValue(); + std::swap(N0, N1); + } + + EVT VT = N->getValueType(0); + DebugLoc DL = N->getDebugLoc(); + SDValue N00 = N0->getOperand(0); + SDValue N01 = N0->getOperand(1); + return DAG.getNode(Opcode, DL, VT, + DAG.getNode(ISD::MUL, DL, VT, N00, N1), + DAG.getNode(ISD::MUL, DL, VT, N01, N1)); +} + static SDValue PerformMULCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget) { @@ -5236,6 +5272,8 @@ return SDValue(); EVT VT = N->getValueType(0); + if (VT.is64BitVector() || VT.is128BitVector()) + return PerformVMULCombine(N, DCI, Subtarget); if (VT != MVT::i32) return SDValue(); Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=128665&r1=128664&r2=128665&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Thu Mar 31 14:38:48 2011 @@ -61,6 +61,10 @@ /// whether the FP VML[AS] instructions are slow (if so, don't use them). bool SlowFPVMLx; + /// HasVMLxForwarding - If true, NEON has special multiplier accumulator + /// forwarding to allow mul + mla being issued back to back. + bool HasVMLxForwarding; + /// SlowFPBrcc - True if floating point compare + branch is slow. bool SlowFPBrcc; @@ -182,6 +186,7 @@ bool hasT2ExtractPack() const { return HasT2ExtractPack; } bool hasDataBarrier() const { return HasDataBarrier; } bool useFPVMLx() const { return !SlowFPVMLx; } + bool hasVMLxForwarding() const { return HasVMLxForwarding; } bool isFPBrccSlow() const { return SlowFPBrcc; } bool isFPOnlySP() const { return FPOnlySP; } bool prefers32BitThumb() const { return Pref32BitThumb; } Modified: llvm/trunk/test/CodeGen/ARM/vmul.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vmul.ll?rev=128665&r1=128664&r2=128665&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vmul.ll (original) +++ llvm/trunk/test/CodeGen/ARM/vmul.ll Thu Mar 31 14:38:48 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s +; RUN: llc < %s -march=arm -mcpu=cortex-a8 | FileCheck %s define <8 x i8> @vmuli8(<8 x i8>* %A, <8 x i8>* %B) nounwind { ;CHECK: vmuli8: @@ -466,3 +466,29 @@ declare <16 x i8> @llvm.arm.neon.vld1.v16i8(i8*, i32) nounwind readonly declare void @llvm.arm.neon.vst1.v8i16(i8*, <8 x i16>, i32) nounwind + +; Take advantage of the Cortex-A8 multiplier accumulator forward. + +%struct.uint8x8_t = type { <8 x i8> } + +define void @distribue2(%struct.uint8x8_t* nocapture %dst, i8* %src, i32 %mul) nounwind { +entry: +; CHECK: distribue2 +; CHECK-NOT: vadd.i8 +; CHECK: vmul.i8 +; CHECK: vmla.i8 + %0 = trunc i32 %mul to i8 + %1 = insertelement <8 x i8> undef, i8 %0, i32 0 + %2 = shufflevector <8 x i8> %1, <8 x i8> undef, <8 x i32> zeroinitializer + %3 = tail call <16 x i8> @llvm.arm.neon.vld1.v16i8(i8* %src, i32 1) + %4 = bitcast <16 x i8> %3 to <2 x double> + %5 = extractelement <2 x double> %4, i32 1 + %6 = bitcast double %5 to <8 x i8> + %7 = extractelement <2 x double> %4, i32 0 + %8 = bitcast double %7 to <8 x i8> + %9 = add <8 x i8> %6, %8 + %10 = mul <8 x i8> %9, %2 + %11 = getelementptr inbounds %struct.uint8x8_t* %dst, i32 0, i32 0 + store <8 x i8> %10, <8 x i8>* %11, align 8 + ret void +} From eli.friedman at gmail.com Thu Mar 31 15:14:00 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Thu, 31 Mar 2011 13:14:00 -0700 Subject: [llvm-commits] [llvm] r128625 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCompares.cpp test/Transforms/InstCombine/fcmp.ll In-Reply-To: <20110331101207.B02362A6C12C@llvm.org> References: <20110331101207.B02362A6C12C@llvm.org> Message-ID: On Thu, Mar 31, 2011 at 3:12 AM, Benjamin Kramer wrote: > Author: d0k > Date: Thu Mar 31 05:12:07 2011 > New Revision: 128625 > > URL: http://llvm.org/viewvc/llvm-project?rev=128625&view=rev > Log: > InstCombine: Shrink "fcmp (fpext x), C" to "fcmp x, C" if C can be losslessly converted to the type of x. > > Fixes PR9592. > > Modified: > ? ?llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp > ? ?llvm/trunk/test/Transforms/InstCombine/fcmp.ll > > Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=128625&r1=128624&r2=128625&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original) > +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu Mar 31 05:12:07 2011 > @@ -2762,6 +2762,40 @@ > ? if (Constant *RHSC = dyn_cast(Op1)) { > ? ? if (Instruction *LHSI = dyn_cast(Op0)) > ? ? ? switch (LHSI->getOpcode()) { > + ? ? ?case Instruction::FPExt: { > + ? ? ? ?// fcmp (fpext x), C -> fcmp x, (fptrunc C) if fptrunc is lossless > + ? ? ? ?FPExtInst *LHSExt = cast(LHSI); > + ? ? ? ?ConstantFP *RHSF = dyn_cast(RHSC); > + ? ? ? ?if (!RHSF) > + ? ? ? ? ?break; > + > + ? ? ? ?const fltSemantics *Sem; > + ? ? ? ?// FIXME: This shouldn't be here. > + ? ? ? ?if (LHSExt->getSrcTy()->isFloatTy()) > + ? ? ? ? ?Sem = &APFloat::IEEEsingle; > + ? ? ? ?else if (LHSExt->getSrcTy()->isDoubleTy()) > + ? ? ? ? ?Sem = &APFloat::IEEEdouble; > + ? ? ? ?else if (LHSExt->getSrcTy()->isFP128Ty()) > + ? ? ? ? ?Sem = &APFloat::IEEEquad; > + ? ? ? ?else if (LHSExt->getSrcTy()->isX86_FP80Ty()) > + ? ? ? ? ?Sem = &APFloat::x87DoubleExtended; > + ? ? ? ?else if (LHSExt->getSrcTy()->isPPC_FP128Ty()) > + ? ? ? ? ?Sem = &APFloat::PPCDoubleDouble; > + ? ? ? ?else > + ? ? ? ? ?break; Trying this transformation on APFloat::PPCDoubleDouble is likely to cause bad things to happen. -Eli > + ? ? ? ?bool Lossy; > + ? ? ? ?APFloat F = RHSF->getValueAPF(); > + ? ? ? ?F.convert(*Sem, APFloat::rmNearestTiesToEven, &Lossy); > + > + ? ? ? ?// Avoid lossy conversions and denormals. > + ? ? ? ?if (!Lossy && > + ? ? ? ? ? ?F.compare(APFloat::getSmallestNormalized(*Sem)) != > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? APFloat::cmpLessThan) > + ? ? ? ? ?return new FCmpInst(I.getPredicate(), LHSExt->getOperand(0), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ConstantFP::get(RHSC->getContext(), F)); > + ? ? ? ?break; > + ? ? ?} > ? ? ? case Instruction::PHI: > ? ? ? ? // Only fold fcmp into the PHI if the phi and fcmp are in the same > ? ? ? ? // block. ?If in the same block, we're encouraging jump threading. ?If > > Modified: llvm/trunk/test/Transforms/InstCombine/fcmp.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fcmp.ll?rev=128625&r1=128624&r2=128625&view=diff > ============================================================================== > --- llvm/trunk/test/Transforms/InstCombine/fcmp.ll (original) > +++ llvm/trunk/test/Transforms/InstCombine/fcmp.ll Thu Mar 31 05:12:07 2011 > @@ -9,3 +9,26 @@ > ?; CHECK-NEXT: fcmp ogt float %x, %y > ?} > > +define i1 @test2(float %a) nounwind { > + ?%ext = fpext float %a to double > + ?%cmp = fcmp ogt double %ext, 1.000000e+00 > + ?ret i1 %cmp > +; CHECK: @test2 > +; CHECK-NEXT: fcmp ogt float %a, 1.0 > +} > + > +define i1 @test3(float %a) nounwind { > + ?%ext = fpext float %a to double > + ?%cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float. > + ?ret i1 %cmp > +; CHECK: @test3 > +; CHECK-NEXT: fpext float %a to double > +} > + > +define i1 @test4(float %a) nounwind { > + ?%ext = fpext float %a to double > + ?%cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float. > + ?ret i1 %cmp > +; CHECK: @test4 > +; CHECK-NEXT: fpext float %a to double > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From aggarwa4 at illinois.edu Thu Mar 31 15:43:05 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 31 Mar 2011 20:43:05 -0000 Subject: [llvm-commits] [poolalloc] r128667 - in /poolalloc/trunk: include/assistDS/TypeAnalysis.h lib/AssistDS/TypeAnalysis.cpp Message-ID: <20110331204305.6F3F92A6C12C@llvm.org> Author: aggarwa4 Date: Thu Mar 31 15:43:05 2011 New Revision: 128667 URL: http://llvm.org/viewvc/llvm-project?rev=128667&view=rev Log: Pass to infer types of load/store instructions. To be used by the dynamic type tracking insertion pass. TODO: expand to ignore loads/stores only used for copying values, as seen in the case of mrv. Added: poolalloc/trunk/include/assistDS/TypeAnalysis.h poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp Added: poolalloc/trunk/include/assistDS/TypeAnalysis.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/TypeAnalysis.h?rev=128667&view=auto ============================================================================== --- poolalloc/trunk/include/assistDS/TypeAnalysis.h (added) +++ poolalloc/trunk/include/assistDS/TypeAnalysis.h Thu Mar 31 15:43:05 2011 @@ -0,0 +1,41 @@ +//===-- TypeAnalysis.h - Deciphers Types of loads and stores --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This code defines a pass which clones functions which could potentially be +// used in indirect function calls. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Instructions.h" +#include "llvm/Module.h" +#include "llvm/Pass.h" + +namespace llvm { + // + // Class: TypeAnalysis + // + // Description: + // Implement an LLVM pass that analyses a file to say what + // the type of a load/store instruction is. + // + class TypeAnalysis : public ModulePass { + public: + static char ID; + TypeAnalysis() : ModulePass(&ID) {} + virtual ~TypeAnalysis(); + virtual bool runOnModule(Module& M); + virtual void getAnalysisUsage(llvm::AnalysisUsage &Info) const; + + const Type *getType(LoadInst *); + const Type *getType(StoreInst *); + const Type *getType(ExtractValueInst *); + const Type *getType(InsertValueInst *); + }; +} + Added: poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp?rev=128667&view=auto ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp (added) +++ poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp Thu Mar 31 15:43:05 2011 @@ -0,0 +1,48 @@ +//===-- TypeAnalysis.cpp - Clone Indirectly Called Functions --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "assistDS/TypeAnalysis.h" + + +#include + +using namespace llvm; + +// Pass ID variable +char TypeAnalysis::ID = 0; + +// Register the Pass +static RegisterPass +X("type-analysis", "Get types for load/stores"); + + +// +// Method: runOnModule() +// +bool +TypeAnalysis::runOnModule(Module& M) { + return false; +} +const Type * +TypeAnalysis::getType(LoadInst *LI){ + return LI->getType(); +} +const Type * +TypeAnalysis::getType(StoreInst *SI){ + return SI->getOperand(0)->getType(); +} +const Type * +TypeAnalysis::getType(InsertValueInst *I){ + return I->getInsertedValueOperand()->getType(); +} +const Type * +TypeAnalysis::getType(ExtractValueInst *I){ + return I->getType(); +} + From johnny.chen at apple.com Thu Mar 31 15:54:31 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 31 Mar 2011 20:54:31 -0000 Subject: [llvm-commits] [llvm] r128668 - /llvm/trunk/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt Message-ID: <20110331205431.1C21D2A6C12C@llvm.org> Author: johnny Date: Thu Mar 31 15:54:30 2011 New Revision: 128668 URL: http://llvm.org/viewvc/llvm-project?rev=128668&view=rev Log: Add a test case for a malformed LDC/LDC2 instructions with PUDW = 0b0000, which amounts to an UNDEFINED instruction. Added: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt Added: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt?rev=128668&view=auto ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt (added) +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt Thu Mar 31 15:54:30 2011 @@ -0,0 +1,11 @@ +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} + +# Opcode=0 Name=PHI Format=(42) +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# ------------------------------------------------------------------------------------------------- +# | 1: 1: 0: 1| 1: 1: 0: 0| 0: 0: 0: 1| 1: 1: 1: 1| 1: 0: 1: 1| 0: 1: 0: 0| 1: 0: 0: 1| 0: 0: 1: 0| +# ------------------------------------------------------------------------------------------------- +# +# The bytes have 0b0000 for P,U,D,W; from A8.6.51, it is undefined. +0x92 0xb4 0x1f 0xdc + From resistor at mac.com Thu Mar 31 16:05:45 2011 From: resistor at mac.com (Owen Anderson) Date: Thu, 31 Mar 2011 14:05:45 -0700 Subject: [llvm-commits] [llvm] r128662 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td test/MC/Disassembler/ARM/invalid-LDRrs-arm.txt In-Reply-To: <20110331192836.0D8842A6C12C@llvm.org> References: <20110331192836.0D8842A6C12C@llvm.org> Message-ID: <7B62E364-4A8C-4379-A5FA-A876082BB234@mac.com> Johnny, On Mar 31, 2011, at 12:28 PM, Johnny Chen wrote: > + let shift{4} = 0; // Inst{4} = 0 Why are assigning to shift{4} rather than to Inst{4}? The latter is consistent with how we handle this in other places. --Owen From johnny.chen at apple.com Thu Mar 31 16:18:57 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 31 Mar 2011 14:18:57 -0700 Subject: [llvm-commits] [llvm] r128662 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td test/MC/Disassembler/ARM/invalid-LDRrs-arm.txt In-Reply-To: <7B62E364-4A8C-4379-A5FA-A876082BB234@mac.com> References: <20110331192836.0D8842A6C12C@llvm.org> <7B62E364-4A8C-4379-A5FA-A876082BB234@mac.com> Message-ID: Hi Owen, There are a lot of places in the ARMInstrInfo.td which use the variable shift as a logical unit, and distributes the fragments of variable shift to various parts of the Inst. I was guessing that it could eventually be used for JITing purposes and I don't like to disturb the pattern. If this is not true, I'll just write: let Inst{4} = 0; and change the variable shift to have: bits<16> shift; instead of: bits<17> shift; Please let me know. Thanks. On Mar 31, 2011, at 2:05 PM, Owen Anderson wrote: > Johnny, > > On Mar 31, 2011, at 12:28 PM, Johnny Chen wrote: >> + let shift{4} = 0; // Inst{4} = 0 > > Why are assigning to shift{4} rather than to Inst{4}? The latter is consistent with how we handle this in other places. > > --Owen From isanbard at gmail.com Thu Mar 31 16:32:28 2011 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 31 Mar 2011 21:32:28 -0000 Subject: [llvm-commits] [test-suite] r128675 - /test-suite/tags/RELEASE_29/final/ Message-ID: <20110331213228.DBFE92A6C12C@llvm.org> Author: void Date: Thu Mar 31 16:32:28 2011 New Revision: 128675 URL: http://llvm.org/viewvc/llvm-project?rev=128675&view=rev Log: Creating test-suite - final tag. Added: test-suite/tags/RELEASE_29/final/ (props changed) - copied from r128674, test-suite/branches/release_29/ Propchange: test-suite/tags/RELEASE_29/final/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Thu Mar 31 16:32:28 2011 @@ -0,0 +1,4 @@ +Makefile.config +config.log +config.status +mklib Propchange: test-suite/tags/RELEASE_29/final/ ------------------------------------------------------------------------------ svn:mergeinfo = /test-suite/trunk:128083,128270 From benny.kra at googlemail.com Thu Mar 31 16:35:50 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 31 Mar 2011 21:35:50 -0000 Subject: [llvm-commits] [llvm] r128676 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCompares.cpp test/Transforms/InstCombine/fcmp.ll Message-ID: <20110331213550.2B5542A6C12C@llvm.org> Author: d0k Date: Thu Mar 31 16:35:49 2011 New Revision: 128676 URL: http://llvm.org/viewvc/llvm-project?rev=128676&view=rev Log: InstCombine: APFloat can't perform arithmetic on PPC double doubles, don't even try. Thanks Eli! Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/trunk/test/Transforms/InstCombine/fcmp.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=128676&r1=128675&r2=128676&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu Mar 31 16:35:49 2011 @@ -2769,6 +2769,10 @@ if (!RHSF) break; + // We can't convert a PPC double double. + if (RHSF->getType()->isPPC_FP128Ty()) + break; + const fltSemantics *Sem; // FIXME: This shouldn't be here. if (LHSExt->getSrcTy()->isFloatTy()) @@ -2779,8 +2783,6 @@ Sem = &APFloat::IEEEquad; else if (LHSExt->getSrcTy()->isX86_FP80Ty()) Sem = &APFloat::x87DoubleExtended; - else if (LHSExt->getSrcTy()->isPPC_FP128Ty()) - Sem = &APFloat::PPCDoubleDouble; else break; Modified: llvm/trunk/test/Transforms/InstCombine/fcmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fcmp.ll?rev=128676&r1=128675&r2=128676&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/fcmp.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/fcmp.ll Thu Mar 31 16:35:49 2011 @@ -49,3 +49,12 @@ ; CHECK: @test6 ; CHECK-NEXT: fcmp ogt float %x, %y } + +define i1 @test7(float %x) nounwind readnone ssp noredzone { + %ext = fpext float %x to ppc_fp128 + %cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000 + ret i1 %cmp +; Can't convert ppc_fp128 +; CHECK: @test7 +; CHECK-NEXT: fpext float %x to ppc_fp128 +} From benny.kra at googlemail.com Thu Mar 31 16:40:51 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 31 Mar 2011 23:40:51 +0200 Subject: [llvm-commits] [llvm] r128625 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCompares.cpp test/Transforms/InstCombine/fcmp.ll In-Reply-To: References: <20110331101207.B02362A6C12C@llvm.org> Message-ID: On 31.03.2011, at 22:14, Eli Friedman wrote: > Trying this transformation on APFloat::PPCDoubleDouble is likely to > cause bad things to happen. Yep, APFloat asserts immediately when asked to convert a ppc double double into something else. Fixed in r128676. From stoklund at 2pi.dk Thu Mar 31 17:14:03 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 31 Mar 2011 22:14:03 -0000 Subject: [llvm-commits] [llvm] r128680 - in /llvm/trunk/test/CodeGen/ARM: 2009-10-27-double-align.ll arguments.ll arm-and-tst-peephole.ll arm-returnaddr.ll fnmscs.ll indirectbr.ll ldrd.ll memcpy-inline.ll peephole-bitcast.ll reg_sequence.ll str_pre-2.ll thumb1-varalloc.ll vcgt.ll vfp.ll vld1.ll vld3.ll vldlane.ll Message-ID: <20110331221403.719902A6C12C@llvm.org> Author: stoklund Date: Thu Mar 31 17:14:03 2011 New Revision: 128680 URL: http://llvm.org/viewvc/llvm-project?rev=128680&view=rev Log: Fix ARM tests to be register allocator independent. Modified: llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll llvm/trunk/test/CodeGen/ARM/arguments.ll llvm/trunk/test/CodeGen/ARM/arm-and-tst-peephole.ll llvm/trunk/test/CodeGen/ARM/arm-returnaddr.ll llvm/trunk/test/CodeGen/ARM/fnmscs.ll llvm/trunk/test/CodeGen/ARM/indirectbr.ll llvm/trunk/test/CodeGen/ARM/ldrd.ll llvm/trunk/test/CodeGen/ARM/memcpy-inline.ll llvm/trunk/test/CodeGen/ARM/peephole-bitcast.ll llvm/trunk/test/CodeGen/ARM/reg_sequence.ll llvm/trunk/test/CodeGen/ARM/str_pre-2.ll llvm/trunk/test/CodeGen/ARM/thumb1-varalloc.ll llvm/trunk/test/CodeGen/ARM/vcgt.ll llvm/trunk/test/CodeGen/ARM/vfp.ll llvm/trunk/test/CodeGen/ARM/vld1.ll llvm/trunk/test/CodeGen/ARM/vld3.ll llvm/trunk/test/CodeGen/ARM/vldlane.ll Modified: llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll Thu Mar 31 17:14:03 2011 @@ -1,4 +1,6 @@ -; RUN: llc < %s -mtriple=arm-linux-gnueabi | FileCheck %s +; RUN: llc < %s -mtriple=arm-linux-gnueabi -regalloc=linearscan | FileCheck %s + +; This test depends on linear scan's reserved register coalescing. @.str = private constant [1 x i8] zeroinitializer, align 1 Modified: llvm/trunk/test/CodeGen/ARM/arguments.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/arguments.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/arguments.ll (original) +++ llvm/trunk/test/CodeGen/ARM/arguments.ll Thu Mar 31 17:14:03 2011 @@ -14,7 +14,7 @@ define i32 @f2() nounwind optsize { ; ELF: f2: ; ELF: mov [[REGISTER:(r[0-9]+)]], #128 -; ELF: str [[REGISTER]], [sp] +; ELF: str [[REGISTER]], [ ; DARWIN: f2: ; DARWIN: mov r3, #128 entry: Modified: llvm/trunk/test/CodeGen/ARM/arm-and-tst-peephole.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/arm-and-tst-peephole.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/arm-and-tst-peephole.ll (original) +++ llvm/trunk/test/CodeGen/ARM/arm-and-tst-peephole.ll Thu Mar 31 17:14:03 2011 @@ -26,9 +26,9 @@ ; ARM: ands r12, r12, #3 ; ARM-NEXT: beq -; THUMB: movs r5, #3 -; THUMB-NEXT: ands r5, r4 -; THUMB-NEXT: cmp r5, #0 +; THUMB: movs r[[R0:[0-9]+]], #3 +; THUMB-NEXT: ands r[[R0]], r +; THUMB-NEXT: cmp r[[R0]], #0 ; THUMB-NEXT: beq ; T2: ands r12, r12, #3 Modified: llvm/trunk/test/CodeGen/ARM/arm-returnaddr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/arm-returnaddr.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/arm-returnaddr.ll (original) +++ llvm/trunk/test/CodeGen/ARM/arm-returnaddr.ll Thu Mar 31 17:14:03 2011 @@ -1,8 +1,11 @@ -; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s -; RUN: llc < %s -mtriple=thumbv6-apple-darwin | FileCheck %s +; RUN: llc < %s -mtriple=arm-apple-darwin -regalloc=linearscan | FileCheck %s +; RUN: llc < %s -mtriple=thumbv6-apple-darwin -regalloc=linearscan | FileCheck %s ; rdar://8015977 ; rdar://8020118 +; This test needs the reserved register r7 to be coalesced into the ldr. +; So far, only linear scan can do that. + define i8* @rt0(i32 %x) nounwind readnone { entry: ; CHECK: rt0: @@ -16,7 +19,7 @@ entry: ; CHECK: rt2: ; CHECK: {r7, lr} -; CHECK: ldr r0, [r7] +; CHECK: ldr r[[R0:[0-9]+]], [r7] ; CHECK: ldr r0, [r0] ; CHECK: ldr r0, [r0, #4] %0 = tail call i8* @llvm.returnaddress(i32 2) Modified: llvm/trunk/test/CodeGen/ARM/fnmscs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fnmscs.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fnmscs.ll (original) +++ llvm/trunk/test/CodeGen/ARM/fnmscs.ll Thu Mar 31 17:14:03 2011 @@ -1,6 +1,7 @@ ; RUN: llc < %s -march=arm -mattr=+vfp2 | FileCheck %s -check-prefix=VFP2 ; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s -check-prefix=NEON ; RUN: llc < %s -march=arm -mcpu=cortex-a8 | FileCheck %s -check-prefix=A8 +; RUN: llc < %s -march=arm -mcpu=cortex-a8 -regalloc=basic | FileCheck %s -check-prefix=A8 define float @t1(float %acc, float %a, float %b) nounwind { entry: @@ -11,8 +12,8 @@ ; NEON: vnmla.f32 ; A8: t1: -; A8: vnmul.f32 s0, s{{[01]}}, s{{[01]}} -; A8: vsub.f32 d0, d0, d1 +; A8: vnmul.f32 s{{[0-9]}}, s{{[0-9]}}, s{{[0-9]}} +; A8: vsub.f32 d{{[0-9]}}, d{{[0-9]}}, d{{[0-9]}} %0 = fmul float %a, %b %1 = fsub float -0.0, %0 %2 = fsub float %1, %acc @@ -28,8 +29,8 @@ ; NEON: vnmla.f32 ; A8: t2: -; A8: vnmul.f32 s0, s{{[01]}}, s{{[01]}} -; A8: vsub.f32 d0, d0, d1 +; A8: vnmul.f32 s{{[0123]}}, s{{[0123]}}, s{{[0123]}} +; A8: vsub.f32 d{{[0-9]}}, d{{[0-9]}}, d{{[0-9]}} %0 = fmul float %a, %b %1 = fmul float -1.0, %0 %2 = fsub float %1, %acc @@ -45,8 +46,8 @@ ; NEON: vnmla.f64 ; A8: t3: -; A8: vnmul.f64 d16, d1{{[67]}}, d1{{[67]}} -; A8: vsub.f64 d16, d16, d17 +; A8: vnmul.f64 d1{{[67]}}, d1{{[67]}}, d1{{[67]}} +; A8: vsub.f64 d1{{[67]}}, d1{{[67]}}, d1{{[67]}} %0 = fmul double %a, %b %1 = fsub double -0.0, %0 %2 = fsub double %1, %acc @@ -62,8 +63,8 @@ ; NEON: vnmla.f64 ; A8: t4: -; A8: vnmul.f64 d16, d1{{[67]}}, d1{{[67]}} -; A8: vsub.f64 d16, d16, d17 +; A8: vnmul.f64 d1{{[67]}}, d1{{[67]}}, d1{{[67]}} +; A8: vsub.f64 d1{{[67]}}, d1{{[67]}}, d1{{[67]}} %0 = fmul double %a, %b %1 = fmul double -1.0, %0 %2 = fsub double %1, %acc Modified: llvm/trunk/test/CodeGen/ARM/indirectbr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/indirectbr.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/indirectbr.ll (original) +++ llvm/trunk/test/CodeGen/ARM/indirectbr.ll Thu Mar 31 17:14:03 2011 @@ -14,15 +14,15 @@ %1 = icmp eq i8* %0, null ; [#uses=1] ; indirect branch gets duplicated here ; ARM: bx -; THUMB: mov pc, r1 -; THUMB2: mov pc, r2 +; THUMB: mov pc, +; THUMB2: mov pc, br i1 %1, label %bb3, label %bb2 bb2: ; preds = %entry, %bb3 %gotovar.4.0 = phi i8* [ %gotovar.4.0.pre, %bb3 ], [ %0, %entry ] ; [#uses=1] ; ARM: bx -; THUMB: mov pc, r1 -; THUMB2: mov pc, r2 +; THUMB: mov pc, +; THUMB2: mov pc, indirectbr i8* %gotovar.4.0, [label %L5, label %L4, label %L3, label %L2, label %L1] bb3: ; preds = %entry Modified: llvm/trunk/test/CodeGen/ARM/ldrd.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ldrd.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/ldrd.ll (original) +++ llvm/trunk/test/CodeGen/ARM/ldrd.ll Thu Mar 31 17:14:03 2011 @@ -1,19 +1,21 @@ -; RUN: llc < %s -mtriple=armv6-apple-darwin | FileCheck %s -check-prefix=V6 +; RUN: llc < %s -mtriple=armv6-apple-darwin -regalloc=linearscan | FileCheck %s -check-prefix=V6 ; RUN: llc < %s -mtriple=armv5-apple-darwin | FileCheck %s -check-prefix=V5 ; RUN: llc < %s -mtriple=armv6-eabi | FileCheck %s -check-prefix=EABI ; rdar://r6949835 +; Magic ARM pair hints works best with linearscan. + @b = external global i64* define i64 @t(i64 %a) nounwind readonly { entry: ;V6: ldrd r2, [r2] -;V5: ldr r3, [r2] -;V5: ldr r2, [r2, #4] +;V5: ldr r{{[0-9]+}}, [r2] +;V5: ldr r{{[0-9]+}}, [r2, #4] -;EABI: ldr r3, [r2] -;EABI: ldr r2, [r2, #4] +;EABI: ldr r{{[0-9]+}}, [r2] +;EABI: ldr r{{[0-9]+}}, [r2, #4] %0 = load i64** @b, align 4 %1 = load i64* %0, align 4 Modified: llvm/trunk/test/CodeGen/ARM/memcpy-inline.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/memcpy-inline.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/memcpy-inline.ll (original) +++ llvm/trunk/test/CodeGen/ARM/memcpy-inline.ll Thu Mar 31 17:14:03 2011 @@ -1,9 +1,13 @@ -; RUN: llc < %s -mtriple=arm-apple-darwin | grep ldmia -; RUN: llc < %s -mtriple=arm-apple-darwin | grep stmia -; RUN: llc < %s -mtriple=arm-apple-darwin | grep ldrb -; RUN: llc < %s -mtriple=arm-apple-darwin | grep ldrh +; RUN: llc < %s -mtriple=arm-apple-darwin -regalloc=linearscan -disable-post-ra | FileCheck %s +; RUN: llc < %s -mtriple=arm-apple-darwin -regalloc=basic -disable-post-ra | FileCheck %s - %struct.x = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 } +; The ARM magic hinting works best with linear scan. +; CHECK: ldmia +; CHECK: stmia +; CHECK: ldrh +; CHECK: ldrb + +%struct.x = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 } @src = external global %struct.x @dst = external global %struct.x Modified: llvm/trunk/test/CodeGen/ARM/peephole-bitcast.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/peephole-bitcast.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/peephole-bitcast.ll (original) +++ llvm/trunk/test/CodeGen/ARM/peephole-bitcast.ll Thu Mar 31 17:14:03 2011 @@ -1,8 +1,11 @@ -; RUN: llc < %s -march=arm -mcpu=cortex-a8 | FileCheck %s +; RUN: llc < %s -march=arm -mcpu=cortex-a8 -regalloc=linearscan | FileCheck %s ; vmov s0, r0 + vmov r0, s0 should have been optimized away. ; rdar://9104514 +; Peephole leaves a dead vmovsr instruction behind, and depends on linear scan +; to remove it. + define void @t(float %x) nounwind ssp { entry: ; CHECK: t: Modified: llvm/trunk/test/CodeGen/ARM/reg_sequence.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/reg_sequence.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/reg_sequence.ll (original) +++ llvm/trunk/test/CodeGen/ARM/reg_sequence.ll Thu Mar 31 17:14:03 2011 @@ -1,4 +1,5 @@ ; RUN: llc < %s -march=arm -mcpu=cortex-a8 | FileCheck %s +; RUN: llc < %s -march=arm -mcpu=cortex-a8 -regalloc=basic | FileCheck %s ; Implementing vld / vst as REG_SEQUENCE eliminates the extra vmov's. %struct.int16x8_t = type { <8 x i16> } @@ -123,9 +124,9 @@ return2: ; CHECK: %return2 ; CHECK: vadd.i32 -; CHECK: vmov q9, q11 +; CHECK: vmov {{q[0-9]+}}, {{q[0-9]+}} ; CHECK-NOT: vmov -; CHECK: vst2.32 {d16, d17, d18, d19} +; CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}} %tmp100 = extractvalue %struct.__neon_int32x4x2_t %tmp2, 0 ; <<4 x i32>> [#uses=1] %tmp101 = extractvalue %struct.__neon_int32x4x2_t %tmp5, 1 ; <<4 x i32>> [#uses=1] %tmp102 = add <4 x i32> %tmp100, %tmp101 ; <<4 x i32>> [#uses=1] @@ -137,9 +138,10 @@ define <8 x i16> @t5(i16* %A, <8 x i16>* %B) nounwind { ; CHECK: t5: ; CHECK: vldmia -; CHECK: vmov q9, q8 +; How can FileCheck match Q and D registers? We need a lisp interpreter. +; CHECK: vmov {{q[0-9]+}}, {{q[0-9]+}} ; CHECK-NOT: vmov -; CHECK: vld2.16 {d16[1], d18[1]}, [r0] +; CHECK: vld2.16 {d{{[0-9]+}}[1], d{{[0-9]+}}[1]}, [r0] ; CHECK-NOT: vmov ; CHECK: vadd.i16 %tmp0 = bitcast i16* %A to i8* ; [#uses=1] @@ -154,8 +156,8 @@ define <8 x i8> @t6(i8* %A, <8 x i8>* %B) nounwind { ; CHECK: t6: ; CHECK: vldr.64 -; CHECK: vmov d17, d16 -; CHECK-NEXT: vld2.8 {d16[1], d17[1]} +; CHECK: vmov d[[D0:[0-9]+]], d[[D1:[0-9]+]] +; CHECK-NEXT: vld2.8 {d[[D1]][1], d[[D0]][1]} %tmp1 = load <8 x i8>* %B ; <<8 x i8>> [#uses=2] %tmp2 = call %struct.__neon_int8x8x2_t @llvm.arm.neon.vld2lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 1) ; <%struct.__neon_int8x8x2_t> [#uses=2] %tmp3 = extractvalue %struct.__neon_int8x8x2_t %tmp2, 0 ; <<8 x i8>> [#uses=1] @@ -169,10 +171,10 @@ ; CHECK: t7: ; CHECK: vld2.32 ; CHECK: vst2.32 -; CHECK: vld1.32 {d16, d17}, -; CHECK: vmov q9, q8 +; CHECK: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, +; CHECK: vmov q[[Q0:[0-9]+]], q[[Q1:[0-9]+]] ; CHECK-NOT: vmov -; CHECK: vuzp.32 q8, q9 +; CHECK: vuzp.32 q[[Q1]], q[[Q0]] ; CHECK: vst1.32 %0 = bitcast i32* %iptr to i8* ; [#uses=2] %1 = tail call %struct.__neon_int32x4x2_t @llvm.arm.neon.vld2.v4i32(i8* %0, i32 1) ; <%struct.__neon_int32x4x2_t> [#uses=2] @@ -271,7 +273,7 @@ entry: ; CHECK: t10: ; CHECK: vmul.f32 q8, q8, d0[0] -; CHECK: vmov.i32 q9, #0x3F000000 +; CHECK: vmov.i32 q[[Q0:[0-9]+]], #0x3F000000 ; CHECK: vadd.f32 q8, q8, q8 %0 = shufflevector <4 x float> zeroinitializer, <4 x float> undef, <4 x i32> zeroinitializer ; <<4 x float>> [#uses=1] %1 = insertelement <4 x float> %0, float undef, i32 1 ; <<4 x float>> [#uses=1] Modified: llvm/trunk/test/CodeGen/ARM/str_pre-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/str_pre-2.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/str_pre-2.ll (original) +++ llvm/trunk/test/CodeGen/ARM/str_pre-2.ll Thu Mar 31 17:14:03 2011 @@ -1,4 +1,7 @@ -; RUN: llc < %s -mtriple=armv6-linux-gnu | FileCheck %s +; RUN: llc < %s -mtriple=armv6-linux-gnu -regalloc=linearscan | FileCheck %s +; RUN: llc < %s -mtriple=armv6-linux-gnu -regalloc=basic | FileCheck %s + +; The greedy register allocator uses a single CSR here, invalidating the test. @b = external global i64* Modified: llvm/trunk/test/CodeGen/ARM/thumb1-varalloc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/thumb1-varalloc.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/thumb1-varalloc.ll (original) +++ llvm/trunk/test/CodeGen/ARM/thumb1-varalloc.ll Thu Mar 31 17:14:03 2011 @@ -1,4 +1,5 @@ ; RUN: llc < %s -mtriple=thumbv6-apple-darwin | FileCheck %s +; RUN: llc < %s -mtriple=thumbv6-apple-darwin -regalloc=basic | FileCheck %s ; rdar://8819685 @__bar = external hidden global i8* @@ -12,12 +13,13 @@ %0 = load i8** @__bar, align 4 %1 = icmp eq i8* %0, null br i1 %1, label %bb1, label %bb3 +; CHECK: bne bb1: store i32 1026, i32* %size, align 4 %2 = alloca [1026 x i8], align 1 -; CHECK: mov r0, sp -; CHECK: adds r4, r0, r4 +; CHECK: mov [[R0:r[0-9]+]], sp +; CHECK: adds {{r[0-9]+}}, [[R0]], {{r[0-9]+}} %3 = getelementptr inbounds [1026 x i8]* %2, i32 0, i32 0 %4 = call i32 @_called_func(i8* %3, i32* %size) nounwind %5 = icmp eq i32 %4, 0 Modified: llvm/trunk/test/CodeGen/ARM/vcgt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vcgt.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vcgt.ll (original) +++ llvm/trunk/test/CodeGen/ARM/vcgt.ll Thu Mar 31 17:14:03 2011 @@ -1,4 +1,5 @@ ; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s +; RUN: llc < %s -march=arm -mattr=+neon -regalloc=basic | FileCheck %s define <8 x i8> @vcgts8(<8 x i8>* %A, <8 x i8>* %B) nounwind { ;CHECK: vcgts8: @@ -161,9 +162,9 @@ ; rdar://7923010 define <4 x i32> @vcgt_zext(<4 x float>* %A, <4 x float>* %B) nounwind { ;CHECK: vcgt_zext: -;CHECK: vmov.i32 q10, #0x1 -;CHECK: vcgt.f32 q8 -;CHECK: vand q8, q8, q10 +;CHECK: vmov.i32 [[Q0:q[0-9]+]], #0x1 +;CHECK: vcgt.f32 [[Q1:q[0-9]+]] +;CHECK: vand [[Q2:q[0-9]+]], [[Q1]], [[Q0]] %tmp1 = load <4 x float>* %A %tmp2 = load <4 x float>* %B %tmp3 = fcmp ogt <4 x float> %tmp1, %tmp2 Modified: llvm/trunk/test/CodeGen/ARM/vfp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vfp.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vfp.ll (original) +++ llvm/trunk/test/CodeGen/ARM/vfp.ll Thu Mar 31 17:14:03 2011 @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=arm -mattr=+vfp2 | FileCheck %s +; RUN: llc < %s -march=arm -mattr=+vfp2 -disable-post-ra | FileCheck %s +; RUN: llc < %s -march=arm -mattr=+vfp2 -disable-post-ra -regalloc=basic | FileCheck %s define void @test(float* %P, double* %D) { %A = load float* %P ; [#uses=1] @@ -39,10 +40,10 @@ define void @test_ext_round(float* %P, double* %D) { ;CHECK: test_ext_round: %a = load float* %P ; [#uses=1] +;CHECK: vcvt.f32.f64 ;CHECK: vcvt.f64.f32 %b = fpext float %a to double ; [#uses=1] %A = load double* %D ; [#uses=1] -;CHECK: vcvt.f32.f64 %B = fptrunc double %A to float ; [#uses=1] store double %b, double* %D store float %B, float* %P Modified: llvm/trunk/test/CodeGen/ARM/vld1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vld1.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vld1.ll (original) +++ llvm/trunk/test/CodeGen/ARM/vld1.ll Thu Mar 31 17:14:03 2011 @@ -1,4 +1,5 @@ ; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s +; RUN: llc < %s -march=arm -mattr=+neon -regalloc=basic | FileCheck %s define <8 x i8> @vld1i8(i8* %A) nounwind { ;CHECK: vld1i8: @@ -19,7 +20,7 @@ ;Check for a post-increment updating load. define <4 x i16> @vld1i16_update(i16** %ptr) nounwind { ;CHECK: vld1i16_update: -;CHECK: vld1.16 {d16}, [r1]! +;CHECK: vld1.16 {d16}, [{{r[0-9]+}}]! %A = load i16** %ptr %tmp0 = bitcast i16* %A to i8* %tmp1 = call <4 x i16> @llvm.arm.neon.vld1.v4i16(i8* %tmp0, i32 1) @@ -39,7 +40,7 @@ ;Check for a post-increment updating load with register increment. define <2 x i32> @vld1i32_update(i32** %ptr, i32 %inc) nounwind { ;CHECK: vld1i32_update: -;CHECK: vld1.32 {d16}, [r2], r1 +;CHECK: vld1.32 {d16}, [{{r[0-9]+}}], {{r[0-9]+}} %A = load i32** %ptr %tmp0 = bitcast i32* %A to i8* %tmp1 = call <2 x i32> @llvm.arm.neon.vld1.v2i32(i8* %tmp0, i32 1) @@ -75,7 +76,7 @@ ;Check for a post-increment updating load. define <16 x i8> @vld1Qi8_update(i8** %ptr) nounwind { ;CHECK: vld1Qi8_update: -;CHECK: vld1.8 {d16, d17}, [r1, :64]! +;CHECK: vld1.8 {d16, d17}, [{{r[0-9]+}}, :64]! %A = load i8** %ptr %tmp1 = call <16 x i8> @llvm.arm.neon.vld1.v16i8(i8* %A, i32 8) %tmp2 = getelementptr i8* %A, i32 16 Modified: llvm/trunk/test/CodeGen/ARM/vld3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vld3.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vld3.ll (original) +++ llvm/trunk/test/CodeGen/ARM/vld3.ll Thu Mar 31 17:14:03 2011 @@ -1,4 +1,5 @@ ; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s +; RUN: llc < %s -march=arm -mattr=+neon -regalloc=basic | FileCheck %s %struct.__neon_int8x8x3_t = type { <8 x i8>, <8 x i8>, <8 x i8> } %struct.__neon_int16x4x3_t = type { <4 x i16>, <4 x i16>, <4 x i16> } @@ -36,7 +37,7 @@ ;Check for a post-increment updating load with register increment. define <4 x i16> @vld3i16_update(i16** %ptr, i32 %inc) nounwind { ;CHECK: vld3i16_update: -;CHECK: vld3.16 {d16, d17, d18}, [r2], r1 +;CHECK: vld3.16 {d16, d17, d18}, [{{r[0-9]+}}], {{r[0-9]+}} %A = load i16** %ptr %tmp0 = bitcast i16* %A to i8* %tmp1 = call %struct.__neon_int16x4x3_t @llvm.arm.neon.vld3.v4i16(i8* %tmp0, i32 1) @@ -121,8 +122,8 @@ ;Check for a post-increment updating load. define <4 x i32> @vld3Qi32_update(i32** %ptr) nounwind { ;CHECK: vld3Qi32_update: -;CHECK: vld3.32 {d16, d18, d20}, [r1]! -;CHECK: vld3.32 {d17, d19, d21}, [r1]! +;CHECK: vld3.32 {d16, d18, d20}, [r[[R:[0-9]+]]]! +;CHECK: vld3.32 {d17, d19, d21}, [r[[R]]]! %A = load i32** %ptr %tmp0 = bitcast i32* %A to i8* %tmp1 = call %struct.__neon_int32x4x3_t @llvm.arm.neon.vld3.v4i32(i8* %tmp0, i32 1) Modified: llvm/trunk/test/CodeGen/ARM/vldlane.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vldlane.ll?rev=128680&r1=128679&r2=128680&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vldlane.ll (original) +++ llvm/trunk/test/CodeGen/ARM/vldlane.ll Thu Mar 31 17:14:03 2011 @@ -1,4 +1,5 @@ ; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s +; RUN: llc < %s -march=arm -mattr=+neon -regalloc=basic | FileCheck %s define <8 x i8> @vld1lanei8(i8* %A, <8 x i8>* %B) nounwind { ;CHECK: vld1lanei8: @@ -279,7 +280,7 @@ ;Check for a post-increment updating load with register increment. define <8 x i16> @vld3laneQi16_update(i16** %ptr, <8 x i16>* %B, i32 %inc) nounwind { ;CHECK: vld3laneQi16_update: -;CHECK: vld3.16 {d16[1], d18[1], d20[1]}, [r2], r1 +;CHECK: vld3.16 {d16[1], d18[1], d20[1]}, [{{r[0-9]+}}], {{r[0-9]+}} %A = load i16** %ptr %tmp0 = bitcast i16* %A to i8* %tmp1 = load <8 x i16>* %B From johnny.chen at apple.com Thu Mar 31 17:48:31 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 31 Mar 2011 15:48:31 -0700 Subject: [llvm-commits] code review: ARMInstPrinter.cpp (Constants with multiple encodings) Message-ID: <0BD84ACC-8578-42C3-96A8-392A0998C147@apple.com> Hi, I sent an incomplete patch to Bob Wilson and Jim Grosbach earlier today. This is the complete patch. Thanks. -------------- next part -------------- A non-text attachment was scrubbed... Name: InstPrinter.patch Type: application/octet-stream Size: 2721 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110331/ce363d0b/attachment.obj From nadav.rotem at intel.com Thu Mar 31 17:57:29 2011 From: nadav.rotem at intel.com (Nadav Rotem) Date: Thu, 31 Mar 2011 22:57:29 -0000 Subject: [llvm-commits] [llvm] r128683 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineVectorOps.cpp test/Transforms/InstCombine/ExtractCast.ll Message-ID: <20110331225729.4935A2A6C12C@llvm.org> Author: nadav Date: Thu Mar 31 17:57:29 2011 New Revision: 128683 URL: http://llvm.org/viewvc/llvm-project?rev=128683&view=rev Log: Instcombile optimization: extractelement(cast) -> cast(extractelement) Added: llvm/trunk/test/Transforms/InstCombine/ExtractCast.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineVectorOps.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineVectorOps.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineVectorOps.cpp?rev=128683&r1=128682&r2=128683&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineVectorOps.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineVectorOps.cpp Thu Mar 31 17:57:29 2011 @@ -230,8 +230,16 @@ ConstantInt::get(Int32Ty, SrcIdx, false)); } + } else if (CastInst *CI = dyn_cast(I)) { + // Canonicalize extractelement(cast) -> cast(extractelement) + // bitcasts can change the number of vector elements and they cost nothing + if (CI->hasOneUse() && EI.hasOneUse() && + (CI->getOpcode() != Instruction::BitCast)) { + Value *EE = Builder->CreateExtractElement(CI->getOperand(0), + EI.getIndexOperand()); + return CastInst::Create(CI->getOpcode(), EE, EI.getType()); + } } - // FIXME: Canonicalize extractelement(bitcast) -> bitcast(extractelement) } return 0; } Added: llvm/trunk/test/Transforms/InstCombine/ExtractCast.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/ExtractCast.ll?rev=128683&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/ExtractCast.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/ExtractCast.ll Thu Mar 31 17:57:29 2011 @@ -0,0 +1,27 @@ +; RUN: opt < %s -instcombine -S -o - | FileCheck %s + +; CHECK: @a +define i32 @a(<4 x i64> %I) { +entry: +; CHECK-NOT: trunc <4 x i64> + %J = trunc <4 x i64> %I to <4 x i32> + %K = extractelement <4 x i32> %J, i32 3 +; CHECK: extractelement <4 x i64> +; CHECK: trunc i64 +; CHECK: ret + ret i32 %K +} + + +; CHECK: @b +define i32 @b(<4 x float> %I) { +entry: +; CHECK-NOT: fptosi <4 x float> + %J = fptosi <4 x float> %I to <4 x i32> + %K = extractelement <4 x i32> %J, i32 3 +; CHECK: extractelement <4 x float> +; CHECK: fptosi float +; CHECK: ret + ret i32 %K +} + From aggarwa4 at illinois.edu Thu Mar 31 17:59:37 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 31 Mar 2011 22:59:37 -0000 Subject: [llvm-commits] [poolalloc] r128684 - in /poolalloc/trunk: include/assistDS/TypeAnalysis.h lib/AssistDS/TypeAnalysis.cpp Message-ID: <20110331225937.F3F4A2A6C12C@llvm.org> Author: aggarwa4 Date: Thu Mar 31 17:59:37 2011 New Revision: 128684 URL: http://llvm.org/viewvc/llvm-project?rev=128684&view=rev Log: Add functions to infer if this load/store is only used to copy values. Modified: poolalloc/trunk/include/assistDS/TypeAnalysis.h poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp Modified: poolalloc/trunk/include/assistDS/TypeAnalysis.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/TypeAnalysis.h?rev=128684&r1=128683&r2=128684&view=diff ============================================================================== --- poolalloc/trunk/include/assistDS/TypeAnalysis.h (original) +++ poolalloc/trunk/include/assistDS/TypeAnalysis.h Thu Mar 31 17:59:37 2011 @@ -28,14 +28,17 @@ public: static char ID; TypeAnalysis() : ModulePass(&ID) {} - virtual ~TypeAnalysis(); virtual bool runOnModule(Module& M); - virtual void getAnalysisUsage(llvm::AnalysisUsage &Info) const; + virtual void getAnalysisUsage(AnalysisUsage &Info) const; const Type *getType(LoadInst *); const Type *getType(StoreInst *); const Type *getType(ExtractValueInst *); const Type *getType(InsertValueInst *); + bool isCopyingLoad(LoadInst *); + bool isCopyingLoad(ExtractValueInst *); + bool isCopyingStore(StoreInst *); + bool isCopyingStore(InsertValueInst *); }; } Modified: poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp?rev=128684&r1=128683&r2=128684&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp Thu Mar 31 17:59:37 2011 @@ -8,8 +8,6 @@ //===----------------------------------------------------------------------===// #include "assistDS/TypeAnalysis.h" - - #include using namespace llvm; @@ -45,4 +43,51 @@ TypeAnalysis::getType(ExtractValueInst *I){ return I->getType(); } +bool +TypeAnalysis::isCopyingLoad(LoadInst *LI){ + if(LI->getNumUses() == 1) + if(StoreInst *SI = dyn_cast(LI->use_begin())) { + if(SI->getOperand(0) == LI) + return true; + } else if(InsertValueInst *IV = dyn_cast(LI->use_begin())) { + if(IV->getInsertedValueOperand() == LI) + return true; + } + return false; +} +bool +TypeAnalysis::isCopyingLoad(ExtractValueInst * EI) { + if(EI->getNumUses() == 1) + if(StoreInst *SI = dyn_cast(EI->use_begin())) { + if(SI->getOperand(0) == EI) + return true; + } else if(InsertValueInst *IV = dyn_cast(EI->use_begin())) { + if(IV->getInsertedValueOperand() == EI) + return true; + } + return false; +} +bool +TypeAnalysis::isCopyingStore(StoreInst *SI) { + if(SI->getOperand(0)->getNumUses() == 1) + if(isa(SI->getOperand(0))) + return true; + else if(isa(SI->getOperand(0))) + return true; + + return false; +} +bool +TypeAnalysis::isCopyingStore(InsertValueInst *IVI) { + if(IVI->getInsertedValueOperand()->getNumUses() == 1) + if(isa(IVI->getInsertedValueOperand())) + return true; + else if(isa(IVI->getInsertedValueOperand())) + return true; + return false; +} +void +TypeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); +} From stoklund at 2pi.dk Thu Mar 31 18:02:12 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 31 Mar 2011 23:02:12 -0000 Subject: [llvm-commits] [llvm] r128686 - /llvm/trunk/test/CodeGen/SystemZ/2009-07-10-BadIncomingArgOffset.ll Message-ID: <20110331230212.66EFA2A6C12C@llvm.org> Author: stoklund Date: Thu Mar 31 18:02:12 2011 New Revision: 128686 URL: http://llvm.org/viewvc/llvm-project?rev=128686&view=rev Log: Fix SystemZ tests Modified: llvm/trunk/test/CodeGen/SystemZ/2009-07-10-BadIncomingArgOffset.ll Modified: llvm/trunk/test/CodeGen/SystemZ/2009-07-10-BadIncomingArgOffset.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/2009-07-10-BadIncomingArgOffset.ll?rev=128686&r1=128685&r2=128686&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/SystemZ/2009-07-10-BadIncomingArgOffset.ll (original) +++ llvm/trunk/test/CodeGen/SystemZ/2009-07-10-BadIncomingArgOffset.ll Thu Mar 31 18:02:12 2011 @@ -1,4 +1,5 @@ ; RUN: llc < %s | FileCheck %s +; RUN: llc < %s -regalloc=basic | FileCheck %s target datalayout = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16" target triple = "s390x-ibm-linux" @@ -8,7 +9,7 @@ declare double @mp_mul_d2i_test(i32 signext, i32 signext, double* nocapture) nounwind define void @mp_mul_radix_test_bb3(i32 %radix, i32 %nfft, double* %tmpfft, i32* %ip, double* %w, double* %arrayidx44.reload, double* %call.out) nounwind { -; CHECK: lg %r11, 328(%r15) +; CHECK: lg %r{{[0-9]+}}, 328(%r15) newFuncRoot: br label %bb3 From stoklund at 2pi.dk Thu Mar 31 18:02:15 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 31 Mar 2011 23:02:15 -0000 Subject: [llvm-commits] [llvm] r128687 - in /llvm/trunk: lib/Target/ARM/Thumb1RegisterInfo.cpp lib/Target/ARM/Thumb1RegisterInfo.h test/CodeGen/Thumb/2009-08-20-ISelBug.ll Message-ID: <20110331230215.BED962A6C12D@llvm.org> Author: stoklund Date: Thu Mar 31 18:02:15 2011 New Revision: 128687 URL: http://llvm.org/viewvc/llvm-project?rev=128687&view=rev Log: Provide a legal pointer register class when targeting thumb1. The LocalStackSlotAllocation pass was creating illegal registers. Modified: llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h llvm/trunk/test/CodeGen/Thumb/2009-08-20-ISelBug.ll Modified: llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp?rev=128687&r1=128686&r2=128687&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp Thu Mar 31 18:02:15 2011 @@ -48,6 +48,11 @@ : ARMBaseRegisterInfo(tii, sti) { } +const TargetRegisterClass * +Thumb1RegisterInfo::getPointerRegClass(unsigned Kind) const { + return ARM::tGPRRegisterClass; +} + /// emitLoadConstPool - Emits a load from constpool to materialize the /// specified immediate. void Modified: llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h?rev=128687&r1=128686&r2=128687&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h (original) +++ llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h Thu Mar 31 18:02:15 2011 @@ -28,6 +28,8 @@ public: Thumb1RegisterInfo(const ARMBaseInstrInfo &tii, const ARMSubtarget &STI); + const TargetRegisterClass *getPointerRegClass(unsigned Kind = 0) const; + /// emitLoadConstPool - Emits a load from constpool to materialize the /// specified immediate. void emitLoadConstPool(MachineBasicBlock &MBB, Modified: llvm/trunk/test/CodeGen/Thumb/2009-08-20-ISelBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb/2009-08-20-ISelBug.ll?rev=128687&r1=128686&r2=128687&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb/2009-08-20-ISelBug.ll (original) +++ llvm/trunk/test/CodeGen/Thumb/2009-08-20-ISelBug.ll Thu Mar 31 18:02:15 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=thumbv6-apple-darwin -relocation-model=pic -disable-fp-elim -mattr=+v6 | FileCheck %s +; RUN: llc < %s -mtriple=thumbv6-apple-darwin -relocation-model=pic -disable-fp-elim -mattr=+v6 -verify-machineinstrs | FileCheck %s ; rdar://7157006 %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 } From stoklund at 2pi.dk Thu Mar 31 18:02:18 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 31 Mar 2011 23:02:18 -0000 Subject: [llvm-commits] [llvm] r128688 - /llvm/trunk/lib/CodeGen/RegAllocBasic.cpp Message-ID: <20110331230218.14C652A6C12E@llvm.org> Author: stoklund Date: Thu Mar 31 18:02:17 2011 New Revision: 128688 URL: http://llvm.org/viewvc/llvm-project?rev=128688&view=rev Log: The basic register allocator must also use the inline spiller. It is using a trivial rewriter that doesn't know how to insert spill code requested by the standard spiller. Modified: llvm/trunk/lib/CodeGen/RegAllocBasic.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocBasic.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocBasic.cpp?rev=128688&r1=128687&r2=128688&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocBasic.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocBasic.cpp Thu Mar 31 18:02:17 2011 @@ -508,7 +508,7 @@ ReservedRegs = TRI->getReservedRegs(*MF); - SpillerInstance.reset(createSpiller(*this, *MF, *VRM)); + SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM)); allocatePhysRegs(); From bruno.cardoso at gmail.com Thu Mar 31 18:26:08 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Thu, 31 Mar 2011 23:26:08 -0000 Subject: [llvm-commits] [llvm] r128689 - in /llvm/trunk: lib/Target/ARM/ARMAddressingModes.h lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.h test/MC/ARM/arm_addrmode2.s Message-ID: <20110331232608.567522A6C12C@llvm.org> Author: bruno Date: Thu Mar 31 18:26:08 2011 New Revision: 128689 URL: http://llvm.org/viewvc/llvm-project?rev=128689&view=rev Log: Apply again changes to support ARM memory asm parsing. I removed all LDR/STR changes and left them to a future patch. Passing all checks now. - Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and fix the encoding wherever is possible. - Add a new encoding bit to describe the index mode used and teach printAddrMode2Operand to check by the addressing mode which index mode to print. - Testcases Added: llvm/trunk/test/MC/ARM/arm_addrmode2.s Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h llvm/trunk/lib/Target/ARM/ARMBaseInfo.h llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h llvm/trunk/lib/Target/ARM/ARMInstrFormats.td llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAddressingModes.h?rev=128689&r1=128688&r2=128689&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAddressingModes.h (original) +++ llvm/trunk/lib/Target/ARM/ARMAddressingModes.h Thu Mar 31 18:26:08 2011 @@ -408,16 +408,18 @@ // // The first operand is always a Reg. The second operand is a reg if in // reg/reg form, otherwise it's reg#0. The third field encodes the operation - // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. + // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The + // forth operand 16-17 encodes the index mode. // // If this addressing mode is a frame index (before prolog/epilog insertion // and code rewriting), this operand will have the form: FI#, reg0, // with no shift amount for the frame offset. // - static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO) { + static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, + unsigned IdxMode = 0) { assert(Imm12 < (1 << 12) && "Imm too large!"); bool isSub = Opc == sub; - return Imm12 | ((int)isSub << 12) | (SO << 13); + return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ; } static inline unsigned getAM2Offset(unsigned AM2Opc) { return AM2Opc & ((1 << 12)-1); @@ -426,7 +428,10 @@ return ((AM2Opc >> 12) & 1) ? sub : add; } static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) { - return (ShiftOpc)(AM2Opc >> 13); + return (ShiftOpc)((AM2Opc >> 13) & 7); + } + static inline unsigned getAM2IdxMode(unsigned AM2Opc) { + return (AM2Opc >> 16); } Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=128689&r1=128688&r2=128689&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Thu Mar 31 18:26:08 2011 @@ -200,6 +200,59 @@ } namespace ARMII { + + /// ARM Index Modes + enum IndexMode { + IndexModeNone = 0, + IndexModePre = 1, + IndexModePost = 2, + IndexModeUpd = 3 + }; + + /// ARM Addressing Modes + enum AddrMode { + AddrModeNone = 0, + AddrMode1 = 1, + AddrMode2 = 2, + AddrMode3 = 3, + AddrMode4 = 4, + AddrMode5 = 5, + AddrMode6 = 6, + AddrModeT1_1 = 7, + AddrModeT1_2 = 8, + AddrModeT1_4 = 9, + AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data + AddrModeT2_i12 = 11, + AddrModeT2_i8 = 12, + AddrModeT2_so = 13, + AddrModeT2_pc = 14, // +/- i12 for pc relative data + AddrModeT2_i8s4 = 15, // i8 * 4 + AddrMode_i12 = 16 + }; + + inline static const char *AddrModeToString(AddrMode addrmode) { + switch (addrmode) { + default: llvm_unreachable("Unknown memory operation"); + case AddrModeNone: return "AddrModeNone"; + case AddrMode1: return "AddrMode1"; + case AddrMode2: return "AddrMode2"; + case AddrMode3: return "AddrMode3"; + case AddrMode4: return "AddrMode4"; + case AddrMode5: return "AddrMode5"; + case AddrMode6: return "AddrMode6"; + case AddrModeT1_1: return "AddrModeT1_1"; + case AddrModeT1_2: return "AddrModeT1_2"; + case AddrModeT1_4: return "AddrModeT1_4"; + case AddrModeT1_s: return "AddrModeT1_s"; + case AddrModeT2_i12: return "AddrModeT2_i12"; + case AddrModeT2_i8: return "AddrModeT2_i8"; + case AddrModeT2_so: return "AddrModeT2_so"; + case AddrModeT2_pc: return "AddrModeT2_pc"; + case AddrModeT2_i8s4: return "AddrModeT2_i8s4"; + case AddrMode_i12: return "AddrMode_i12"; + } + } + /// Target Operand Flag enum. enum TOF { //===------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=128689&r1=128688&r2=128689&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Thu Mar 31 18:26:08 2011 @@ -34,25 +34,7 @@ //===------------------------------------------------------------------===// // This four-bit field describes the addressing mode used. - - AddrModeMask = 0x1f, - AddrModeNone = 0, - AddrMode1 = 1, - AddrMode2 = 2, - AddrMode3 = 3, - AddrMode4 = 4, - AddrMode5 = 5, - AddrMode6 = 6, - AddrModeT1_1 = 7, - AddrModeT1_2 = 8, - AddrModeT1_4 = 9, - AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data - AddrModeT2_i12 = 11, - AddrModeT2_i8 = 12, - AddrModeT2_so = 13, - AddrModeT2_pc = 14, // +/- i12 for pc relative data - AddrModeT2_i8s4 = 15, // i8 * 4 - AddrMode_i12 = 16, + AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h // Size* - Flags to keep track of the size of an instruction. SizeShift = 5, @@ -64,11 +46,9 @@ // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load // and store ops only. Generic "updating" flag is used for ld/st multiple. + // The index mode enums are declared in ARMBaseInfo.h IndexModeShift = 8, IndexModeMask = 3 << IndexModeShift, - IndexModePre = 1, - IndexModePost = 2, - IndexModeUpd = 3, //===------------------------------------------------------------------===// // Instruction encoding formats. Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128689&r1=128688&r2=128689&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu Mar 31 18:26:08 2011 @@ -525,6 +525,24 @@ let Inst{19-16} = Rn; let Inst{11-0} = offset{11-0}; } +// FIXME: Merge with the above class when addrmode2 gets used for STR, STRB +// but for now use this class for STRT and STRBT. +class AI2stridxT pattern> + : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, + pattern> { + // AM2 store w/ two operands: (GPR, am2offset) + // {17-14} Rn + // {13} 1 == Rm, 0 == imm12 + // {12} isAdd + // {11-0} imm12/Rm + bits<18> addr; + let Inst{25} = addr{13}; + let Inst{23} = addr{12}; + let Inst{19-16} = addr{17-14}; + let Inst{11-0} = addr{11-0}; +} // addrmode3 instructions class AI3ld op, bit op20, dag oops, dag iops, Format f, Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128689&r1=128688&r2=128689&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Mar 31 18:26:08 2011 @@ -498,6 +498,12 @@ let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } +def MemMode2AsmOperand : AsmOperandClass { + let Name = "MemMode2"; + let SuperClasses = []; + let ParserMethod = "tryParseMemMode2Operand"; +} + // addrmode2 := reg +/- imm12 // := reg +/- reg shop imm // @@ -505,6 +511,7 @@ ComplexPattern { let EncoderMethod = "getAddrMode2OpValue"; let PrintMethod = "printAddrMode2Operand"; + let ParserMatchClass = MemMode2AsmOperand; let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } @@ -1668,6 +1675,7 @@ let Inst{23} = addr{12}; let Inst{19-16} = addr{17-14}; let Inst{11-0} = addr{11-0}; + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; } def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), (ins GPR:$Rn, am2offset:$offset), @@ -1726,17 +1734,35 @@ // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. let mayLoad = 1, neverHasSideEffects = 1 in { -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb), - (ins GPR:$base, am2offset:$offset), IndexModePost, - LdFrm, IIC_iLoad_ru, - "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { +def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb), + (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru, + "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { + // {17-14} Rn + // {13} 1 == Rm, 0 == imm12 + // {12} isAdd + // {11-0} imm12/Rm + bits<18> addr; + let Inst{25} = addr{13}; + let Inst{23} = addr{12}; let Inst{21} = 1; // overwrite -} -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb), - (ins GPR:$base, am2offset:$offset), IndexModePost, - LdFrm, IIC_iLoad_bh_ru, - "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> { + let Inst{19-16} = addr{17-14}; + let Inst{11-0} = addr{11-0}; + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; +} +def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), + (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru, + "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { + // {17-14} Rn + // {13} 1 == Rm, 0 == imm12 + // {12} isAdd + // {11-0} imm12/Rm + bits<18> addr; + let Inst{25} = addr{13}; + let Inst{23} = addr{12}; let Inst{21} = 1; // overwrite + let Inst{19-16} = addr{17-14}; + let Inst{11-0} = addr{11-0}; + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; } def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb), (ins GPR:$base, am3offset:$offset), IndexModePost, @@ -1830,20 +1856,20 @@ // STRT, STRBT, and STRHT are for disassembly only. -def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn,am2offset:$offset), - IndexModePost, StFrm, IIC_iStore_ru, - "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", - [/* For disassembly only; pattern left blank */]> { +def STRT : AI2stridxT<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), + IndexModePost, StFrm, IIC_iStore_ru, + "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb", + [/* For disassembly only; pattern left blank */]> { let Inst{21} = 1; // overwrite + let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; } -def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), - IndexModePost, StFrm, IIC_iStore_bh_ru, - "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", - [/* For disassembly only; pattern left blank */]> { +def STRBT : AI2stridxT<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), + IndexModePost, StFrm, IIC_iStore_bh_ru, + "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb", + [/* For disassembly only; pattern left blank */]> { let Inst{21} = 1; // overwrite + let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; } def STRHT: AI3sthpo<(outs GPR:$base_wb), @@ -3403,8 +3429,9 @@ let Inst{23-20} = opc1; } -class ACI - : I + : I { let Inst{27-25} = 0b110; } @@ -3423,7 +3450,7 @@ def _PRE : ACI<(outs), (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - opc, "\tp$cop, cr$CRd, $addr!"> { + opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> { let Inst{31-28} = op31_28; let Inst{24} = 1; // P = 1 let Inst{21} = 1; // W = 1 @@ -3432,8 +3459,8 @@ } def _POST : ACI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), - opc, "\tp$cop, cr$CRd, [$base], $offset"> { + (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), + opc, "\tp$cop, cr$CRd, $addr", IndexModePost> { let Inst{31-28} = op31_28; let Inst{24} = 0; // P = 0 let Inst{21} = 1; // W = 1 @@ -3464,7 +3491,7 @@ def L_PRE : ACI<(outs), (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> { let Inst{31-28} = op31_28; let Inst{24} = 1; // P = 1 let Inst{21} = 1; // W = 1 @@ -3473,8 +3500,8 @@ } def L_POST : ACI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> { + (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr", IndexModePost> { let Inst{31-28} = op31_28; let Inst{24} = 0; // P = 0 let Inst{21} = 1; // W = 1 Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128689&r1=128688&r2=128689&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Mar 31 18:26:08 2011 @@ -48,7 +48,8 @@ bool TryParseRegisterWithWriteBack(SmallVectorImpl &); bool TryParseShiftRegister(SmallVectorImpl &); bool ParseRegisterList(SmallVectorImpl &); - bool ParseMemory(SmallVectorImpl &); + bool ParseMemory(SmallVectorImpl &, + ARMII::AddrMode AddrMode); bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic); bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); const MCExpr *ApplyPrefixToExpr(const MCExpr *E, @@ -95,6 +96,14 @@ SmallVectorImpl&); OperandMatchResultTy tryParseMSRMaskOperand( SmallVectorImpl&); + OperandMatchResultTy tryParseMemMode2Operand( + SmallVectorImpl&); + + // Asm Match Converter Methods + bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &); + bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &); public: ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) @@ -172,6 +181,7 @@ /// Combined record for all forms of ARM address expressions. struct { + ARMII::AddrMode AddrMode; unsigned BaseRegNum; union { unsigned RegNum; ///< Offset register num, when OffsetIsReg. @@ -293,7 +303,9 @@ /// @name Memory Operand Accessors /// @{ - + ARMII::AddrMode getMemAddrMode() const { + return Mem.AddrMode; + } unsigned getMemBaseRegNum() const { return Mem.BaseRegNum; } @@ -338,6 +350,27 @@ bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } bool isMemory() const { return Kind == Memory; } bool isShifter() const { return Kind == Shifter; } + bool isMemMode2() const { + if (getMemAddrMode() != ARMII::AddrMode2) + return false; + + if (getMemOffsetIsReg()) + return true; + + if (getMemNegative() && + !(getMemPostindexed() || getMemPreindexed())) + return false; + + const MCConstantExpr *CE = dyn_cast(getMemOffset()); + if (!CE) return false; + int64_t Value = CE->getValue(); + + // The offset must be in the range 0-4095 (imm12). + if (Value > 4095 || Value < -4095) + return false; + + return true; + } bool isMemMode5() const { if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || getMemNegative()) @@ -465,6 +498,47 @@ "No offset operand support in mode 7"); } + void addMemMode2Operands(MCInst &Inst, unsigned N) const { + assert(isMemMode2() && "Invalid mode or number of operands!"); + Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); + unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); + + if (getMemOffsetIsReg()) { + Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); + + ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; + ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; + int64_t ShiftAmount = 0; + + if (getMemOffsetRegShifted()) { + ShOpc = getMemShiftType(); + const MCConstantExpr *CE = + dyn_cast(getMemShiftAmount()); + ShiftAmount = CE->getValue(); + } + + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, + ShOpc, IdxMode))); + return; + } + + // Create a operand placeholder to always yield the same number of operands. + Inst.addOperand(MCOperand::CreateReg(0)); + + // FIXME: #-0 is encoded differently than #0. Does the parser preserve + // the difference? + const MCConstantExpr *CE = dyn_cast(getMemOffset()); + assert(CE && "Non-constant mode 2 offset operand!"); + int64_t Offset = CE->getValue(); + + if (Offset >= 0) + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, + Offset, ARM_AM::no_shift, IdxMode))); + else + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, + -Offset, ARM_AM::no_shift, IdxMode))); + } + void addMemMode5Operands(MCInst &Inst, unsigned N) const { assert(N == 2 && isMemMode5() && "Invalid number of operands!"); @@ -599,9 +673,9 @@ return Op; } - static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, - const MCExpr *Offset, int OffsetRegNum, - bool OffsetRegShifted, + static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, + bool OffsetIsReg, const MCExpr *Offset, + int OffsetRegNum, bool OffsetRegShifted, enum ARM_AM::ShiftOpc ShiftType, const MCExpr *ShiftAmount, bool Preindexed, bool Postindexed, bool Negative, bool Writeback, @@ -618,6 +692,7 @@ "Cannot have expression offset and register offset!"); ARMOperand *Op = new ARMOperand(Memory); + Op->Mem.AddrMode = AddrMode; Op->Mem.BaseRegNum = BaseRegNum; Op->Mem.OffsetIsReg = OffsetIsReg; if (OffsetIsReg) @@ -689,7 +764,8 @@ break; case Memory: OS << " &Operands) { + SMLoc S = Parser.getTok().getLoc(); + const AsmToken &Tok = Parser.getTok(); + assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\""); + + if (ParseMemory(Operands, ARMII::AddrMode2)) + return MatchOperand_NoMatch; + + return MatchOperand_Success; +} + +/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. +/// Needed here because the Asm Gen Matcher can't handle properly tied operands +/// when they refer multiple MIOperands inside a single one. +bool ARMAsmParser:: +CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &Operands) { + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); + + // Create a writeback register dummy placeholder. + Inst.addOperand(MCOperand::CreateImm(0)); + + ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); + return true; +} + +/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. +/// Needed here because the Asm Gen Matcher can't handle properly tied operands +/// when they refer multiple MIOperands inside a single one. +bool ARMAsmParser:: +CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &Operands) { + // Create a writeback register dummy placeholder. + Inst.addOperand(MCOperand::CreateImm(0)); + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); + ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); + return true; +} + /// Parse an ARM memory expression, return false if successful else return true /// or an error. The first token must be a '[' when called. /// /// TODO Only preindexing and postindexing addressing are started, unindexed /// with option, etc are still to do. bool ARMAsmParser:: -ParseMemory(SmallVectorImpl &Operands) { +ParseMemory(SmallVectorImpl &Operands, + ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { SMLoc S, E; assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a Left Bracket"); @@ -1196,6 +1316,9 @@ ExclaimTok.getLoc()); Writeback = true; Parser.Lex(); // Eat exclaim token + } else { // In addressing mode 2, pre-indexed mode always end with "!" + if (AddrMode == ARMII::AddrMode2) + Preindexed = false; } } else { // The "[Rn" we have so far was not followed by a comma. @@ -1231,11 +1354,10 @@ Offset = MCConstantExpr::Create(0, getContext()); } - Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, - OffsetRegNum, OffsetRegShifted, - ShiftType, ShiftAmount, Preindexed, - Postindexed, Negative, Writeback, - S, E)); + Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, + Offset, OffsetRegNum, OffsetRegShifted, + ShiftType, ShiftAmount, Preindexed, + Postindexed, Negative, Writeback, S, E)); if (WBOp) Operands.push_back(WBOp); Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128689&r1=128688&r2=128689&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Thu Mar 31 18:26:08 2011 @@ -643,8 +643,11 @@ if (PW) { MI.addOperand(MCOperand::CreateReg(0)); ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; + const TargetInstrDesc &TID = ARMInsts[Opcode]; + unsigned IndexMode = + (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << 2, - ARM_AM::no_shift); + ARM_AM::no_shift, IndexMode); MI.addOperand(MCOperand::CreateImm(Offset)); OpIdx = 5; } else { @@ -1084,6 +1087,8 @@ return false; ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; + unsigned IndexMode = + (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; if (getIBit(insn) == 0) { // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2). // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already @@ -1095,7 +1100,8 @@ // Disassemble the 12-bit immediate offset. unsigned Imm12 = slice(insn, 11, 0); - unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift); + unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift, + IndexMode); MI.addOperand(MCOperand::CreateImm(Offset)); OpIdx += 1; } else { @@ -1110,7 +1116,7 @@ // A8.4.1. Possible rrx or shift amount of 32... getImmShiftSE(ShOp, ShImm); MI.addOperand(MCOperand::CreateImm( - ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp))); + ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, IndexMode))); OpIdx += 2; } Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=128689&r1=128688&r2=128689&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Thu Mar 31 18:26:08 2011 @@ -181,18 +181,12 @@ } } - -void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, - raw_ostream &O) { +void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, + raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(Op); const MCOperand &MO2 = MI->getOperand(Op+1); const MCOperand &MO3 = MI->getOperand(Op+2); - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. - printOperand(MI, Op, O); - return; - } - O << "[" << getRegisterName(MO1.getReg()); if (!MO2.getReg()) { @@ -215,6 +209,50 @@ O << "]"; } +void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, + raw_ostream &O) { + const MCOperand &MO1 = MI->getOperand(Op); + const MCOperand &MO2 = MI->getOperand(Op+1); + const MCOperand &MO3 = MI->getOperand(Op+2); + + O << "[" << getRegisterName(MO1.getReg()) << "], "; + + if (!MO2.getReg()) { + unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); + O << '#' + << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) + << ImmOffs; + return; + } + + O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) + << getRegisterName(MO2.getReg()); + + if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) + O << ", " + << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) + << " #" << ShImm; +} + +void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, + raw_ostream &O) { + const MCOperand &MO1 = MI->getOperand(Op); + + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. + printOperand(MI, Op, O); + return; + } + + const MCOperand &MO3 = MI->getOperand(Op+2); + unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm()); + + if (IdxMode == ARMII::IndexModePost) { + printAM2PostIndexOp(MI, Op, O); + return; + } + printAM2PreOrOffsetIndexOp(MI, Op, O); +} + void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) { Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=128689&r1=128688&r2=128689&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Thu Mar 31 18:26:08 2011 @@ -42,7 +42,11 @@ void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, + raw_ostream &O); void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); Added: llvm/trunk/test/MC/ARM/arm_addrmode2.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128689&view=auto ============================================================================== --- llvm/trunk/test/MC/ARM/arm_addrmode2.s (added) +++ llvm/trunk/test/MC/ARM/arm_addrmode2.s Thu Mar 31 18:26:08 2011 @@ -0,0 +1,34 @@ +@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | FileCheck %s + +@ Post-indexed +@ CHECK: ldrt r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6] +@ CHECK: ldrt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6] +@ CHECK: ldrt r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4] +@ CHECK: ldrbt r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6] +@ CHECK: ldrbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6] +@ CHECK: ldrbt r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4] +@ CHECK: strt r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6] +@ CHECK: strt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6] +@ CHECK: strt r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4] +@ CHECK: strbt r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6] +@ CHECK: strbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6] +@ CHECK: strbt r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4] + ldrt r1, [r0], r2 + ldrt r1, [r0], r2, lsr #3 + ldrt r1, [r0], #4 + ldrbt r1, [r0], r2 + ldrbt r1, [r0], r2, lsr #3 + ldrbt r1, [r0], #4 + strt r1, [r0], r2 + strt r1, [r0], r2, lsr #3 + strt r1, [r0], #4 + strbt r1, [r0], r2 + strbt r1, [r0], r2, lsr #3 + strbt r1, [r0], #4 + +@ Pre-indexed +@ CHECK: ldr r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7] +@ CHECK: ldrb r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7] + ldr r1, [r0, r2, lsr #3]! + ldrb r1, [r0, r2, lsr #3]! + From stoklund at 2pi.dk Thu Mar 31 18:31:51 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 31 Mar 2011 23:31:51 -0000 Subject: [llvm-commits] [llvm] r128690 - in /llvm/trunk/test/CodeGen: Thumb/dyn-stackalloc.ll Thumb2/2009-10-15-ITBlockBranch.ll Thumb2/2010-03-15-AsmCCClobber.ll Thumb2/ldr-str-imm12.ll Thumb2/thumb2-ldrd.ll Message-ID: <20110331233151.1ED7C2A6C12C@llvm.org> Author: stoklund Date: Thu Mar 31 18:31:50 2011 New Revision: 128690 URL: http://llvm.org/viewvc/llvm-project?rev=128690&view=rev Log: Fix Thumb and Thumb2 tests to be register allocator independent. Modified: llvm/trunk/test/CodeGen/Thumb/dyn-stackalloc.ll llvm/trunk/test/CodeGen/Thumb2/2009-10-15-ITBlockBranch.ll llvm/trunk/test/CodeGen/Thumb2/2010-03-15-AsmCCClobber.ll llvm/trunk/test/CodeGen/Thumb2/ldr-str-imm12.ll llvm/trunk/test/CodeGen/Thumb2/thumb2-ldrd.ll Modified: llvm/trunk/test/CodeGen/Thumb/dyn-stackalloc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb/dyn-stackalloc.ll?rev=128690&r1=128689&r2=128690&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb/dyn-stackalloc.ll (original) +++ llvm/trunk/test/CodeGen/Thumb/dyn-stackalloc.ll Thu Mar 31 18:31:50 2011 @@ -1,4 +1,5 @@ -; RUN: llc < %s -mtriple=thumb-apple-darwin -disable-cgp-branch-opts | FileCheck %s +; RUN: llc < %s -mtriple=thumb-apple-darwin -disable-cgp-branch-opts -disable-post-ra | FileCheck %s +; RUN: llc < %s -mtriple=thumb-apple-darwin -disable-cgp-branch-opts -disable-post-ra -regalloc=basic | FileCheck %s %struct.state = type { i32, %struct.info*, float**, i32, i32, i32, i32, i32, i32, i32, i32, i32, i64, i64, i64, i64, i64, i64, i8* } %struct.info = type { i32, i32, i32, i32, i32, i32, i32, i8* } @@ -7,9 +8,10 @@ ; CHECK: t1: ; CHECK: push ; CHECK: add r7, sp, #12 -; CHECK: mov r2, sp -; CHECK: subs r4, r2, r1 -; CHECK: mov sp, r4 +; CHECK: lsls r[[R0:[0-9]+]] +; CHECK: mov r[[R1:[0-9]+]], sp +; CHECK: subs r[[R2:[0-9]+]], r[[R1]], r[[R0]] +; CHECK: mov sp, r[[R2]] %tmp6 = load i32* null %tmp8 = alloca float, i32 %tmp6 store i32 1, i32* null @@ -40,15 +42,16 @@ ; CHECK: t2: ; CHECK: push ; CHECK: add r7, sp, #12 -; CHECK: sub sp, #8 -; CHECK: mov r6, sp -; CHECK: str r2, [r6, #4] -; CHECK: str r0, [r6] +; CHECK: sub sp, # +; CHECK: mov r[[R0:[0-9]+]], sp +; CHECK: str r{{[0-9+]}}, [r[[R0]] +; CHECK: str r{{[0-9+]}}, [r[[R0]] ; CHECK-NOT: ldr r0, [sp -; CHECK: ldr r0, [r6, #4] -; CHECK: mov r0, sp -; CHECK: subs r5, r0, r1 -; CHECK: mov sp, r5 +; CHECK: mov r[[R1:[0-9]+]], sp +; CHECK: subs r[[R2:[0-9]+]], r[[R1]], r{{[0-9]+}} +; CHECK: mov sp, r[[R2]] +; CHECK-NOT: ldr r0, [sp +; CHECK: bx %tmp1 = call i32 @strlen( i8* %tag ) %tmp3 = call i32 @strlen( i8* %contents ) %tmp4 = add i32 %tmp1, 2 Modified: llvm/trunk/test/CodeGen/Thumb2/2009-10-15-ITBlockBranch.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/2009-10-15-ITBlockBranch.ll?rev=128690&r1=128689&r2=128690&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/2009-10-15-ITBlockBranch.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/2009-10-15-ITBlockBranch.ll Thu Mar 31 18:31:50 2011 @@ -1,4 +1,5 @@ ; RUN: llc < %s -mtriple=thumbv7-eabi -mcpu=cortex-a8 -float-abi=hard | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7-eabi -mcpu=cortex-a8 -float-abi=hard -regalloc=basic | FileCheck %s ; PR5204 %"struct.__gnu_cxx::__normal_iterator, std::allocator > >" = type { i8* } @@ -11,7 +12,7 @@ define weak arm_aapcs_vfpcc i32 @_ZNKSs7compareERKSs(%"struct.std::basic_string,std::allocator >"* %this, %"struct.std::basic_string,std::allocator >"* %__str) { ; CHECK: _ZNKSs7compareERKSs: ; CHECK: it eq -; CHECK-NEXT: subeq r0, r6, r7 +; CHECK-NEXT: subeq r0, r{{[0-9]+}}, r{{[0-9]+}} ; CHECK-NEXT: ldmia.w sp!, {r4, r5, r6, r7, r8, pc} entry: %0 = tail call arm_aapcs_vfpcc i32 @_ZNKSs4sizeEv(%"struct.std::basic_string,std::allocator >"* %this) ; [#uses=3] Modified: llvm/trunk/test/CodeGen/Thumb2/2010-03-15-AsmCCClobber.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/2010-03-15-AsmCCClobber.ll?rev=128690&r1=128689&r2=128690&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/2010-03-15-AsmCCClobber.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/2010-03-15-AsmCCClobber.ll Thu Mar 31 18:31:50 2011 @@ -1,10 +1,11 @@ ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 \ -; RUN: -pre-RA-sched=source | FileCheck -check-prefix=SOURCE %s +; RUN: -pre-RA-sched=source | FileCheck %s ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 \ -; RUN: -pre-RA-sched=list-hybrid | FileCheck -check-prefix=HYBRID %s +; RUN: -pre-RA-sched=list-hybrid | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -regalloc=basic | FileCheck %s ; Radar 7459078 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32" - + %0 = type { i32, i32 } %s1 = type { %s3, i32, %s4, i8*, void (i8*, i8*)*, i8*, i32*, i32*, i32*, i32, i64, [1 x i32] } %s2 = type { i32 (...)**, %s4 } @@ -13,11 +14,10 @@ %s5 = type { i32 } ; Make sure the cmp is not scheduled before the InlineAsm that clobbers cc. -; SOURCE: InlineAsm End -; SOURCE: cmp -; SOURCE: beq -; HYBRID: InlineAsm End -; HYBRID: cbz +; CHECK: blx _f2 +; CHECK: cmp r0, #0 +; CHECK-NOT: cmp +; CHECK: InlineAsm Start define void @test(%s1* %this, i32 %format, i32 %w, i32 %h, i32 %levels, i32* %s, i8* %data, i32* nocapture %rowbytes, void (i8*, i8*)* %release, i8* %info) nounwind { entry: %tmp1 = getelementptr inbounds %s1* %this, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0 Modified: llvm/trunk/test/CodeGen/Thumb2/ldr-str-imm12.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/ldr-str-imm12.ll?rev=128690&r1=128689&r2=128690&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/ldr-str-imm12.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/ldr-str-imm12.ll Thu Mar 31 18:31:50 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim -regalloc=linearscan | FileCheck %s ; rdar://7352504 ; Make sure we use "str r9, [sp, #+28]" instead of "sub.w r4, r7, #256" followed by "str r9, [r4, #-32]". Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-ldrd.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-ldrd.ll?rev=128690&r1=128689&r2=128690&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/thumb2-ldrd.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/thumb2-ldrd.ll Thu Mar 31 18:31:50 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mattr=+thumb2 | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mattr=+thumb2 -regalloc=linearscan | FileCheck %s @b = external global i64* From matthewbg at google.com Thu Mar 31 19:06:01 2011 From: matthewbg at google.com (Matt Beaumont-Gay) Date: Fri, 01 Apr 2011 00:06:01 -0000 Subject: [llvm-commits] [llvm] r128692 - /llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Message-ID: <20110401000601.DCBC22A6C12C@llvm.org> Author: matthewbg Date: Thu Mar 31 19:06:01 2011 New Revision: 128692 URL: http://llvm.org/viewvc/llvm-project?rev=128692&view=rev Log: Remove unused variables Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128692&r1=128691&r2=128692&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Mar 31 19:06:01 2011 @@ -1211,9 +1211,7 @@ /// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand. ARMAsmParser::OperandMatchResultTy ARMAsmParser:: tryParseMemMode2Operand(SmallVectorImpl &Operands) { - SMLoc S = Parser.getTok().getLoc(); - const AsmToken &Tok = Parser.getTok(); - assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\""); + assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\""); if (ParseMemory(Operands, ARMII::AddrMode2)) return MatchOperand_NoMatch; From clattner at apple.com Thu Mar 31 19:13:19 2011 From: clattner at apple.com (Chris Lattner) Date: Thu, 31 Mar 2011 17:13:19 -0700 Subject: [llvm-commits] [PATCH] simplify various Instructions' resizeOperands() methods In-Reply-To: References: Message-ID: <7B0C312F-E7A2-4F44-8A5C-4E82CCEA790F@apple.com> On Mar 30, 2011, at 5:27 AM, Jay Foad wrote: > Various Instructions have resizeOperands() methods. Since this patch: > > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20110328/118717.html > > ... they are all only called with an argument of 0. Simplify them accordingly. > > (Maybe resizeOperands() should be renamed now that it always just > grows the list of operands by some constant factor, but I couldn't > think of a good new name.) > > Tested with "make check", LLVM and Clang. OK to apply? Looks good to me, with the rename to "growOperands". Thanks Jay! -Chris From evan.cheng at apple.com Thu Mar 31 19:42:02 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 01 Apr 2011 00:42:02 -0000 Subject: [llvm-commits] [llvm] r128696 - in /llvm/trunk: include/llvm/CodeGen/RuntimeLibcalls.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/ARM/ARMISelLowering.cpp Message-ID: <20110401004202.4F7412A6C12C@llvm.org> Author: evancheng Date: Thu Mar 31 19:42:02 2011 New Revision: 128696 URL: http://llvm.org/viewvc/llvm-project?rev=128696&view=rev Log: Issue libcalls __udivmod*i4 / __divmod*i4 for div / rem pairs. rdar://8911343 Modified: llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h?rev=128696&r1=128695&r2=128696&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h (original) +++ llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h Thu Mar 31 19:42:02 2011 @@ -66,6 +66,16 @@ UREM_I32, UREM_I64, UREM_I128, + SDIVREM_I8, + SDIVREM_I16, + SDIVREM_I32, + SDIVREM_I64, + SDIVREM_I128, + UDIVREM_I8, + UDIVREM_I16, + UDIVREM_I32, + UDIVREM_I64, + UDIVREM_I128, NEG_I32, NEG_I64, Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=128696&r1=128695&r2=128696&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Mar 31 19:42:02 2011 @@ -153,6 +153,7 @@ RTLIB::Libcall Call_I32, RTLIB::Libcall Call_I64, RTLIB::Libcall Call_I128); + SDValue ExpandDivRemLibCall(SDNode *Node, bool isSigned, bool isDIV); SDValue EmitStackConvert(SDValue SrcOp, EVT SlotVT, EVT DestVT, DebugLoc dl); SDValue ExpandBUILD_VECTOR(SDNode *Node); @@ -786,7 +787,7 @@ } } } - return SDValue(); + return SDValue(0, 0); } /// LegalizeOp - We know that the specified value has a legal type, and @@ -2114,6 +2115,116 @@ return ExpandLibCall(LC, Node, isSigned); } +/// ExpandDivRemLibCall - Issue libcalls to __{u}divmod to compute div / rem +/// pairs. +SDValue SelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node, bool isSigned, + bool isDIV) { + RTLIB::Libcall LC; + switch (Node->getValueType(0).getSimpleVT().SimpleTy) { + default: assert(0 && "Unexpected request for libcall!"); + case MVT::i8: LC= isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break; + case MVT::i16: LC= isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break; + case MVT::i32: LC= isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break; + case MVT::i64: LC= isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; break; + case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128; break; + } + + if (!TLI.getLibcallName(LC)) + return SDValue(); + + // Only issue divrem libcall if both quotient and remainder are needed. + unsigned OtherOpcode = 0; + if (isSigned) { + OtherOpcode = isDIV ? ISD::SREM : ISD::SDIV; + } else { + OtherOpcode = isDIV ? ISD::UREM : ISD::UDIV; + } + SDNode *OtherNode = 0; + SDValue Op0 = Node->getOperand(0); + SDValue Op1 = Node->getOperand(1); + for (SDNode::use_iterator UI = Op0.getNode()->use_begin(), + UE = Op0.getNode()->use_end(); UI != UE; ++UI) { + SDNode *User = *UI; + if (User == Node) + continue; + if (User->getOpcode() == OtherOpcode && + User->getOperand(0) == Op0 && + User->getOperand(1) == Op1) { + OtherNode = User; + break; + } + } + if (!OtherNode) + return SDValue(); + + // If the libcall is already generated, no need to issue it again. + DenseMap::iterator I + = LegalizedNodes.find(SDValue(OtherNode,0)); + if (I != LegalizedNodes.end()) { + OtherNode = I->second.getNode(); + SDNode *Chain = OtherNode->getOperand(0).getNode(); + for (SDNode::use_iterator UI = Chain->use_begin(), UE = Chain->use_end(); + UI != UE; ++UI) { + SDNode *User = *UI; + if (User == OtherNode) + continue; + if (isDIV) { + assert(User->getOpcode() == ISD::CopyFromReg); + } else { + assert(User->getOpcode() == ISD::LOAD); + } + return SDValue(User, 0); + } + } + + // The input chain to this libcall is the entry node of the function. + // Legalizing the call will automatically add the previous call to the + // dependence. + SDValue InChain = DAG.getEntryNode(); + + EVT RetVT = Node->getValueType(0); + const Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); + + TargetLowering::ArgListTy Args; + TargetLowering::ArgListEntry Entry; + for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { + EVT ArgVT = Node->getOperand(i).getValueType(); + const Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); + Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; + Entry.isSExt = isSigned; + Entry.isZExt = !isSigned; + Args.push_back(Entry); + } + + // Also pass the return address of the remainder. + SDValue FIPtr = DAG.CreateStackTemporary(RetVT); + Entry.Node = FIPtr; + Entry.Ty = RetTy->getPointerTo(); + Entry.isSExt = isSigned; + Entry.isZExt = !isSigned; + Args.push_back(Entry); + + SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), + TLI.getPointerTy()); + + // Splice the libcall in wherever FindInputOutputChains tells us to. + DebugLoc dl = Node->getDebugLoc(); + std::pair CallInfo = + TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, + 0, TLI.getLibcallCallingConv(LC), /*isTailCall=*/false, + /*isReturnValueUsed=*/true, Callee, Args, DAG, dl); + + // Legalize the call sequence, starting with the chain. This will advance + // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that + // was added by LowerCallTo (guaranteeing proper serialization of calls). + LegalizeOp(CallInfo.second); + + // Remainder is loaded back from the stack frame. + SDValue Rem = DAG.getLoad(RetVT, dl, LastCALLSEQ_END, FIPtr, + MachinePointerInfo(), false, false, 0); + return isDIV ? CallInfo.first : Rem; +} + /// ExpandLegalINT_TO_FP - This function is responsible for legalizing a /// INT_TO_FP operation of the specified operand when the target requests that /// we expand it. At this point, we know that the result and operand types are @@ -3095,15 +3206,19 @@ Tmp1 = DAG.getNode(ISD::MUL, dl, VT, Tmp1, Tmp3); Tmp1 = DAG.getNode(ISD::SUB, dl, VT, Tmp2, Tmp1); } else if (isSigned) { - Tmp1 = ExpandIntLibCall(Node, true, - RTLIB::SREM_I8, - RTLIB::SREM_I16, RTLIB::SREM_I32, - RTLIB::SREM_I64, RTLIB::SREM_I128); + Tmp1 = ExpandDivRemLibCall(Node, true, false); + if (!Tmp1.getNode()) + Tmp1 = ExpandIntLibCall(Node, true, + RTLIB::SREM_I8, + RTLIB::SREM_I16, RTLIB::SREM_I32, + RTLIB::SREM_I64, RTLIB::SREM_I128); } else { - Tmp1 = ExpandIntLibCall(Node, false, - RTLIB::UREM_I8, - RTLIB::UREM_I16, RTLIB::UREM_I32, - RTLIB::UREM_I64, RTLIB::UREM_I128); + Tmp1 = ExpandDivRemLibCall(Node, false, false); + if (!Tmp1.getNode()) + Tmp1 = ExpandIntLibCall(Node, false, + RTLIB::UREM_I8, + RTLIB::UREM_I16, RTLIB::UREM_I32, + RTLIB::UREM_I64, RTLIB::UREM_I128); } Results.push_back(Tmp1); break; @@ -3117,16 +3232,23 @@ if (TLI.isOperationLegalOrCustom(DivRemOpc, VT)) Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Node->getOperand(0), Node->getOperand(1)); - else if (isSigned) - Tmp1 = ExpandIntLibCall(Node, true, - RTLIB::SDIV_I8, - RTLIB::SDIV_I16, RTLIB::SDIV_I32, - RTLIB::SDIV_I64, RTLIB::SDIV_I128); - else - Tmp1 = ExpandIntLibCall(Node, false, - RTLIB::UDIV_I8, - RTLIB::UDIV_I16, RTLIB::UDIV_I32, - RTLIB::UDIV_I64, RTLIB::UDIV_I128); + else if (isSigned) { + Tmp1 = ExpandDivRemLibCall(Node, true, true); + if (!Tmp1.getNode()) { + Tmp1 = ExpandIntLibCall(Node, true, + RTLIB::SDIV_I8, + RTLIB::SDIV_I16, RTLIB::SDIV_I32, + RTLIB::SDIV_I64, RTLIB::SDIV_I128); + } + } else { + Tmp1 = ExpandDivRemLibCall(Node, false, true); + if (!Tmp1.getNode()) { + Tmp1 = ExpandIntLibCall(Node, false, + RTLIB::UDIV_I8, + RTLIB::UDIV_I16, RTLIB::UDIV_I32, + RTLIB::UDIV_I64, RTLIB::UDIV_I128); + } + } Results.push_back(Tmp1); break; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=128696&r1=128695&r2=128696&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Thu Mar 31 19:42:02 2011 @@ -93,6 +93,19 @@ Names[RTLIB::UREM_I32] = "__umodsi3"; Names[RTLIB::UREM_I64] = "__umoddi3"; Names[RTLIB::UREM_I128] = "__umodti3"; + + // These are generally not available. + Names[RTLIB::SDIVREM_I8] = 0; + Names[RTLIB::SDIVREM_I16] = 0; + Names[RTLIB::SDIVREM_I32] = 0; + Names[RTLIB::SDIVREM_I64] = 0; + Names[RTLIB::SDIVREM_I128] = 0; + Names[RTLIB::UDIVREM_I8] = 0; + Names[RTLIB::UDIVREM_I16] = 0; + Names[RTLIB::UDIVREM_I32] = 0; + Names[RTLIB::UDIVREM_I64] = 0; + Names[RTLIB::UDIVREM_I128] = 0; + Names[RTLIB::NEG_I32] = "__negsi2"; Names[RTLIB::NEG_I64] = "__negdi2"; Names[RTLIB::ADD_F32] = "__addsf3"; Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=128696&r1=128695&r2=128696&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu Mar 31 19:42:02 2011 @@ -72,6 +72,11 @@ cl::desc("Enable / disable ARM interworking (for debugging only)"), cl::init(true)); +static cl::opt +UseDivMod("arm-divmod-libcall", cl::Hidden, + cl::desc("Use __{u}divmod libcalls for div / rem pairs"), + cl::init(false)); + void ARMTargetLowering::addTypeForNEON(EVT VT, EVT PromotedLdStVT, EVT PromotedBitwiseVT) { if (VT != PromotedLdStVT) { @@ -393,6 +398,11 @@ setLibcallCallingConv(RTLIB::UDIV_I32, CallingConv::ARM_AAPCS); } + if (UseDivMod) { + setLibcallName(RTLIB::SDIVREM_I32, "__divmodsi4"); + setLibcallName(RTLIB::UDIVREM_I32, "__udivmodsi4"); + } + if (Subtarget->isThumb1Only()) addRegisterClass(MVT::i32, ARM::tGPRRegisterClass); else From eli.friedman at gmail.com Thu Mar 31 19:53:07 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Thu, 31 Mar 2011 17:53:07 -0700 Subject: [llvm-commits] [llvm] r128696 - in /llvm/trunk: include/llvm/CodeGen/RuntimeLibcalls.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/ARM/ARMISelLowering.cpp In-Reply-To: <20110401004202.4F7412A6C12C@llvm.org> References: <20110401004202.4F7412A6C12C@llvm.org> Message-ID: On Thu, Mar 31, 2011 at 5:42 PM, Evan Cheng wrote: > Author: evancheng > Date: Thu Mar 31 19:42:02 2011 > New Revision: 128696 > > URL: http://llvm.org/viewvc/llvm-project?rev=128696&view=rev > Log: > Issue libcalls __udivmod*i4 / __divmod*i4 for div / rem pairs. > > rdar://8911343 > > Modified: > ? ?llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h > ? ?llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp > ? ?llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp > ? ?llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Missing testcase. -Eli From atrick at apple.com Thu Mar 31 20:56:56 2011 From: atrick at apple.com (Andrew Trick) Date: Fri, 01 Apr 2011 01:56:56 -0000 Subject: [llvm-commits] [llvm] r128701 - in /llvm/trunk/utils/TableGen: SubtargetEmitter.cpp SubtargetEmitter.h Message-ID: <20110401015656.28F0E2A6C12C@llvm.org> Author: atrick Date: Thu Mar 31 20:56:55 2011 New Revision: 128701 URL: http://llvm.org/viewvc/llvm-project?rev=128701&view=rev Log: whitespace Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp llvm/trunk/utils/TableGen/SubtargetEmitter.h Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.cpp?rev=128701&r1=128700&r2=128701&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp Thu Mar 31 20:56:55 2011 @@ -31,24 +31,24 @@ // Open enumeration OS << "enum {\n"; - + // For each record for (unsigned i = 0, N = DefList.size(); i < N;) { // Next record Record *Def = DefList[i]; - + // Get and emit name OS << " " << Def->getName(); - + // If bit flags then emit expression (1 << i) if (isBits) OS << " = " << " 1 << " << i; // Depending on 'if more in the list' emit comma if (++i < N) OS << ","; - + OS << "\n"; } - + // Close enumeration OS << "};\n"; } @@ -66,7 +66,7 @@ // Begin feature table OS << "// Sorted (by key) array of values for CPU features.\n" << "static const llvm::SubtargetFeatureKV FeatureKV[] = {\n"; - + // For each feature for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) { // Next feature @@ -75,18 +75,18 @@ const std::string &Name = Feature->getName(); const std::string &CommandLineName = Feature->getValueAsString("Name"); const std::string &Desc = Feature->getValueAsString("Desc"); - + if (CommandLineName.empty()) continue; - + // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in } OS << " { " << "\"" << CommandLineName << "\", " << "\"" << Desc << "\", " << Name << ", "; - const std::vector &ImpliesList = + const std::vector &ImpliesList = Feature->getValueAsListOfDefs("Implies"); - + if (ImpliesList.empty()) { OS << "0"; } else { @@ -97,13 +97,13 @@ } OS << " }"; - + // Depending on 'if more in the list' emit comma if ((i + 1) < N) OS << ","; - + OS << "\n"; } - + // End feature table OS << "};\n"; @@ -126,21 +126,21 @@ // Begin processor table OS << "// Sorted (by key) array of values for CPU subtype.\n" << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n"; - + // For each processor for (unsigned i = 0, N = ProcessorList.size(); i < N;) { // Next processor Record *Processor = ProcessorList[i]; const std::string &Name = Processor->getValueAsString("Name"); - const std::vector &FeatureList = + const std::vector &FeatureList = Processor->getValueAsListOfDefs("Features"); - + // Emit as { "cpu", "description", f1 | f2 | ... fn }, OS << " { " << "\"" << Name << "\", " << "\"Select the " << Name << " processor\", "; - + if (FeatureList.empty()) { OS << "0"; } else { @@ -149,16 +149,16 @@ if (++j < M) OS << " | "; } } - + // The "0" is for the "implies" section of this data structure. OS << ", 0 }"; - + // Depending on 'if more in the list' emit comma if (++i < N) OS << ","; - + OS << "\n"; } - + // End processor table OS << "};\n"; @@ -185,7 +185,7 @@ // Assign itinerary class a unique number ItinClassesMap[ItinClass->getName()] = i; } - + // Emit size of table OS<<"\nenum {\n"; OS<<" ItinClassesSize = " << N << "\n"; @@ -213,21 +213,21 @@ for (unsigned i = 0; i < N;) { // Next stage const Record *Stage = StageList[i]; - + // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc, kind } int Cycles = Stage->getValueAsInt("Cycles"); ItinString += " { " + itostr(Cycles) + ", "; - + // Get unit list const std::vector &UnitList = Stage->getValueAsListOfDefs("Units"); - + // For each unit for (unsigned j = 0, M = UnitList.size(); j < M;) { // Add name and bitwise or ItinString += Name + "FU::" + UnitList[j]->getName(); if (++j < M) ItinString += " | "; } - + int TimeInc = Stage->getValueAsInt("TimeInc"); ItinString += ", " + itostr(TimeInc); @@ -256,7 +256,7 @@ for (unsigned i = 0; i < N;) { // Next operand cycle const int OCycle = OperandCycleList[i]; - + ItinString += " " + itostr(OCycle); if (++i < N) ItinString += ", "; } @@ -292,7 +292,7 @@ // Gather processor iteraries std::vector ProcItinList = Records.getAllDerivedDefinitions("ProcessorItineraries"); - + // If just no itinerary then don't bother if (ProcItinList.size() < 2) return; @@ -332,7 +332,7 @@ // Begin stages table std::string StageTable = "\nstatic const llvm::InstrStage Stages[] = {\n"; StageTable += " { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n"; - + // Begin operand cycle table std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n"; OperandCycleTable += " 0, // No itinerary\n"; @@ -340,32 +340,32 @@ // Begin pipeline bypass table std::string BypassTable = "static const unsigned ForwardingPathes[] = {\n"; BypassTable += " 0, // No itinerary\n"; - + unsigned StageCount = 1, OperandCycleCount = 1; unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1; std::map ItinStageMap, ItinOperandMap; for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) { // Next record Record *Proc = ProcItinList[i]; - + // Get processor itinerary name const std::string &Name = Proc->getName(); - + // Skip default if (Name == "NoItineraries") continue; - + // Create and expand processor itinerary to cover all itinerary classes std::vector ItinList; ItinList.resize(NItinClasses); - + // Get itinerary data list std::vector ItinDataList = Proc->getValueAsListOfDefs("IID"); - + // For each itinerary data for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) { // Next itinerary data Record *ItinData = ItinDataList[j]; - + // Get string and stage count std::string ItinStageString; unsigned NStages; @@ -394,7 +394,7 @@ ItinStageEnum++; } } - + // Check to see if operand cycle already exists and create if it doesn't unsigned FindOperandCycle = 0; if (NOperandCycles > 0) { @@ -402,25 +402,25 @@ FindOperandCycle = ItinOperandMap[ItinOperandString]; if (FindOperandCycle == 0) { // Emit as cycle, // index - OperandCycleTable += ItinOperandCycleString + ", // " + + OperandCycleTable += ItinOperandCycleString + ", // " + itostr(ItinOperandCycleEnum) + "\n"; // Record Itin class number. - ItinOperandMap[ItinOperandCycleString] = + ItinOperandMap[ItinOperandCycleString] = FindOperandCycle = OperandCycleCount; // Emit as bypass, // index - BypassTable += ItinBypassString + ", // " + + BypassTable += ItinBypassString + ", // " + itostr(ItinOperandCycleEnum) + "\n"; OperandCycleCount += NOperandCycles; ItinOperandCycleEnum++; } } - + // Locate where to inject into processor itinerary table const std::string &Name = ItinData->getValueAsDef("TheClass")->getName(); unsigned Find = ItinClassesMap[Name]; - + // Set up itinerary as location and location + stage count unsigned NumUOps = ItinClassList[Find]->getValueAsInt("NumMicroOps"); InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages, @@ -430,7 +430,7 @@ // Inject - empty slots will be 0, 0 ItinList[Find] = Intinerary; } - + // Add process itinerary to list ProcList.push_back(ItinList); } @@ -450,7 +450,7 @@ OS << StageTable; OS << OperandCycleTable; OS << BypassTable; - + // Emit size of tables OS<<"\nenum {\n"; OS<<" StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage),\n"; @@ -466,7 +466,7 @@ // Get an iterator for processor itinerary stages std::vector >::iterator ProcListIter = ProcList.begin(); - + // For each processor itinerary std::vector Itins = Records.getAllDerivedDefinitions("ProcessorItineraries"); @@ -476,35 +476,35 @@ // Get processor itinerary name const std::string &Name = Itin->getName(); - + // Skip default if (Name == "NoItineraries") continue; // Begin processor itinerary table OS << "\n"; OS << "static const llvm::InstrItinerary " << Name << "[] = {\n"; - + // For each itinerary class std::vector &ItinList = *ProcListIter++; for (unsigned j = 0, M = ItinList.size(); j < M; ++j) { InstrItinerary &Intinerary = ItinList[j]; - - // Emit in the form of + + // Emit in the form of // { firstStage, lastStage, firstCycle, lastCycle } // index if (Intinerary.FirstStage == 0) { OS << " { 1, 0, 0, 0, 0 }"; } else { OS << " { " << Intinerary.NumMicroOps << ", " << - Intinerary.FirstStage << ", " << - Intinerary.LastStage << ", " << - Intinerary.FirstOperandCycle << ", " << + Intinerary.FirstStage << ", " << + Intinerary.LastStage << ", " << + Intinerary.FirstOperandCycle << ", " << Intinerary.LastOperandCycle << " }"; } - + OS << ", // " << j << "\n"; } - + // End processor itinerary table OS << " { 1, ~0U, ~0U, ~0U, ~0U } // end marker\n"; OS << "};\n"; @@ -524,7 +524,7 @@ OS << "\n"; OS << "// Sorted (by key) array of itineraries for CPU subtype.\n" << "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n"; - + // For each processor for (unsigned i = 0, N = ProcessorList.size(); i < N;) { // Next processor @@ -533,20 +533,20 @@ const std::string &Name = Processor->getValueAsString("Name"); const std::string &ProcItin = Processor->getValueAsDef("ProcItin")->getName(); - + // Emit as { "cpu", procinit }, OS << " { " << "\"" << Name << "\", " << "(void *)&" << ProcItin; - + OS << " }"; - + // Depending on ''if more in the list'' emit comma if (++i < N) OS << ","; - + OS << "\n"; } - + // End processor table OS << "};\n"; @@ -566,13 +566,13 @@ std::vector ItinClassList = Records.getAllDerivedDefinitions("InstrItinClass"); std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord()); - + // Enumerate all the itinerary classes unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap, ItinClassList); // Make sure the rest is worth the effort HasItineraries = NItinClasses != 1; // Ignore NoItinerary. - + if (HasItineraries) { std::vector > ProcList; // Emit the stage data @@ -594,8 +594,8 @@ Records.getAllDerivedDefinitions("SubtargetFeature"); std::sort(Features.begin(), Features.end(), LessRecord()); - OS << "// ParseSubtargetFeatures - Parses features string setting specified\n" - << "// subtarget options.\n" + OS << "// ParseSubtargetFeatures - Parses features string setting specified\n" + << "// subtarget options.\n" << "std::string llvm::"; OS << Target; OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n" @@ -618,7 +618,7 @@ OS << " if ((Bits & " << Instance << ") != 0) " << Attribute << " = " << Value << ";\n"; else - OS << " if ((Bits & " << Instance << ") != 0 && " << Attribute << + OS << " if ((Bits & " << Instance << ") != 0 && " << Attribute << " < " << Value << ") " << Attribute << " = " << Value << ";\n"; } Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.h?rev=128701&r1=128700&r2=128701&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/SubtargetEmitter.h (original) +++ llvm/trunk/utils/TableGen/SubtargetEmitter.h Thu Mar 31 20:56:55 2011 @@ -24,11 +24,11 @@ namespace llvm { class SubtargetEmitter : public TableGenBackend { - + RecordKeeper &Records; std::string Target; bool HasItineraries; - + void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits); void FeatureKeyValues(raw_ostream &OS); void CPUKeyValues(raw_ostream &OS); @@ -52,7 +52,7 @@ void EmitProcessorLookup(raw_ostream &OS); void EmitData(raw_ostream &OS); void ParseFeaturesFunction(raw_ostream &OS); - + public: SubtargetEmitter(RecordKeeper &R) : Records(R), HasItineraries(false) {} From geek4civic at gmail.com Thu Mar 31 21:03:43 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Fri, 1 Apr 2011 11:03:43 +0900 Subject: [llvm-commits] [Review request][PATCH] MC: Recognize alignment stuff on PECOFF. In-Reply-To: <4D909305.5030300@gmail.com> References: <4D909305.5030300@gmail.com> Message-ID: Rafael, I am sorry to respond so late. 2011/3/28 Rafael ?vila de Esp?ndola : > Looks reasonable, but without updating the parser and adding a test it > is hard to be sure. I had not been unaware of MC parser. My 1st mission was to satisfy mingw32-as. It makes sense, I will tweak MC later. Excuse me, I have been testing release_29, to sped so much time :) > Also, it might be better to add an empty implementation to MCStreamer > instead of making it pure virtual. IMHO we have many pure virtuals in > MCStreamer that could reasonably have an empty implementation. Agree, though, I would clean up them later because I would like to tweak .lcomm in 1st step. Shall we clean up pure virtuals at first, do you think? ...Takumi From atrick at apple.com Thu Mar 31 21:22:47 2011 From: atrick at apple.com (Andrew Trick) Date: Fri, 01 Apr 2011 02:22:47 -0000 Subject: [llvm-commits] [llvm] r128703 - in /llvm/trunk/utils/TableGen: SubtargetEmitter.cpp SubtargetEmitter.h Message-ID: <20110401022247.75F6E2A6C12C@llvm.org> Author: atrick Date: Thu Mar 31 21:22:47 2011 New Revision: 128703 URL: http://llvm.org/viewvc/llvm-project?rev=128703&view=rev Log: Add annotations to tablegen-generated processor itineraries, or replace them with something meaningful. I want to be able to read and debug the generated tables. Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp llvm/trunk/utils/TableGen/SubtargetEmitter.h Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.cpp?rev=128703&r1=128702&r2=128703&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp Thu Mar 31 21:22:47 2011 @@ -342,7 +342,6 @@ BypassTable += " 0, // No itinerary\n"; unsigned StageCount = 1, OperandCycleCount = 1; - unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1; std::map ItinStageMap, ItinOperandMap; for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) { // Next record @@ -386,12 +385,14 @@ if (NStages > 0) { FindStage = ItinStageMap[ItinStageString]; if (FindStage == 0) { - // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // index - StageTable += ItinStageString + ", // " + itostr(ItinStageEnum) + "\n"; + // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // indices + StageTable += ItinStageString + ", // " + itostr(StageCount); + if (NStages > 1) + StageTable += "-" + itostr(StageCount + NStages - 1); + StageTable += "\n"; // Record Itin class number. ItinStageMap[ItinStageString] = FindStage = StageCount; StageCount += NStages; - ItinStageEnum++; } } @@ -402,18 +403,18 @@ FindOperandCycle = ItinOperandMap[ItinOperandString]; if (FindOperandCycle == 0) { // Emit as cycle, // index - OperandCycleTable += ItinOperandCycleString + ", // " + - itostr(ItinOperandCycleEnum) + "\n"; + OperandCycleTable += ItinOperandCycleString + ", // "; + std::string OperandIdxComment = itostr(OperandCycleCount); + if (NOperandCycles > 1) + OperandIdxComment += "-" + + itostr(OperandCycleCount + NOperandCycles - 1); + OperandCycleTable += OperandIdxComment + "\n"; // Record Itin class number. ItinOperandMap[ItinOperandCycleString] = FindOperandCycle = OperandCycleCount; - // Emit as bypass, // index - BypassTable += ItinBypassString + ", // " + - itostr(ItinOperandCycleEnum) + "\n"; - + BypassTable += ItinBypassString + ", // " + OperandIdxComment + "\n"; OperandCycleCount += NOperandCycles; - ItinOperandCycleEnum++; } } @@ -461,8 +462,10 @@ // // EmitProcessorData - Generate data for processor itineraries. // -void SubtargetEmitter::EmitProcessorData(raw_ostream &OS, - std::vector > &ProcList) { +void SubtargetEmitter:: +EmitProcessorData(raw_ostream &OS, + std::vector &ItinClassList, + std::vector > &ProcList) { // Get an iterator for processor itinerary stages std::vector >::iterator ProcListIter = ProcList.begin(); @@ -486,6 +489,7 @@ // For each itinerary class std::vector &ItinList = *ProcListIter++; + assert(ItinList.size() == ItinClassList.size() && "bad itinerary"); for (unsigned j = 0, M = ItinList.size(); j < M; ++j) { InstrItinerary &Intinerary = ItinList[j]; @@ -502,7 +506,7 @@ Intinerary.LastOperandCycle << " }"; } - OS << ", // " << j << "\n"; + OS << ", // " << j << " " << ItinClassList[j]->getName() << "\n"; } // End processor itinerary table @@ -579,7 +583,7 @@ EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap, ItinClassList, ProcList); // Emit the processor itinerary data - EmitProcessorData(OS, ProcList); + EmitProcessorData(OS, ItinClassList, ProcList); // Emit the processor lookup data EmitProcessorLookup(OS); } Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.h?rev=128703&r1=128702&r2=128703&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/SubtargetEmitter.h (original) +++ llvm/trunk/utils/TableGen/SubtargetEmitter.h Thu Mar 31 21:22:47 2011 @@ -48,7 +48,8 @@ std::vector &ItinClassList, std::vector > &ProcList); void EmitProcessorData(raw_ostream &OS, - std::vector > &ProcList); + std::vector &ItinClassList, + std::vector > &ProcList); void EmitProcessorLookup(raw_ostream &OS); void EmitData(raw_ostream &OS); void ParseFeaturesFunction(raw_ostream &OS); From echristo at apple.com Thu Mar 31 21:28:56 2011 From: echristo at apple.com (Eric Christopher) Date: Thu, 31 Mar 2011 19:28:56 -0700 Subject: [llvm-commits] [llvm] r128703 - in /llvm/trunk/utils/TableGen: SubtargetEmitter.cpp SubtargetEmitter.h In-Reply-To: <20110401022247.75F6E2A6C12C@llvm.org> References: <20110401022247.75F6E2A6C12C@llvm.org> Message-ID: On Mar 31, 2011, at 7:22 PM, Andrew Trick wrote: > Add annotations to tablegen-generated processor itineraries, or replace them with something meaningful. I want to be able to read and debug the generated tables. Heresy! Next you'll want to have it actually tell you what's wrong when you do something incorrectly! -eric From atrick at apple.com Thu Mar 31 21:45:17 2011 From: atrick at apple.com (Andrew Trick) Date: Thu, 31 Mar 2011 19:45:17 -0700 Subject: [llvm-commits] [llvm] r128703 - in /llvm/trunk/utils/TableGen: SubtargetEmitter.cpp SubtargetEmitter.h In-Reply-To: References: <20110401022247.75F6E2A6C12C@llvm.org> Message-ID: <520199B3-D416-4AB9-A40A-D1DF7CAD4117@apple.com> On Mar 31, 2011, at 7:28 PM, Eric Christopher wrote: > > On Mar 31, 2011, at 7:22 PM, Andrew Trick wrote: > >> Add annotations to tablegen-generated processor itineraries, or replace them with something meaningful. I want to be able to read and debug the generated tables. > > Heresy! Next you'll want to have it actually tell you what's wrong when you do something incorrectly! > > -eric You're quite perceptive. My next request is a static analyzer that counts cycles and tells us where the scheduler screwed up ...assuming perfect cache, yadayada. -Andy From aggarwa4 at illinois.edu Thu Mar 31 22:26:34 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Fri, 01 Apr 2011 03:26:34 -0000 Subject: [llvm-commits] [poolalloc] r128704 - /poolalloc/trunk/lib/DSA/DataStructureStats.cpp Message-ID: <20110401032634.773A72A6C12C@llvm.org> Author: aggarwa4 Date: Thu Mar 31 22:26:34 2011 New Revision: 128704 URL: http://llvm.org/viewvc/llvm-project?rev=128704&view=rev Log: Some more stats. Also, for insertvalue/extractvalue inst, we must check the types at an offset. Modified: poolalloc/trunk/lib/DSA/DataStructureStats.cpp Modified: poolalloc/trunk/lib/DSA/DataStructureStats.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructureStats.cpp?rev=128704&r1=128703&r2=128704&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DataStructureStats.cpp (original) +++ poolalloc/trunk/lib/DSA/DataStructureStats.cpp Thu Mar 31 22:26:34 2011 @@ -36,6 +36,8 @@ "Number of loads/stores which are fully typed"); STATISTIC (NumUntypedMemAccesses, "Number of loads/stores which are untyped"); + STATISTIC (NumTypeCount0Accesses, + "Number of loads/stores which are access a DSNode with 0 type"); STATISTIC (NumTypeCount1Accesses, "Number of loads/stores which are access a DSNode with 1 type"); STATISTIC (NumTypeCount2Accesses, @@ -50,14 +52,17 @@ "Number of loads/stores which are on unknown nodes"); STATISTIC (NumExternalAccesses, "Number of loads/stores which are on external nodes"); + STATISTIC (NumFoldedAccess, + "Number of loads/stores which are on folded nodes"); class DSGraphStats : public FunctionPass, public InstVisitor { void countCallees(const Function &F); const TDDataStructures *DS; + const TargetData *TD; const DSGraph *TDGraph; dsa::TypeSafety *TS; DSNodeHandle getNodeHandleForValue(Value *V); - bool isNodeForValueUntyped(Value *V, const Function *); + bool isNodeForValueUntyped(Value *V, unsigned offset, const Function *); public: static char ID; DSGraphStats() : FunctionPass((intptr_t)&ID) {} @@ -69,6 +74,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); + AU.addRequired(); AU.addRequired >(); } @@ -155,7 +161,7 @@ return 0; } -bool DSGraphStats::isNodeForValueUntyped(Value *V, const Function *F) { +bool DSGraphStats::isNodeForValueUntyped(Value *V, unsigned Offset, const Function *F) { DSNodeHandle NH = getNodeHandleForValue(V); if(!NH.getNode()){ return true; @@ -163,6 +169,7 @@ else { DSNode *N = NH.getNode(); if (N->isNodeCompletelyFolded()){ + ++NumFoldedAccess; return true; } if ( N->isExternalNode()){ @@ -179,7 +186,7 @@ } // it is a complete node, now check how many types are present int count = 0; - unsigned offset = NH.getOffset(); + unsigned offset = NH.getOffset() + Offset; if (N->type_begin() != N->type_end()) for (DSNode::TyMapTy::const_iterator ii = N->type_begin(), ee = N->type_end(); ii != ee; ++ii) { @@ -188,13 +195,15 @@ count += ii->second->size(); } - if(count == 1) + if (count ==0) + ++NumTypeCount0Accesses; + else if(count == 1) ++NumTypeCount1Accesses; else if(count == 2) ++NumTypeCount2Accesses; else if(count == 3) ++NumTypeCount3Accesses; - else + else ++NumTypeCount4Accesses; DEBUG(assert(TS->isTypeSafe(V,F))); } @@ -202,7 +211,7 @@ } void DSGraphStats::visitLoad(LoadInst &LI) { - if (isNodeForValueUntyped(LI.getOperand(0), LI.getParent()->getParent())) { + if (isNodeForValueUntyped(LI.getOperand(0), 0,LI.getParent()->getParent())) { NumUntypedMemAccesses++; } else { NumTypedMemAccesses++; @@ -210,7 +219,7 @@ } void DSGraphStats::visitStore(StoreInst &SI) { - if (isNodeForValueUntyped(SI.getOperand(1), SI.getParent()->getParent())) { + if (isNodeForValueUntyped(SI.getOperand(1), 0,SI.getParent()->getParent())) { NumUntypedMemAccesses++; } else { NumTypedMemAccesses++; @@ -218,7 +227,15 @@ } void DSGraphStats::visitInsertValue(InsertValueInst &I) { - if (isNodeForValueUntyped(I.getAggregateOperand(), I.getParent()->getParent())) { + unsigned Offset = 0; + const Type* STy = I.getAggregateOperand()->getType(); + llvm::InsertValueInst::idx_iterator i = I.idx_begin(), e = I.idx_end(); + for (; i != e; i++) { + const StructLayout *SL = TD->getStructLayout(cast(STy)); + Offset += SL->getElementOffset(*i); + STy = (cast(STy))->getTypeAtIndex(*i); + } + if (isNodeForValueUntyped(&I, Offset, I.getParent()->getParent())) { NumUntypedMemAccesses++; } else { NumTypedMemAccesses++; @@ -226,16 +243,24 @@ } void DSGraphStats::visitExtractValue(ExtractValueInst &I) { - if (isNodeForValueUntyped(I.getAggregateOperand(), I.getParent()->getParent())) { + unsigned Offset = 0; + const Type* STy = I.getAggregateOperand()->getType(); + llvm::ExtractValueInst::idx_iterator i = I.idx_begin(), e = I.idx_end(); + for (; i != e; i++) { + const StructLayout *SL = TD->getStructLayout(cast(STy)); + Offset += SL->getElementOffset(*i); + STy = (cast(STy))->getTypeAtIndex(*i); + } + if (isNodeForValueUntyped(I.getAggregateOperand(), Offset, I.getParent()->getParent())) { NumUntypedMemAccesses++; } else { NumTypedMemAccesses++; } } - bool DSGraphStats::runOnFunction(Function& F) { DS = &getAnalysis(); + TD = &getAnalysis(); TS = &getAnalysis >(); TDGraph = DS->getDSGraph(F); countCallees(F); From baldrick at free.fr Thu Mar 31 22:34:54 2011 From: baldrick at free.fr (Duncan Sands) Date: Fri, 01 Apr 2011 03:34:54 -0000 Subject: [llvm-commits] [llvm] r128705 - in /llvm/trunk: lib/VMCore/Instructions.cpp unittests/VMCore/InstructionsTest.cpp Message-ID: <20110401033455.020312A6C12C@llvm.org> Author: baldrick Date: Thu Mar 31 22:34:54 2011 New Revision: 128705 URL: http://llvm.org/viewvc/llvm-project?rev=128705&view=rev Log: While testing dragonegg I noticed that isCastable and getCastOpcode had gotten out of sync: isCastable didn't think it was possible to cast the x86_mmx type to anything, while it did think it possible to cast an i64 to x86_mmx. Modified: llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/unittests/VMCore/InstructionsTest.cpp Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=128705&r1=128704&r2=128705&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Thu Mar 31 22:34:54 2011 @@ -2297,8 +2297,12 @@ if (const VectorType *SrcPTy = dyn_cast(SrcTy)) { // Casting from vector return DestPTy->getBitWidth() == SrcPTy->getBitWidth(); - } else { // Casting from something else - return DestPTy->getBitWidth() == SrcBits; + } else if (DestPTy->getBitWidth() == SrcBits) { + return true; // float/int -> vector + } else if (SrcTy->isX86_MMXTy()) { + return DestPTy->getBitWidth() == 64; // MMX to 64-bit vector + } else { + return false; } } else if (DestTy->isPointerTy()) { // Casting to pointer if (SrcTy->isPointerTy()) { // Casting from pointer @@ -2308,8 +2312,12 @@ } else { // Casting from something else return false; } - } else if (DestTy->isX86_MMXTy()) { - return SrcBits == 64; + } else if (DestTy->isX86_MMXTy()) { + if (const VectorType *SrcPTy = dyn_cast(SrcTy)) { + return SrcPTy->getBitWidth() == 64; // 64-bit vector to MMX + } else { + return false; + } } else { // Casting to something else return false; } Modified: llvm/trunk/unittests/VMCore/InstructionsTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/VMCore/InstructionsTest.cpp?rev=128705&r1=128704&r2=128705&view=diff ============================================================================== --- llvm/trunk/unittests/VMCore/InstructionsTest.cpp (original) +++ llvm/trunk/unittests/VMCore/InstructionsTest.cpp Thu Mar 31 22:34:54 2011 @@ -107,5 +107,18 @@ delete bb1; } +TEST(InstructionsTest, CastInst) { + LLVMContext &C(getGlobalContext()); + + const Type* Int8Ty = Type::getInt8Ty(C); + const Type* Int64Ty = Type::getInt64Ty(C); + const Type* V8x8Ty = VectorType::get(Int8Ty, 8); + const Type* X86MMXTy = Type::getX86_MMXTy(C); + + EXPECT_TRUE(CastInst::isCastable(V8x8Ty, X86MMXTy)); + EXPECT_TRUE(CastInst::isCastable(X86MMXTy, V8x8Ty)); + EXPECT_FALSE(CastInst::isCastable(Int64Ty, X86MMXTy)); +} + } // end anonymous namespace } // end namespace llvm From evan.cheng at apple.com Thu Mar 31 22:36:33 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 01 Apr 2011 03:36:33 -0000 Subject: [llvm-commits] [llvm] r128706 - /llvm/trunk/test/CodeGen/ARM/smul.ll Message-ID: <20110401033633.4708A2A6C12C@llvm.org> Author: evancheng Date: Thu Mar 31 22:36:33 2011 New Revision: 128706 URL: http://llvm.org/viewvc/llvm-project?rev=128706&view=rev Log: FileCheck'ify test. Modified: llvm/trunk/test/CodeGen/ARM/smul.ll Modified: llvm/trunk/test/CodeGen/ARM/smul.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/smul.ll?rev=128706&r1=128705&r2=128706&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/smul.ll (original) +++ llvm/trunk/test/CodeGen/ARM/smul.ll Thu Mar 31 22:36:33 2011 @@ -1,16 +1,12 @@ -; RUN: llc < %s -march=arm -; RUN: llc < %s -march=arm -mattr=+v5TE -; RUN: llc < %s -march=arm -mattr=+v5TE | \ -; RUN: grep smulbt | count 1 -; RUN: llc < %s -march=arm -mattr=+v5TE | \ -; RUN: grep smultt | count 1 -; RUN: llc < %s -march=arm -mattr=+v5TE | \ -; RUN: grep smlabt | count 1 +; RUN: llc < %s -march=arm -mcpu=generic +; RUN: llc < %s -march=arm -mcpu=cortex-a8 | FileCheck %s @x = weak global i16 0 ; [#uses=1] @y = weak global i16 0 ; [#uses=0] define i32 @f1(i32 %y) { +; CHECK: f1 +; CHECK: smulbt %tmp = load i16* @x ; [#uses=1] %tmp1 = add i16 %tmp, 2 ; [#uses=1] %tmp2 = sext i16 %tmp1 to i32 ; [#uses=1] @@ -20,6 +16,8 @@ } define i32 @f2(i32 %x, i32 %y) { +; CHECK: f2 +; CHECK: smultt %tmp1 = ashr i32 %x, 16 ; [#uses=1] %tmp3 = ashr i32 %y, 16 ; [#uses=1] %tmp4 = mul i32 %tmp3, %tmp1 ; [#uses=1] @@ -27,6 +25,8 @@ } define i32 @f3(i32 %a, i16 %x, i32 %y) { +; CHECK: f3 +; CHECK: smlabt %tmp = sext i16 %x to i32 ; [#uses=1] %tmp2 = ashr i32 %y, 16 ; [#uses=1] %tmp3 = mul i32 %tmp2, %tmp ; [#uses=1] From evan.cheng at apple.com Fri Apr 1 01:27:25 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 01 Apr 2011 06:27:25 -0000 Subject: [llvm-commits] [llvm] r128707 - /llvm/trunk/test/CodeGen/ARM/divmod.ll Message-ID: <20110401062725.2FCEC2A6C12C@llvm.org> Author: evancheng Date: Fri Apr 1 01:27:25 2011 New Revision: 128707 URL: http://llvm.org/viewvc/llvm-project?rev=128707&view=rev Log: Add test case. Added: llvm/trunk/test/CodeGen/ARM/divmod.ll Added: llvm/trunk/test/CodeGen/ARM/divmod.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/divmod.ll?rev=128707&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/divmod.ll (added) +++ llvm/trunk/test/CodeGen/ARM/divmod.ll Fri Apr 1 01:27:25 2011 @@ -0,0 +1,27 @@ +; RUN: llc < %s -mtriple=arm-apple-darwin -arm-divmod-libcall | FileCheck %s + +define void @foo(i32 %x, i32 %y, i32* nocapture %P) nounwind ssp { +entry: +; CHECK: foo: +; CHECK: bl ___divmodsi4 +; CHECK-NOT: bl ___divmodsi4 + %div = sdiv i32 %x, %y + store i32 %div, i32* %P, align 4 + %rem = srem i32 %x, %y + %arrayidx6 = getelementptr inbounds i32* %P, i32 1 + store i32 %rem, i32* %arrayidx6, align 4 + ret void +} + +define void @bar(i32 %x, i32 %y, i32* nocapture %P) nounwind ssp { +entry: +; CHECK: bar: +; CHECK: bl ___udivmodsi4 +; CHECK-NOT: bl ___udivmodsi4 + %div = udiv i32 %x, %y + store i32 %div, i32* %P, align 4 + %rem = urem i32 %x, %y + %arrayidx6 = getelementptr inbounds i32* %P, i32 1 + store i32 %rem, i32* %arrayidx6, align 4 + ret void +} From jay.foad at gmail.com Fri Apr 1 03:00:58 2011 From: jay.foad at gmail.com (Jay Foad) Date: Fri, 01 Apr 2011 08:00:58 -0000 Subject: [llvm-commits] [llvm] r128708 - in /llvm/trunk: include/llvm/Instructions.h lib/VMCore/Instructions.cpp Message-ID: <20110401080058.6746E2A6C12D@llvm.org> Author: foad Date: Fri Apr 1 03:00:58 2011 New Revision: 128708 URL: http://llvm.org/viewvc/llvm-project?rev=128708&view=rev Log: Various Instructions' resizeOperands() methods are only used to grow the list of operands. Simplify and rename them accordingly. Modified: llvm/trunk/include/llvm/Instructions.h llvm/trunk/lib/VMCore/Instructions.cpp Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=128708&r1=128707&r2=128708&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Fri Apr 1 03:00:58 2011 @@ -1910,7 +1910,7 @@ "All operands to PHI node must be the same type as the PHI node!"); unsigned OpNo = NumOperands; if (OpNo+2 > ReservedSpace) - resizeOperands(0); // Get more space! + growOperands(); // Get more space! // Initialize some new operands. NumOperands = OpNo+2; OperandList[OpNo] = V; @@ -1960,7 +1960,7 @@ return isa(V) && classof(cast(V)); } private: - void resizeOperands(unsigned NumOperands); + void growOperands(); }; template <> @@ -2152,7 +2152,7 @@ // Operand[2n+1] = BasicBlock to go to on match SwitchInst(const SwitchInst &SI); void init(Value *Value, BasicBlock *Default, unsigned NumReserved); - void resizeOperands(unsigned No); + void growOperands(); // allocate space for exactly zero operands void *operator new(size_t s) { return User::operator new(s, 0); @@ -2304,7 +2304,7 @@ // Operand[2n+1] = BasicBlock to go to on match IndirectBrInst(const IndirectBrInst &IBI); void init(Value *Address, unsigned NumDests); - void resizeOperands(unsigned No); + void growOperands(); // allocate space for exactly zero operands void *operator new(size_t s) { return User::operator new(s, 0); Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=128708&r1=128707&r2=128708&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Fri Apr 1 03:00:58 2011 @@ -131,26 +131,14 @@ return Removed; } -/// resizeOperands - resize operands - This adjusts the length of the operands -/// list according to the following behavior: -/// 1. If NumOps == 0, grow the operand list in response to a push_back style -/// of operation. This grows the number of ops by 1.5 times. -/// 2. If NumOps > NumOperands, reserve space for NumOps operands. -/// 3. If NumOps == NumOperands, trim the reserved space. +/// growOperands - grow operands - This grows the operand list in response +/// to a push_back style of operation. This grows the number of ops by 1.5 +/// times. /// -void PHINode::resizeOperands(unsigned NumOps) { +void PHINode::growOperands() { unsigned e = getNumOperands(); - if (NumOps == 0) { - NumOps = e*3/2; - if (NumOps < 4) NumOps = 4; // 4 op PHI nodes are VERY common. - } else if (NumOps*2 > NumOperands) { - // No resize needed. - if (ReservedSpace >= NumOps) return; - } else if (NumOps == NumOperands) { - if (ReservedSpace == NumOps) return; - } else { - return; - } + unsigned NumOps = e*3/2; + if (NumOps < 4) NumOps = 4; // 4 op PHI nodes are VERY common. ReservedSpace = NumOps; Use *OldOps = OperandList; @@ -2998,7 +2986,7 @@ void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) { unsigned OpNo = NumOperands; if (OpNo+2 > ReservedSpace) - resizeOperands(0); // Get more space! + growOperands(); // Get more space! // Initialize some new operands. assert(OpNo+1 < ReservedSpace && "Growing didn't work!"); NumOperands = OpNo+2; @@ -3029,25 +3017,12 @@ NumOperands = NumOps-2; } -/// resizeOperands - resize operands - This adjusts the length of the operands -/// list according to the following behavior: -/// 1. If NumOps == 0, grow the operand list in response to a push_back style -/// of operation. This grows the number of ops by 3 times. -/// 2. If NumOps > NumOperands, reserve space for NumOps operands. -/// 3. If NumOps == NumOperands, trim the reserved space. +/// growOperands - grow operands - This grows the operand list in response +/// to a push_back style of operation. This grows the number of ops by 3 times. /// -void SwitchInst::resizeOperands(unsigned NumOps) { +void SwitchInst::growOperands() { unsigned e = getNumOperands(); - if (NumOps == 0) { - NumOps = e*3; - } else if (NumOps*2 > NumOperands) { - // No resize needed. - if (ReservedSpace >= NumOps) return; - } else if (NumOps == NumOperands) { - if (ReservedSpace == NumOps) return; - } else { - return; - } + unsigned NumOps = e*3; ReservedSpace = NumOps; Use *NewOps = allocHungoffUses(NumOps); @@ -3085,25 +3060,12 @@ } -/// resizeOperands - resize operands - This adjusts the length of the operands -/// list according to the following behavior: -/// 1. If NumOps == 0, grow the operand list in response to a push_back style -/// of operation. This grows the number of ops by 2 times. -/// 2. If NumOps > NumOperands, reserve space for NumOps operands. -/// 3. If NumOps == NumOperands, trim the reserved space. +/// growOperands - grow operands - This grows the operand list in response +/// to a push_back style of operation. This grows the number of ops by 2 times. /// -void IndirectBrInst::resizeOperands(unsigned NumOps) { +void IndirectBrInst::growOperands() { unsigned e = getNumOperands(); - if (NumOps == 0) { - NumOps = e*2; - } else if (NumOps*2 > NumOperands) { - // No resize needed. - if (ReservedSpace >= NumOps) return; - } else if (NumOps == NumOperands) { - if (ReservedSpace == NumOps) return; - } else { - return; - } + unsigned NumOps = e*2; ReservedSpace = NumOps; Use *NewOps = allocHungoffUses(NumOps); @@ -3147,7 +3109,7 @@ void IndirectBrInst::addDestination(BasicBlock *DestBB) { unsigned OpNo = NumOperands; if (OpNo+1 > ReservedSpace) - resizeOperands(0); // Get more space! + growOperands(); // Get more space! // Initialize some new operands. assert(OpNo < ReservedSpace && "Growing didn't work!"); NumOperands = OpNo+1; From benny.kra at googlemail.com Fri Apr 1 04:20:31 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 01 Apr 2011 09:20:31 -0000 Subject: [llvm-commits] [llvm] r128709 - /llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp Message-ID: <20110401092031.967732A6C12C@llvm.org> Author: d0k Date: Fri Apr 1 04:20:31 2011 New Revision: 128709 URL: http://llvm.org/viewvc/llvm-project?rev=128709&view=rev Log: Initialize HasVMLxForwarding. Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp?rev=128709&r1=128708&r2=128709&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp Fri Apr 1 04:20:31 2011 @@ -38,6 +38,7 @@ , ARMFPUType(None) , UseNEONForSinglePrecisionFP(false) , SlowFPVMLx(false) + , HasVMLxForwarding(false) , SlowFPBrcc(false) , IsThumb(isT) , ThumbMode(Thumb1) From baldrick at free.fr Fri Apr 1 05:44:34 2011 From: baldrick at free.fr (Duncan Sands) Date: Fri, 01 Apr 2011 10:44:34 -0000 Subject: [llvm-commits] [dragonegg] r128710 - /dragonegg/trunk/Constants.cpp Message-ID: <20110401104434.29E832A6C12C@llvm.org> Author: baldrick Date: Fri Apr 1 05:44:33 2011 New Revision: 128710 URL: http://llvm.org/viewvc/llvm-project?rev=128710&view=rev Log: GCC allows implicit (scalar) type casts when an initial value is "assigned" to a field. Handle the case of record fields as well as array elements, and factor out the casting code. Modified: dragonegg/trunk/Constants.cpp Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=128710&r1=128709&r2=128710&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Fri Apr 1 05:44:33 2011 @@ -482,6 +482,40 @@ // ... ConvertInitializer ... //===----------------------------------------------------------------------===// +/// ConvertInitializerWithCast - Convert the initial value for a global variable +/// to an equivalent LLVM constant then cast to the given type if both the type +/// and the initializer are scalar. This is convenient for making explicit the +/// implicit scalar casts that GCC allows in "assignments" such as initializing +/// a record field. +static Constant *ConvertInitializerWithCast(tree exp, tree type) { + // Convert the initializer. + Constant *C = ConvertInitializer(exp); + + // If no cast is needed, or it would not be a scalar cast, then just return + // the initializer as is. + if (type == TREE_TYPE(exp) || AGGREGATE_TYPE_P(TREE_TYPE(exp)) || + AGGREGATE_TYPE_P(type)) + return C; + const Type *SrcTy = ConvertType(TREE_TYPE(exp)); + const Type *DestTy = ConvertType(type); + // LLVM types are often the same even when the GCC types differ. + if (SrcTy == DestTy) + return C; + + // First ensure that the initializer has a sensible type. Note that it would + // be wrong to interpret the constant as being of type DestTy here since that + // would not perform a value extension (adding extra zeros or sign bits when + // casting to a larger integer type for example): any extra bits would get an + // undefined value instead. + C = InterpretAsType(C, SrcTy, 0); + // Now cast to the desired type. + bool SrcIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp)); + bool DestIsSigned = !TYPE_UNSIGNED(type); + Instruction::CastOps opcode = CastInst::getCastOpcode(C, SrcIsSigned, DestTy, + DestIsSigned); + return TheFolder->CreateCast(opcode, C, DestTy); +} + /// ConvertCST - Return the given simple constant as an array of bytes. For the /// moment only INTEGER_CST, REAL_CST, COMPLEX_CST and VECTOR_CST are supported. static Constant *ConvertCST(tree exp) { @@ -579,8 +613,6 @@ // If we have a lower bound for the range of the type, get it. tree init_type = TREE_TYPE(exp); tree elt_type = TREE_TYPE(init_type); - const Type *EltTy = ConvertType(elt_type); - bool EltIsSigned = !TYPE_UNSIGNED(elt_type); tree min_element = size_zero_node; std::vector ResultElts; @@ -609,19 +641,7 @@ Constant *SomeVal = 0; FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), ix, elt_index, elt_value) { // Find and decode the constructor's value. - Constant *Val = ConvertInitializer(elt_value); - - // If needed, cast the value to the type of the array element. - if (TREE_TYPE(elt_value) != elt_type && !AGGREGATE_TYPE_P(elt_type) && - !AGGREGATE_TYPE_P(TREE_TYPE(elt_value))) { - const Type *ValTy = ConvertType(TREE_TYPE(elt_value)); - Val = InterpretAsType(Val, ValTy, 0); - bool ValIsSigned = !TYPE_UNSIGNED(TREE_TYPE(elt_value)); - Instruction::CastOps opcode = CastInst::getCastOpcode(Val, ValIsSigned, - EltTy, EltIsSigned); - Val = TheFolder->CreateCast(opcode, Val, EltTy); - } - + Constant *Val = ConvertInitializerWithCast(elt_value, elt_type); SomeVal = Val; // Get the index position of the element within the array. Note that this @@ -904,7 +924,7 @@ assert(TREE_CODE(field) == FIELD_DECL && "Initial value not for a field!"); assert(OffsetIsLLVMCompatible(field) && "Field position not known!"); // Turn the initial value for this field into an LLVM constant. - Constant *Init = ConvertInitializer(value); + Constant *Init = ConvertInitializerWithCast(value, TREE_TYPE(field)); // Work out the range of bits occupied by the field. uint64_t FirstBit = getFieldOffsetInBits(field); assert(FirstBit <= TypeSize && "Field off end of type!"); @@ -1011,22 +1031,6 @@ } } -static Constant *ConvertCONVERT_EXPR(tree exp) { - if (AGGREGATE_TYPE_P(TREE_TYPE(exp)) || - AGGREGATE_TYPE_P(TREE_TYPE(TREE_OPERAND(exp, 0)))) { - // A no-op record view conversion. These do not change any of the bits in - // the constant so just ignore them. - return ConvertInitializer(TREE_OPERAND(exp, 0)); - } - Constant *Elt = ConvertInitializer(TREE_OPERAND(exp, 0)); - bool EltIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0))); - const Type *Ty = ConvertType(TREE_TYPE(exp)); - bool TyIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp)); - Instruction::CastOps opcode = CastInst::getCastOpcode(Elt, EltIsSigned, Ty, - TyIsSigned); - return TheFolder->CreateCast(opcode, Elt, Ty); -} - static Constant *ConvertBinOp_CST(tree exp) { Constant *LHS = ConvertInitializer(TREE_OPERAND(exp, 0)); bool LHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp,0))); @@ -1104,7 +1108,7 @@ break; case CONVERT_EXPR: case NOP_EXPR: - Init = ConvertCONVERT_EXPR(exp); + Init = ConvertInitializerWithCast(TREE_OPERAND(exp, 0), TREE_TYPE(exp)); break; case MINUS_EXPR: case PLUS_EXPR: From 6yearold at gmail.com Fri Apr 1 08:20:23 2011 From: 6yearold at gmail.com (arrowdodger) Date: Fri, 1 Apr 2011 17:20:23 +0400 Subject: [llvm-commits] [llvm] r128440 - in /llvm/trunk/tools/lto: Makefile lto.exports In-Reply-To: <20110329000139.73D4B2A6C12C@llvm.org> References: <20110329000139.73D4B2A6C12C@llvm.org> Message-ID: On Tue, Mar 29, 2011 at 4:01 AM, Devang Patel wrote: > New Revision: 128440 > --- llvm/trunk/tools/lto/Makefile (original) > +++ llvm/trunk/tools/lto/Makefile Mon Mar 28 19:01:39 2011 > @@ -20,7 +20,8 @@ > LINK_LIBS_IN_SHARED = 1 > SHARED_LIBRARY = 1 > > -LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader > bitwriter > +LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader \ > + bitwriter mcdisassembler > > include $(LEVEL)/Makefile.common > Is it intended? libLTO happily compiles even without mcdisassembler component. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110401/5812d0db/attachment.html From baldrick at free.fr Fri Apr 1 08:31:01 2011 From: baldrick at free.fr (Duncan Sands) Date: Fri, 01 Apr 2011 13:31:01 -0000 Subject: [llvm-commits] [dragonegg] r128711 - in /dragonegg/trunk: Debug.cpp Types.cpp Message-ID: <20110401133101.7108E2A6C12C@llvm.org> Author: baldrick Date: Fri Apr 1 08:31:01 2011 New Revision: 128711 URL: http://llvm.org/viewvc/llvm-project?rev=128711&view=rev Log: No need to check that the value is not null: isInt64 checks this (and returns false if it is null). Modified: dragonegg/trunk/Debug.cpp dragonegg/trunk/Types.cpp Modified: dragonegg/trunk/Debug.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Debug.cpp?rev=128711&r1=128710&r2=128711&view=diff ============================================================================== --- dragonegg/trunk/Debug.cpp (original) +++ dragonegg/trunk/Debug.cpp Fri Apr 1 08:31:01 2011 @@ -646,9 +646,9 @@ tree MaxValue = TYPE_MAX_VALUE(Domain); uint64_t Low = 0; uint64_t Hi = 0; - if (MinValue && isInt64(MinValue, 0)) + if (isInt64(MinValue, false)) Low = getINTEGER_CSTVal(MinValue); - if (MaxValue && isInt64(MaxValue, 0)) + if (isInt64(MaxValue, false)) Hi = getINTEGER_CSTVal(MaxValue); Subscripts.push_back(DebugFactory.GetOrCreateSubrange(Low, Hi)); } Modified: dragonegg/trunk/Types.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Types.cpp?rev=128711&r1=128710&r2=128711&view=diff ============================================================================== --- dragonegg/trunk/Types.cpp (original) +++ dragonegg/trunk/Types.cpp Fri Apr 1 08:31:01 2011 @@ -70,7 +70,7 @@ // variable size, that the LLVM type is not bigger than any possible value of // the GCC type. #ifndef NDEBUG - if (TYPE_SIZE(Tr) && Ty->isSized() && isInt64(TYPE_SIZE(Tr), true)) { + if (Ty->isSized() && isInt64(TYPE_SIZE(Tr), true)) { uint64_t LLVMSize = getTargetData().getTypeAllocSizeInBits(Ty); if (getInt64(TYPE_SIZE(Tr), true) != LLVMSize) { errs() << "GCC: "; From baldrick at free.fr Fri Apr 1 09:57:20 2011 From: baldrick at free.fr (Duncan Sands) Date: Fri, 01 Apr 2011 14:57:20 -0000 Subject: [llvm-commits] [dragonegg] r128712 - /dragonegg/trunk/Constants.cpp Message-ID: <20110401145720.EB6FF2A6C12C@llvm.org> Author: baldrick Date: Fri Apr 1 09:57:20 2011 New Revision: 128712 URL: http://llvm.org/viewvc/llvm-project?rev=128712&view=rev Log: Test harder the constants returned from ConvertInitializer: if there are no variable sized or incomplete types floating around, require the constant to have the same size as the type of the constructor. Modified: dragonegg/trunk/Constants.cpp Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=128712&r1=128711&r2=128712&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Fri Apr 1 09:57:20 2011 @@ -879,7 +879,7 @@ assert(FirstBit <= TypeSize && "Field off end of type!"); // Determine the width of the field. uint64_t BitWidth; - if (DECL_SIZE(field) && isInt64(DECL_SIZE(field), true)) { + if (isInt64(DECL_SIZE(field), true)) { // The field has a size and it is a constant, so use it. Note that // this size may be smaller than the type size. For example, if the // next field starts inside alignment padding at the end of this one @@ -930,7 +930,7 @@ assert(FirstBit <= TypeSize && "Field off end of type!"); // If a size was specified for the field then use it. Otherwise take the // size from the initial value. - uint64_t BitWidth = DECL_SIZE(field) && isInt64(DECL_SIZE(field), true) ? + uint64_t BitWidth = isInt64(DECL_SIZE(field), true) ? getInt64(DECL_SIZE(field), true) : TD.getTypeAllocSizeInBits(Init->getType()); uint64_t LastBit = FirstBit + BitWidth; @@ -1080,8 +1080,12 @@ /// ConvertInitializer - Convert the initial value for a global variable to an /// equivalent LLVM constant. Also handles constant constructors. The type of /// the returned value may be pretty much anything. All that is guaranteed is -/// that it has the same alloc size as the original expression and has alignment -/// equal to or less than that of the original expression. +/// that its alloc size is equal to the size of the initial value and that its +/// alignment is less than or equal to the initial value's GCC type alignment. +/// Note that the GCC type may have variable size or no size, in which case the +/// size is determined by the initial value. When this happens the size of the +/// initial value may exceed the alloc size of the LLVM memory type generated +/// for the GCC type (see ConvertType); it is never smaller than the alloc size. Constant *ConvertInitializer(tree exp) { Constant *Init; switch (TREE_CODE(exp)) { @@ -1122,13 +1126,28 @@ break; } - assert((!ConvertType(TREE_TYPE(exp))->isSized() || - getTargetData().getTypeAllocSizeInBits(ConvertType(TREE_TYPE(exp))) <= - getTargetData().getTypeAllocSizeInBits(Init->getType())) && - "Constant too small for type!"); +#ifndef NDEBUG + // Check that the guarantees we make about the returned value actually hold. + // The initializer should always be at least as big as the constructor's type, + // and except in the cases of incomplete types or types with variable size the + // sizes should be the same. + const Type *Ty = ConvertType(TREE_TYPE(exp)); + if (Ty->isSized()) { + uint64_t InitSize = getTargetData().getTypeAllocSizeInBits(Init->getType()); + uint64_t TypeSize = getTargetData().getTypeAllocSizeInBits(Ty); + if (InitSize < TypeSize) { + debug_tree(exp); + llvm_unreachable("Constant too small for type!"); + } + if (isInt64(TREE_TYPE(exp), true) && InitSize != TypeSize) { + debug_tree(exp); + llvm_unreachable("Constant too big for type!"); + } + } // FIXME: This check fails when building libdecnumber (self-host build). // assert(getTargetData().getABITypeAlignment(Init->getType()) * 8 <= // TYPE_ALIGN(TREE_TYPE(exp)) && "Constant over aligned!"); +#endif return Init; } From daniel at zuster.org Fri Apr 1 11:01:52 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Fri, 01 Apr 2011 16:01:52 -0000 Subject: [llvm-commits] [zorg] r128713 - /zorg/trunk/lnt/lnt/tests/nt.py Message-ID: <20110401160152.F2C3F2A6C12C@llvm.org> Author: ddunbar Date: Fri Apr 1 11:01:52 2011 New Revision: 128713 URL: http://llvm.org/viewvc/llvm-project?rev=128713&view=rev Log: LNT: Change recommended usage to be --simple and --without-llvm. Modified: zorg/trunk/lnt/lnt/tests/nt.py Modified: zorg/trunk/lnt/lnt/tests/nt.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/tests/nt.py?rev=128713&r1=128712&r2=128713&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/tests/nt.py (original) +++ zorg/trunk/lnt/lnt/tests/nt.py Fri Apr 1 11:01:52 2011 @@ -567,8 +567,7 @@ --sandbox FOO \\ --cc ~/llvm.obj.64/Release/bin/clang \\ --cxx ~/llvm.obj.64/Release/bin/clang++ \\ - --llvm-src ~/llvm \\ - --llvm-obj ~/llvm.obj.64 \\ + --without-llvm --simple \\ --test-suite ~/llvm-test-suite \\ FOO From daniel at zuster.org Fri Apr 1 11:01:57 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Fri, 01 Apr 2011 16:01:57 -0000 Subject: [llvm-commits] [zorg] r128714 - /zorg/trunk/lnt/lnt/tests/nt.py Message-ID: <20110401160157.3826D2A6C12D@llvm.org> Author: ddunbar Date: Fri Apr 1 11:01:57 2011 New Revision: 128714 URL: http://llvm.org/viewvc/llvm-project?rev=128714&view=rev Log: LNT/nt: Reject llc style options with --simple (they are unused). Modified: zorg/trunk/lnt/lnt/tests/nt.py Modified: zorg/trunk/lnt/lnt/tests/nt.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/tests/nt.py?rev=128714&r1=128713&r2=128714&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/tests/nt.py (original) +++ zorg/trunk/lnt/lnt/tests/nt.py Fri Apr 1 11:01:57 2011 @@ -37,17 +37,6 @@ target_flags.append('-isysroot') target_flags.append(opts.isysroot) - # Compute TARGET_LLCFLAGS. - target_llcflags = [] - if opts.mcpu is not None: - target_llcflags.append('-mcpu') - target_llcflags.append(opts.mcpu) - if opts.relocation_model is not None: - target_llcflags.append('-relocation-model') - target_llcflags.append(opts.relocation_model) - if opts.disable_fp_elim: - target_llcflags.append('-disable-fp-elim') - # Set the make variables to use. make_variables = { 'TARGET_CC' : opts.cc_reference, @@ -55,9 +44,22 @@ 'TARGET_LLVMGCC' : opts.cc_under_test, 'TARGET_LLVMGXX' : opts.cxx_under_test, 'TARGET_FLAGS' : ' '.join(target_flags), - 'TARGET_LLCFLAGS' : ' '.join(target_llcflags), } + # Compute TARGET_LLCFLAGS, for non-TEST=simple runs. + if not opts.test_simple: + # Compute TARGET_LLCFLAGS. + target_llcflags = [] + if opts.mcpu is not None: + target_llcflags.append('-mcpu') + target_llcflags.append(opts.mcpu) + if opts.relocation_model is not None: + target_llcflags.append('-relocation-model') + target_llcflags.append(opts.relocation_model) + if opts.disable_fp_elim: + target_llcflags.append('-disable-fp-elim') + make_variables['TARGET_LLCFLAGS'] = ' '.join(target_llcflags) + # Pick apart the build mode. build_mode = opts.build_mode if build_mode.startswith("Debug"): @@ -778,6 +780,15 @@ parser.error('--cc-reference is unused with --simple') if opts.cxx_reference is not None: parser.error('--cxx-reference is unused with --simple') + # TEST=simple doesn't use a llc options. + if opts.mcpu is not None: + parser.error('--mcpu is unused with --simple (use --cflag)') + if opts.relocation_model is not None: + parser.error('--relocation-model is unused with --simple ' + '(use --cflag)') + if opts.disable_fp_elim: + parser.error('--disable-fp-elim is unused with --simple ' + '(use --cflag)') else: if opts.without_llvm: parser.error('--simple is required with --without-llvm') From aggarwa4 at illinois.edu Fri Apr 1 11:45:50 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Fri, 01 Apr 2011 16:45:50 -0000 Subject: [llvm-commits] [poolalloc] r128716 - in /poolalloc/trunk/test/dsa/types: array2struct.ll dg.exp Message-ID: <20110401164550.2D4632A6C12C@llvm.org> Author: aggarwa4 Date: Fri Apr 1 11:45:49 2011 New Revision: 128716 URL: http://llvm.org/viewvc/llvm-project?rev=128716&view=rev Log: Example for folding of nodes due to llvm front end changes. Added: poolalloc/trunk/test/dsa/types/array2struct.ll poolalloc/trunk/test/dsa/types/dg.exp Added: poolalloc/trunk/test/dsa/types/array2struct.ll URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/types/array2struct.ll?rev=128716&view=auto ============================================================================== --- poolalloc/trunk/test/dsa/types/array2struct.ll (added) +++ poolalloc/trunk/test/dsa/types/array2struct.ll Fri Apr 1 11:45:49 2011 @@ -0,0 +1,30 @@ +; ModuleID = 'bugpoint-reduced-simplified.bc' +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-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" +;RUN: dsaopt %s -dsa-local -analyze -check-type=tree,FoldedVOID +; LLVM front end converts the type of tree, to a struct type instead of an array of the right type. +; even though structurally equivalent, DSA cant infer this yet. + +%0 = type { %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %1, %1, %1, %1, %1, %1, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %1 } +%1 = type { i32, i32, i32, [32 x i8] } +%struct..0tnode = type { i32, i32, i32, [8 x i32] } + + at tree = external global %0, align 32 ; <%0*> [#uses=1] + +define i32 @opening(i32* %i, i32* %j, i32 %type) nounwind { +entry: + br i1 undef, label %bb8, label %bb10 + +bb8: ; preds = %entry + br i1 undef, label %bb2.i, label %random_nasko.exit + +bb2.i: ; preds = %bb8 + br label %random_nasko.exit + +random_nasko.exit: ; preds = %bb2.i, %bb8 + %tmp81moda7 = getelementptr [21 x %struct..0tnode]* bitcast (%0* @tree to [21 x %struct..0tnode]*), i64 0, i64 undef, i32 3, i64 undef ; [#uses=0] + ret i32 1 + +bb10: ; preds = %entry + ret i32 0 +} Added: poolalloc/trunk/test/dsa/types/dg.exp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/types/dg.exp?rev=128716&view=auto ============================================================================== --- poolalloc/trunk/test/dsa/types/dg.exp (added) +++ poolalloc/trunk/test/dsa/types/dg.exp Fri Apr 1 11:45:49 2011 @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,cpp}]] From dpatel at apple.com Fri Apr 1 12:03:10 2011 From: dpatel at apple.com (Devang Patel) Date: Fri, 01 Apr 2011 10:03:10 -0700 Subject: [llvm-commits] [llvm] r128440 - in /llvm/trunk/tools/lto: Makefile lto.exports In-Reply-To: References: <20110329000139.73D4B2A6C12C@llvm.org> Message-ID: On Apr 1, 2011, at 6:20 AM, arrowdodger wrote: > On Tue, Mar 29, 2011 at 4:01 AM, Devang Patel wrote: > New Revision: 128440 > --- llvm/trunk/tools/lto/Makefile (original) > +++ llvm/trunk/tools/lto/Makefile Mon Mar 28 19:01:39 2011 > @@ -20,7 +20,8 @@ > LINK_LIBS_IN_SHARED = 1 > SHARED_LIBRARY = 1 > > -LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader bitwriter > +LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader \ > + bitwriter mcdisassembler > > include $(LEVEL)/Makefile.common > > Is it intended? Yes. To expose new functions listed in lto.exports file. - Devang > libLTO happily compiles even without mcdisassembler component. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110401/692ba46f/attachment.html From ahatanak at gmail.com Fri Apr 1 12:39:08 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Fri, 01 Apr 2011 17:39:08 -0000 Subject: [llvm-commits] [llvm] r128718 - in /llvm/trunk: lib/Target/Mips/MipsInstrInfo.cpp lib/Target/Mips/MipsInstrInfo.h test/CodeGen/Mips/analyzebranch.ll test/CodeGen/Mips/fpcmp.ll Message-ID: <20110401173908.F1C2B2A6C12C@llvm.org> Author: ahatanak Date: Fri Apr 1 12:39:08 2011 New Revision: 128718 URL: http://llvm.org/viewvc/llvm-project?rev=128718&view=rev Log: Add code for analyzing FP branches. Clean up branch Analysis functions. Added: llvm/trunk/test/CodeGen/Mips/analyzebranch.ll Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp llvm/trunk/lib/Target/Mips/MipsInstrInfo.h llvm/trunk/test/CodeGen/Mips/fpcmp.ll Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp?rev=128718&r1=128717&r2=128718&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp Fri Apr 1 12:39:08 2011 @@ -218,103 +218,42 @@ // Branch Analysis //===----------------------------------------------------------------------===// -/// GetCondFromBranchOpc - Return the Mips CC that matches -/// the correspondent Branch instruction opcode. -static Mips::CondCode GetCondFromBranchOpc(unsigned BrOpc) -{ - switch (BrOpc) { - default: return Mips::COND_INVALID; - case Mips::BEQ : return Mips::COND_E; - case Mips::BNE : return Mips::COND_NE; - case Mips::BGTZ : return Mips::COND_GZ; - case Mips::BGEZ : return Mips::COND_GEZ; - case Mips::BLTZ : return Mips::COND_LZ; - case Mips::BLEZ : return Mips::COND_LEZ; - - // We dont do fp branch analysis yet! - case Mips::BC1T : - case Mips::BC1F : return Mips::COND_INVALID; +static unsigned GetAnalyzableBrOpc(unsigned Opc) { + return (Opc == Mips::BEQ || Opc == Mips::BNE || Opc == Mips::BGTZ || + Opc == Mips::BGEZ || Opc == Mips::BLTZ || Opc == Mips::BLEZ || + Opc == Mips::BC1T || Opc == Mips::BC1F || Opc == Mips::J) ? Opc : 0; +} + +/// GetOppositeBranchOpc - Return the inverse of the specified +/// opcode, e.g. turning BEQ to BNE. +unsigned Mips::GetOppositeBranchOpc(unsigned Opc) +{ + switch (Opc) { + default: llvm_unreachable("Illegal opcode!"); + case Mips::BEQ : return Mips::BNE; + case Mips::BNE : return Mips::BEQ; + case Mips::BGTZ : return Mips::BLEZ; + case Mips::BGEZ : return Mips::BLTZ; + case Mips::BLTZ : return Mips::BGEZ; + case Mips::BLEZ : return Mips::BGTZ; + case Mips::BC1T : return Mips::BC1F; + case Mips::BC1F : return Mips::BC1T; } } -/// GetCondBranchFromCond - Return the Branch instruction -/// opcode that matches the cc. -unsigned Mips::GetCondBranchFromCond(Mips::CondCode CC) -{ - switch (CC) { - default: llvm_unreachable("Illegal condition code!"); - case Mips::COND_E : return Mips::BEQ; - case Mips::COND_NE : return Mips::BNE; - case Mips::COND_GZ : return Mips::BGTZ; - case Mips::COND_GEZ : return Mips::BGEZ; - case Mips::COND_LZ : return Mips::BLTZ; - case Mips::COND_LEZ : return Mips::BLEZ; - - case Mips::FCOND_F: - case Mips::FCOND_UN: - case Mips::FCOND_OEQ: - case Mips::FCOND_UEQ: - case Mips::FCOND_OLT: - case Mips::FCOND_ULT: - case Mips::FCOND_OLE: - case Mips::FCOND_ULE: - case Mips::FCOND_SF: - case Mips::FCOND_NGLE: - case Mips::FCOND_SEQ: - case Mips::FCOND_NGL: - case Mips::FCOND_LT: - case Mips::FCOND_NGE: - case Mips::FCOND_LE: - case Mips::FCOND_NGT: return Mips::BC1T; - - case Mips::FCOND_T: - case Mips::FCOND_OR: - case Mips::FCOND_UNE: - case Mips::FCOND_ONE: - case Mips::FCOND_UGE: - case Mips::FCOND_OGE: - case Mips::FCOND_UGT: - case Mips::FCOND_OGT: - case Mips::FCOND_ST: - case Mips::FCOND_GLE: - case Mips::FCOND_SNE: - case Mips::FCOND_GL: - case Mips::FCOND_NLT: - case Mips::FCOND_GE: - case Mips::FCOND_NLE: - case Mips::FCOND_GT: return Mips::BC1F; - } -} +static void AnalyzeCondBr(const MachineInstr* Inst, unsigned Opc, + MachineBasicBlock *&BB, + SmallVectorImpl& Cond) { + assert(GetAnalyzableBrOpc(Opc) && "Not an analyzable branch"); + int NumOp = Inst->getNumExplicitOperands(); + + // for both int and fp branches, the last explicit operand is the + // MBB. + BB = Inst->getOperand(NumOp-1).getMBB(); + Cond.push_back(MachineOperand::CreateImm(Opc)); -/// GetOppositeBranchCondition - Return the inverse of the specified -/// condition, e.g. turning COND_E to COND_NE. -Mips::CondCode Mips::GetOppositeBranchCondition(Mips::CondCode CC) -{ - switch (CC) { - default: llvm_unreachable("Illegal condition code!"); - case Mips::COND_E : return Mips::COND_NE; - case Mips::COND_NE : return Mips::COND_E; - case Mips::COND_GZ : return Mips::COND_LEZ; - case Mips::COND_GEZ : return Mips::COND_LZ; - case Mips::COND_LZ : return Mips::COND_GEZ; - case Mips::COND_LEZ : return Mips::COND_GZ; - case Mips::FCOND_F : return Mips::FCOND_T; - case Mips::FCOND_UN : return Mips::FCOND_OR; - case Mips::FCOND_OEQ: return Mips::FCOND_UNE; - case Mips::FCOND_UEQ: return Mips::FCOND_ONE; - case Mips::FCOND_OLT: return Mips::FCOND_UGE; - case Mips::FCOND_ULT: return Mips::FCOND_OGE; - case Mips::FCOND_OLE: return Mips::FCOND_UGT; - case Mips::FCOND_ULE: return Mips::FCOND_OGT; - case Mips::FCOND_SF: return Mips::FCOND_ST; - case Mips::FCOND_NGLE:return Mips::FCOND_GLE; - case Mips::FCOND_SEQ: return Mips::FCOND_SNE; - case Mips::FCOND_NGL: return Mips::FCOND_GL; - case Mips::FCOND_LT: return Mips::FCOND_NLT; - case Mips::FCOND_NGE: return Mips::FCOND_GE; - case Mips::FCOND_LE: return Mips::FCOND_NLE; - case Mips::FCOND_NGT: return Mips::FCOND_GT; - } + for (int i=0; igetOperand(i)); } bool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, @@ -323,91 +262,92 @@ SmallVectorImpl &Cond, bool AllowModify) const { - // If the block has no terminators, it just falls into the block after it. - MachineBasicBlock::iterator I = MBB.end(); - if (I == MBB.begin()) + MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); + + // Skip all the debug instructions. + while (I != REnd && I->isDebugValue()) + ++I; + + if (I == REnd || !isUnpredicatedTerminator(&*I)) { + // If this block ends with no branches (it just falls through to its succ) + // just return false, leaving TBB/FBB null. + TBB = FBB = NULL; return false; - --I; - while (I->isDebugValue()) { - if (I == MBB.begin()) - return false; - --I; } - if (!isUnpredicatedTerminator(I)) - return false; - // Get the last instruction in the block. - MachineInstr *LastInst = I; - - // If there is only one terminator instruction, process it. + MachineInstr *LastInst = &*I; unsigned LastOpc = LastInst->getOpcode(); - if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { - if (!LastInst->getDesc().isBranch()) + + // Not an analyzable branch (must be an indirect jump). + if (!GetAnalyzableBrOpc(LastOpc)) + return true; + + // Get the second to last instruction in the block. + unsigned SecondLastOpc = 0; + MachineInstr *SecondLastInst = NULL; + + if (++I != REnd) { + SecondLastInst = &*I; + SecondLastOpc = GetAnalyzableBrOpc(SecondLastInst->getOpcode()); + + // Not an analyzable branch (must be an indirect jump). + if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc) return true; + } + // If there is only one terminator instruction, process it. + if (!SecondLastOpc) { // Unconditional branch if (LastOpc == Mips::J) { TBB = LastInst->getOperand(0).getMBB(); return false; } - Mips::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode()); - if (BranchCode == Mips::COND_INVALID) - return true; // Can't handle indirect branch. - // Conditional branch - // Block ends with fall-through condbranch. - if (LastOpc != Mips::COND_INVALID) { - int LastNumOp = LastInst->getNumOperands(); - - TBB = LastInst->getOperand(LastNumOp-1).getMBB(); - Cond.push_back(MachineOperand::CreateImm(BranchCode)); - - for (int i=0; igetOperand(i)); - } - - return false; - } + AnalyzeCondBr(LastInst, LastOpc, TBB, Cond); + return false; } - // Get the instruction before it if it is a terminator. - MachineInstr *SecondLastInst = I; - + // If we reached here, there are two branches. // If there are three terminators, we don't know what sort of block this is. - if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) + if (++I != REnd && isUnpredicatedTerminator(&*I)) return true; - // If the block ends with Mips::J and a Mips::BNE/Mips::BEQ, handle it. - unsigned SecondLastOpc = SecondLastInst->getOpcode(); - Mips::CondCode BranchCode = GetCondFromBranchOpc(SecondLastOpc); + // If second to last instruction is an unconditional branch, + // analyze it and remove the last instruction. + if (SecondLastOpc == Mips::J) { + // Return if the last instruction cannot be removed. + if (!AllowModify) + return true; - if (BranchCode != Mips::COND_INVALID && LastOpc == Mips::J) { - int SecondNumOp = SecondLastInst->getNumOperands(); + TBB = SecondLastInst->getOperand(0).getMBB(); + LastInst->eraseFromParent(); + return false; + } - TBB = SecondLastInst->getOperand(SecondNumOp-1).getMBB(); - Cond.push_back(MachineOperand::CreateImm(BranchCode)); + // Conditional branch followed by an unconditional branch. + // The last one must be unconditional. + if (LastOpc != Mips::J) + return true; - for (int i=0; igetOperand(i)); - } + AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond); + FBB = LastInst->getOperand(0).getMBB(); - FBB = LastInst->getOperand(0).getMBB(); - return false; - } + return false; +} + +void MipsInstrInfo::BuildCondBr(MachineBasicBlock &MBB, + MachineBasicBlock *TBB, DebugLoc DL, + const SmallVectorImpl& Cond) + const { + unsigned Opc = Cond[0].getImm(); + const TargetInstrDesc &TID = get(Opc); + MachineInstrBuilder MIB = BuildMI(&MBB, DL, TID); - // If the block ends with two unconditional branches, handle it. The last - // one is not executed, so remove it. - if ((SecondLastOpc == Mips::J) && (LastOpc == Mips::J)) { - TBB = SecondLastInst->getOperand(0).getMBB(); - I = LastInst; - if (AllowModify) - I->eraseFromParent(); - return false; - } + for (unsigned i = 1; i < Cond.size(); ++i) + MIB.addReg(Cond[i].getReg()); - // Otherwise, can't handle this. - return true; + MIB.addMBB(TBB); } unsigned MipsInstrInfo:: @@ -417,72 +357,53 @@ DebugLoc DL) const { // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); - assert((Cond.size() == 3 || Cond.size() == 2 || Cond.size() == 0) && - "Mips branch conditions can have two|three components!"); - if (FBB == 0) { // One way branch. - if (Cond.empty()) { - // Unconditional branch? - BuildMI(&MBB, DL, get(Mips::J)).addMBB(TBB); - } else { - // Conditional branch. - unsigned Opc = GetCondBranchFromCond((Mips::CondCode)Cond[0].getImm()); - const TargetInstrDesc &TID = get(Opc); - - if (TID.getNumOperands() == 3) - BuildMI(&MBB, DL, TID).addReg(Cond[1].getReg()) - .addReg(Cond[2].getReg()) - .addMBB(TBB); - else - BuildMI(&MBB, DL, TID).addReg(Cond[1].getReg()) - .addMBB(TBB); - - } - return 1; - } + // # of condition operands: + // Unconditional branches: 0 + // Floating point branches: 1 (opc) + // Int BranchZero: 2 (opc, reg) + // Int Branch: 3 (opc, reg0, reg1) + assert((Cond.size() <= 3) && + "# of Mips branch conditions must be <= 3!"); // Two-way Conditional branch. - unsigned Opc = GetCondBranchFromCond((Mips::CondCode)Cond[0].getImm()); - const TargetInstrDesc &TID = get(Opc); - - if (TID.getNumOperands() == 3) - BuildMI(&MBB, DL, TID).addReg(Cond[1].getReg()).addReg(Cond[2].getReg()) - .addMBB(TBB); - else - BuildMI(&MBB, DL, TID).addReg(Cond[1].getReg()).addMBB(TBB); + if (FBB) { + BuildCondBr(MBB, TBB, DL, Cond); + BuildMI(&MBB, DL, get(Mips::J)).addMBB(FBB); + return 2; + } - BuildMI(&MBB, DL, get(Mips::J)).addMBB(FBB); - return 2; + // One way branch. + // Unconditional branch. + if (Cond.empty()) + BuildMI(&MBB, DL, get(Mips::J)).addMBB(TBB); + else // Conditional branch. + BuildCondBr(MBB, TBB, DL, Cond); + return 1; } unsigned MipsInstrInfo:: RemoveBranch(MachineBasicBlock &MBB) const { - MachineBasicBlock::iterator I = MBB.end(); - if (I == MBB.begin()) return 0; - --I; - while (I->isDebugValue()) { - if (I == MBB.begin()) - return 0; - --I; - } - if (I->getOpcode() != Mips::J && - GetCondFromBranchOpc(I->getOpcode()) == Mips::COND_INVALID) - return 0; - - // Remove the branch. - I->eraseFromParent(); - - I = MBB.end(); - - if (I == MBB.begin()) return 1; - --I; - if (GetCondFromBranchOpc(I->getOpcode()) == Mips::COND_INVALID) - return 1; - - // Remove the branch. - I->eraseFromParent(); - return 2; + MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); + MachineBasicBlock::reverse_iterator FirstBr; + unsigned removed; + + // Skip all the debug instructions. + while (I != REnd && I->isDebugValue()) + ++I; + + FirstBr = I; + + // Up to 2 branches are removed. + // Note that indirect branches are not removed. + for(removed = 0; I != REnd && removed < 2; ++I, ++removed) + if (!GetAnalyzableBrOpc(I->getOpcode())) + break; + + MBB.erase(I.base(), FirstBr.base()); + + return removed; } /// ReverseBranchCondition - Return the inverse opcode of the @@ -490,9 +411,9 @@ bool MipsInstrInfo:: ReverseBranchCondition(SmallVectorImpl &Cond) const { - assert( (Cond.size() == 3 || Cond.size() == 2) && + assert( (Cond.size() && Cond.size() <= 3) && "Invalid Mips branch condition!"); - Cond[0].setImm(GetOppositeBranchCondition((Mips::CondCode)Cond[0].getImm())); + Cond[0].setImm(Mips::GetOppositeBranchOpc(Cond[0].getImm())); return false; } Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.h?rev=128718&r1=128717&r2=128718&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.h (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.h Fri Apr 1 12:39:08 2011 @@ -70,24 +70,12 @@ FCOND_NLT, FCOND_GE, FCOND_NLE, - FCOND_GT, - - // Only integer conditions - COND_E, - COND_GZ, - COND_GEZ, - COND_LZ, - COND_LEZ, - COND_NE, - COND_INVALID + FCOND_GT }; - // Turn condition code into conditional branch opcode. - unsigned GetCondBranchFromCond(CondCode CC); - - /// GetOppositeBranchCondition - Return the inverse of the specified cond, - /// e.g. turning COND_E to COND_NE. - CondCode GetOppositeBranchCondition(Mips::CondCode CC); + /// GetOppositeBranchOpc - Return the inverse of the specified + /// opcode, e.g. turning BEQ to BNE. + unsigned GetOppositeBranchOpc(unsigned Opc); /// MipsCCToString - Map each FP condition code to its string inline static const char *MipsFCCToString(Mips::CondCode CC) @@ -196,6 +184,12 @@ SmallVectorImpl &Cond, bool AllowModify) const; virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const; + +private: + void BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB, DebugLoc DL, + const SmallVectorImpl& Cond) const; + +public: virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl &Cond, Added: llvm/trunk/test/CodeGen/Mips/analyzebranch.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/analyzebranch.ll?rev=128718&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/Mips/analyzebranch.ll (added) +++ llvm/trunk/test/CodeGen/Mips/analyzebranch.ll Fri Apr 1 12:39:08 2011 @@ -0,0 +1,46 @@ +; RUN: llc -march=mips < %s | FileCheck %s + +define double @foo(double %a, double %b) nounwind readnone { +entry: +; CHECK: bc1f $BB0_2 +; CHECK: nop +; CHECK: # BB#1: + + %cmp = fcmp ogt double %a, 0.000000e+00 + br i1 %cmp, label %if.end6, label %if.else + +if.else: ; preds = %entry + %cmp3 = fcmp ogt double %b, 0.000000e+00 + br i1 %cmp3, label %if.end6, label %return + +if.end6: ; preds = %if.else, %entry + %c.0 = phi double [ %a, %entry ], [ 0.000000e+00, %if.else ] + %sub = fsub double %b, %c.0 + %mul = fmul double %sub, 2.000000e+00 + br label %return + +return: ; preds = %if.else, %if.end6 + %retval.0 = phi double [ %mul, %if.end6 ], [ 0.000000e+00, %if.else ] + ret double %retval.0 +} + +define void @f1(float %f) nounwind { +entry: +; CHECK: bc1t $BB1_2 +; CHECK: nop +; CHECK: # BB#1: + %cmp = fcmp une float %f, 0.000000e+00 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + tail call void @abort() noreturn + unreachable + +if.end: ; preds = %entry + tail call void (...)* @f2() nounwind + ret void +} + +declare void @abort() noreturn nounwind + +declare void @f2(...) Modified: llvm/trunk/test/CodeGen/Mips/fpcmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/fpcmp.ll?rev=128718&r1=128717&r2=128718&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Mips/fpcmp.ll (original) +++ llvm/trunk/test/CodeGen/Mips/fpcmp.ll Fri Apr 1 12:39:08 2011 @@ -10,9 +10,9 @@ ; CHECK-MIPS32R2: c.olt.s ; CHECK-MIPS32R2: movt ; CHECK-MIPS1: c.olt.s -; CHECK-MIPS1: bc1f +; CHECK-MIPS1: bc1t ; CHECK-MIPS1: c.olt.s -; CHECK-MIPS1: bc1f +; CHECK-MIPS1: bc1t %cmp = fcmp olt float %f0, %f1 %conv = zext i1 %cmp to i32 %tmp2 = load i32* @g1, align 4 From 6yearold at gmail.com Fri Apr 1 12:59:43 2011 From: 6yearold at gmail.com (arrowdodger) Date: Fri, 1 Apr 2011 21:59:43 +0400 Subject: [llvm-commits] [llvm] r128440 - in /llvm/trunk/tools/lto: Makefile lto.exports In-Reply-To: References: <20110329000139.73D4B2A6C12C@llvm.org> Message-ID: On Fri, Apr 1, 2011 at 9:03 PM, Devang Patel wrote: > Yes. To expose new functions listed in lto.exports file. > Then, this patch should be commited too, i think. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110401/3bae35cc/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: lto.diff Type: text/x-patch Size: 434 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110401/3bae35cc/attachment.bin From dpatel at apple.com Fri Apr 1 13:03:58 2011 From: dpatel at apple.com (Devang Patel) Date: Fri, 01 Apr 2011 18:03:58 -0000 Subject: [llvm-commits] [llvm] r128719 - /llvm/trunk/tools/lto/CMakeLists.txt Message-ID: <20110401180358.A6C3B2A6C12C@llvm.org> Author: dpatel Date: Fri Apr 1 13:03:58 2011 New Revision: 128719 URL: http://llvm.org/viewvc/llvm-project?rev=128719&view=rev Log: Update CMakeLists.txt Patch by arrowdoger. Modified: llvm/trunk/tools/lto/CMakeLists.txt Modified: llvm/trunk/tools/lto/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/CMakeLists.txt?rev=128719&r1=128718&r2=128719&view=diff ============================================================================== --- llvm/trunk/tools/lto/CMakeLists.txt (original) +++ llvm/trunk/tools/lto/CMakeLists.txt Fri Apr 1 13:03:58 2011 @@ -1,6 +1,6 @@ set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} - ipo scalaropts linker bitreader bitwriter) + ipo scalaropts linker bitreader bitwriter mcdisassembler) add_definitions( -DLLVM_VERSION_INFO=\"${PACKAGE_VERSION}\" ) From dpatel at apple.com Fri Apr 1 13:08:31 2011 From: dpatel at apple.com (Devang Patel) Date: Fri, 01 Apr 2011 11:08:31 -0700 Subject: [llvm-commits] [llvm] r128440 - in /llvm/trunk/tools/lto: Makefile lto.exports In-Reply-To: References: <20110329000139.73D4B2A6C12C@llvm.org> Message-ID: <042ACAA7-F86E-47DD-92EA-67659650E1B2@apple.com> On Apr 1, 2011, at 10:59 AM, arrowdodger wrote: > Then, this patch should be commited too, i think. Done. r128719. - Devang From ahatanak at gmail.com Fri Apr 1 13:10:04 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Fri, 1 Apr 2011 11:10:04 -0700 Subject: [llvm-commits] patch Message-ID: This patch modifies MipsAsmPrinter::isBlockOnlyReachableByFallthrough so that it handles delay slots correctly. Index: lib/Target/Mips/MipsAsmPrinter.cpp =================================================================== --- lib/Target/Mips/MipsAsmPrinter.cpp (revision 128718) +++ lib/Target/Mips/MipsAsmPrinter.cpp (working copy) @@ -247,7 +247,33 @@ if (isa(bb->getTerminator())) return false; - return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB); + // If this is a landing pad, it isn't a fall through. If it has no preds, + // then nothing falls through to it. + if (MBB->isLandingPad() || MBB->pred_empty()) + return false; + + // If there isn't exactly one predecessor, it can't be a fall through. + MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; + ++PI2; + + if (PI2 != MBB->pred_end()) + return false; + + // The predecessor has to be immediately before this block. + if (!Pred->isLayoutSuccessor(MBB)) + return false; + + // If the block is completely empty, then it definitely does fall through. + if (Pred->empty()) + return true; + + // Otherwise, check the last instruction. + // Check if the last terminator is an unconditional branch. + MachineBasicBlock::const_iterator I = Pred->end(); + while (I != Pred->begin() && !(--I)->getDesc().isTerminator()) + ; + + return !I->getDesc().isBarrier(); } // Print out an operand for an inline asm expression. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110401/3529b97a/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: isBlockOnlyReachableByFallthrough.patch Type: text/x-patch Size: 1359 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110401/3529b97a/attachment.bin From bruno.cardoso at gmail.com Fri Apr 1 13:23:47 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Fri, 1 Apr 2011 15:23:47 -0300 Subject: [llvm-commits] patch In-Reply-To: References: Message-ID: LGTM, one minor note: On Fri, Apr 1, 2011 at 3:10 PM, Akira Hatanaka wrote: > This patch modifies MipsAsmPrinter::isBlockOnlyReachableByFallthrough so > that it handles delay slots correctly. > > > Index: lib/Target/Mips/MipsAsmPrinter.cpp > =================================================================== > --- lib/Target/Mips/MipsAsmPrinter.cpp? (revision 128718) > +++ lib/Target/Mips/MipsAsmPrinter.cpp? (working copy) > @@ -247,7 +247,33 @@ > ???? if (isa(bb->getTerminator())) > ?????? return false; > > -? return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB); > +? // If this is a landing pad, it isn't a fall through.? If it has no > preds, > +? // then nothing falls through to it. > +? if (MBB->isLandingPad() || MBB->pred_empty()) > +??? return false; > + > +? // If there isn't exactly one predecessor, it can't be a fall through. > +? MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; > +? ++PI2; > + > +? if (PI2 != MBB->pred_end()) > +??? return false; > + > +? // The predecessor has to be immediately before this block. > +? if (!Pred->isLayoutSuccessor(MBB)) > +??? return false; > + > +? // If the block is completely empty, then it definitely does fall > through. > +? if (Pred->empty()) > +??? return true; > + > +? // Otherwise, check the last instruction. > +? // Check if the last terminator is an unconditional branch. > +? MachineBasicBlock::const_iterator I = Pred->end(); > +? while (I != Pred->begin() && !(--I)->getDesc().isTerminator()) > +??? ; Use: while (I != Pred->begin() && !(--I)->getDesc().isTerminator()); Instead of: while (I != Pred->begin() && !(--I)->getDesc().isTerminator()) ; -- Bruno Cardoso Lopes http://www.brunocardoso.cc From johnny.chen at apple.com Fri Apr 1 13:26:38 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 01 Apr 2011 18:26:38 -0000 Subject: [llvm-commits] [llvm] r128722 - in /llvm/trunk: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp test/MC/Disassembler/ARM/arm-tests.txt Message-ID: <20110401182638.488432A6C12C@llvm.org> Author: johnny Date: Fri Apr 1 13:26:38 2011 New Revision: 128722 URL: http://llvm.org/viewvc/llvm-project?rev=128722&view=rev Log: Fix LDRi12 immediate operand, which was changed to be the second operand in $addrmode_imm12 => (ops GPR:$base, i32imm:$offsimm). rdar://problem/9219356 Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128722&r1=128721&r2=128722&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Fri Apr 1 13:26:38 2011 @@ -1098,10 +1098,11 @@ OpIdx += 1; } - // Disassemble the 12-bit immediate offset. + // Disassemble the 12-bit immediate offset, which is the second operand in + // $addrmode_imm12 => (ops GPR:$base, i32imm:$offsimm). + // unsigned Imm12 = slice(insn, 11, 0); - unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift, - IndexMode); + int Offset = AddrOpcode == ARM_AM::add ? 1 * Imm12 : -1 * Imm12; MI.addOperand(MCOperand::CreateImm(Offset)); OpIdx += 1; } else { Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=128722&r1=128721&r2=128722&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Fri Apr 1 13:26:38 2011 @@ -164,6 +164,15 @@ # CHECK: ldr r3, [pc, #144] 0x90 0x30 0x9f 0xe5 +# CHECK: ldr r3, [r0, #-4] +0x4 0x30 0x10 0xe5 + +# CHECK: ldr r5, [sp, r0, lsl #1]! +0x80 0x50 0xbd 0xe7 + +# CHECK: ldr r5, [r7], -r0, lsr #2 +0x20 0x51 0x17 0xe6 + # CHECK: strdeq r2, r3, [r0], -r8 0xf8 0x24 0x00 0x00 From ahatanak at gmail.com Fri Apr 1 13:57:38 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Fri, 01 Apr 2011 18:57:38 -0000 Subject: [llvm-commits] [llvm] r128724 - /llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Message-ID: <20110401185738.C36F32A6C12C@llvm.org> Author: ahatanak Date: Fri Apr 1 13:57:38 2011 New Revision: 128724 URL: http://llvm.org/viewvc/llvm-project?rev=128724&view=rev Log: Modifies MipsAsmPrinter::isBlockOnlyReachableByFallthrough so that it handles delay slots correctly. Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=128724&r1=128723&r2=128724&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Fri Apr 1 13:57:38 2011 @@ -247,7 +247,32 @@ if (isa(bb->getTerminator())) return false; - return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB); + // If this is a landing pad, it isn't a fall through. If it has no preds, + // then nothing falls through to it. + if (MBB->isLandingPad() || MBB->pred_empty()) + return false; + + // If there isn't exactly one predecessor, it can't be a fall through. + MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; + ++PI2; + + if (PI2 != MBB->pred_end()) + return false; + + // The predecessor has to be immediately before this block. + if (!Pred->isLayoutSuccessor(MBB)) + return false; + + // If the block is completely empty, then it definitely does fall through. + if (Pred->empty()) + return true; + + // Otherwise, check the last instruction. + // Check if the last terminator is an unconditional branch. + MachineBasicBlock::const_iterator I = Pred->end(); + while (I != Pred->begin() && !(--I)->getDesc().isTerminator()); + + return !I->getDesc().isBarrier(); } // Print out an operand for an inline asm expression. From ofv at wanadoo.es Fri Apr 1 14:36:06 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Fri, 01 Apr 2011 19:36:06 -0000 Subject: [llvm-commits] [llvm] r128727 - in /llvm/trunk: cmake/modules/HandleLLVMOptions.cmake tools/llvm-config/CMakeLists.txt Message-ID: <20110401193607.03C442A6C12C@llvm.org> Author: ofv Date: Fri Apr 1 14:36:06 2011 New Revision: 128727 URL: http://llvm.org/viewvc/llvm-project?rev=128727&view=rev Log: Fix assignment of -fPIC to CMAKE_C_FLAGS. Configure llvm-config.in.in with the contents of CMAKE_C(XX)_FLAGS too, else `llvm-config --c(xx)flags' doesn't tell the absolute truth. This comes from PR9603 and is based on a patch by Ryuta Suzuki! Modified: llvm/trunk/cmake/modules/HandleLLVMOptions.cmake llvm/trunk/tools/llvm-config/CMakeLists.txt Modified: llvm/trunk/cmake/modules/HandleLLVMOptions.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/HandleLLVMOptions.cmake?rev=128727&r1=128726&r2=128727&view=diff ============================================================================== --- llvm/trunk/cmake/modules/HandleLLVMOptions.cmake (original) +++ llvm/trunk/cmake/modules/HandleLLVMOptions.cmake Fri Apr 1 14:36:06 2011 @@ -84,7 +84,7 @@ if( SUPPORTS_FPIC_FLAG ) message(STATUS "Building with -fPIC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") - set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") else( SUPPORTS_FPIC_FLAG ) message(WARNING "-fPIC not supported.") endif() Modified: llvm/trunk/tools/llvm-config/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-config/CMakeLists.txt?rev=128727&r1=128726&r2=128727&view=diff ============================================================================== --- llvm/trunk/tools/llvm-config/CMakeLists.txt (original) +++ llvm/trunk/tools/llvm-config/CMakeLists.txt Fri Apr 1 14:36:06 2011 @@ -7,7 +7,7 @@ set(PERL ${PERL_EXECUTABLE}) set(VERSION PACKAGE_VERSION) -set(PREFIX ${LLVM_BINARY_DIR}) # TODO: Root for `make install'. +set(PREFIX ${CMAKE_INSTALL_PREFIX}) set(abs_top_srcdir ${LLVM_MAIN_SRC_DIR}) set(abs_top_builddir ${LLVM_BINARY_DIR}) execute_process(COMMAND date @@ -91,9 +91,13 @@ DEPENDS ${LIBDEPS} COMMENT "Checking for cyclic dependencies between LLVM libraries.") -set(C_FLGS "${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") -set(CXX_FLGS "${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") -set(CPP_FLGS "${CMAKE_CPP_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") +set(C_FLGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") +message(STATUS "C_FLGS: ${C_FLGS}") +message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") +message(STATUS "LLVM_DEFINITIONS: ${LLVM_DEFINITIONS}") +message(STATUS "other: ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}") +set(CXX_FLGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") +set(CPP_FLGS "${CMAKE_CPP_FLAGS} ${CMAKE_CPP_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") # We don't want certain flags on the output of # llvm-config --cflags --cxxflags From ahatanak at gmail.com Fri Apr 1 14:44:32 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Fri, 1 Apr 2011 12:44:32 -0700 Subject: [llvm-commits] MIPS patch Message-ID: This patch simplifies logic for printing target flags. Index: lib/Target/Mips/MipsAsmPrinter.cpp =================================================================== --- lib/Target/Mips/MipsAsmPrinter.cpp (revision 128724) +++ lib/Target/Mips/MipsAsmPrinter.cpp (working copy) @@ -298,23 +298,10 @@ switch(MO.getTargetFlags()) { case MipsII::MO_GPREL: O << "%gp_rel("; break; case MipsII::MO_GOT_CALL: O << "%call16("; break; - case MipsII::MO_GOT: { - const MachineOperand &LastMO = MI->getOperand(opNum-1); - bool LastMOIsGP = LastMO.getType() == MachineOperand::MO_Register - && LastMO.getReg() == Mips::GP; - if (MI->getOpcode() == Mips::LW || LastMOIsGP) - O << "%got("; - else - O << "%lo("; - break; + case MipsII::MO_GOT: O << "%got("; break; + case MipsII::MO_ABS_HI: O << "%hi("; break; + case MipsII::MO_ABS_LO: O << "%lo("; break; } - case MipsII::MO_ABS_HILO: - if (MI->getOpcode() == Mips::LUi) - O << "%hi("; - else - O << "%lo("; - break; - } switch (MO.getType()) { case MachineOperand::MO_Register: Index: lib/Target/Mips/MipsInstrInfo.h =================================================================== --- lib/Target/Mips/MipsInstrInfo.h (revision 128724) +++ lib/Target/Mips/MipsInstrInfo.h (working copy) @@ -143,10 +143,10 @@ /// for the relocatable object file being produced. MO_GPREL, - /// MO_ABS_HILO - Represents the hi or low part of an absolute symbol + /// MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol /// address. - MO_ABS_HILO - + MO_ABS_HI, + MO_ABS_LO }; } Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp (revision 128724) +++ lib/Target/Mips/MipsISelLowering.cpp (working copy) @@ -769,12 +769,13 @@ return DAG.getNode(ISD::ADD, dl, MVT::i32, GOT, GPRelNode); } // %hi/%lo relocation - SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, - MipsII::MO_ABS_HILO); - SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, VTs, &GA, 1); - SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GA); + SDValue GAHi = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_ABS_HI); + SDValue GALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_ABS_LO); + SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, VTs, &GAHi, 1); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GALo); return DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); - } else { SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, MipsII::MO_GOT); @@ -785,7 +786,9 @@ // a load from got/GP is necessary for PIC to work. if (!GV->hasLocalLinkage() || isa(GV)) return ResNode; - SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GA); + SDValue GALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_ABS_LO); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GALo); return DAG.getNode(ISD::ADD, dl, MVT::i32, ResNode, Lo); } @@ -806,7 +809,7 @@ SDValue BAGOTOffset = DAG.getBlockAddress(BA, MVT::i32, true, MipsII::MO_GOT); SDValue BALOOffset = DAG.getBlockAddress(BA, MVT::i32, true, - MipsII::MO_ABS_HILO); + MipsII::MO_ABS_LO); SDValue Load = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), BAGOTOffset, MachinePointerInfo(), false, false, 0); @@ -830,7 +833,7 @@ // FIXME there isn't actually debug info here DebugLoc dl = Op.getDebugLoc(); bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_; - unsigned char OpFlag = IsPIC ? MipsII::MO_GOT : MipsII::MO_ABS_HILO; + unsigned char OpFlag = IsPIC ? MipsII::MO_GOT : MipsII::MO_ABS_HI; EVT PtrVT = Op.getValueType(); JumpTableSDNode *JT = cast(Op); @@ -845,7 +848,8 @@ MachinePointerInfo(), false, false, 0); - SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, JTI); + SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MipsII::MO_ABS_LO); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, JTILo); ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); return ResNode; @@ -871,18 +875,22 @@ // ResNode = DAG.getNode(ISD::ADD, MVT::i32, GOT, GPRelNode); if (getTargetMachine().getRelocationModel() != Reloc::PIC_) { - SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), - N->getOffset(), MipsII::MO_ABS_HILO); - SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, MVT::i32, CP); - SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CP); + SDValue CPHi = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), + N->getOffset(), MipsII::MO_ABS_HI); + SDValue CPLo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), + N->getOffset(), MipsII::MO_ABS_LO); + SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, MVT::i32, CPHi); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CPLo); ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); } else { SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), - N->getOffset(), MipsII::MO_GOT); + N->getOffset(), MipsII::MO_GOT); SDValue Load = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), CP, MachinePointerInfo::getConstantPool(), false, false, 0); - SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CP); + SDValue CPLo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), + N->getOffset(), MipsII::MO_ABS_LO); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CPLo); ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, Load, Lo); } -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110401/018eb713/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: targetflag.patch Type: text/x-patch Size: 6394 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110401/018eb713/attachment.bin From evan.cheng at apple.com Fri Apr 1 14:42:23 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 01 Apr 2011 19:42:23 -0000 Subject: [llvm-commits] [llvm] r128728 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Message-ID: <20110401194223.2F8742A6C12C@llvm.org> Author: evancheng Date: Fri Apr 1 14:42:22 2011 New Revision: 128728 URL: http://llvm.org/viewvc/llvm-project?rev=128728&view=rev Log: Assign node order numbers to results of call instruction lowering. This should improve src line debug info when sdisel is used. rdar://9199118 Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=128728&r1=128727&r2=128728&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Fri Apr 1 14:42:22 2011 @@ -4927,15 +4927,19 @@ DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), DAG.getVTList(&RetTys[0], RetTys.size()), &ReturnValues[0], ReturnValues.size())); - } // As a special case, a null chain means that a tail call has been emitted and // the DAG root is already updated. - if (Result.second.getNode()) - DAG.setRoot(Result.second); - else + if (!Result.second.getNode()) { HasTailCall = true; + ++SDNodeOrder; + AssignOrderingToNode(DAG.getRoot().getNode()); + } else { + DAG.setRoot(Result.second); + ++SDNodeOrder; + AssignOrderingToNode(Result.second.getNode()); + } if (LandingPad) { // Insert a label at the end of the invoke call to mark the try range. This From evan.cheng at apple.com Fri Apr 1 14:57:02 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 01 Apr 2011 19:57:02 -0000 Subject: [llvm-commits] [llvm] r128730 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Message-ID: <20110401195702.30E192A6C12C@llvm.org> Author: evancheng Date: Fri Apr 1 14:57:01 2011 New Revision: 128730 URL: http://llvm.org/viewvc/llvm-project?rev=128730&view=rev Log: Add comments. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=128730&r1=128729&r2=128730&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Fri Apr 1 14:57:01 2011 @@ -4929,9 +4929,11 @@ &ReturnValues[0], ReturnValues.size())); } - // As a special case, a null chain means that a tail call has been emitted and - // the DAG root is already updated. + // Assign order to nodes here. If the call does not produce a result, it won't + // be mapped to a SDNode and visit() will not assign it an order number. if (!Result.second.getNode()) { + // As a special case, a null chain means that a tail call has been emitted and + // the DAG root is already updated. HasTailCall = true; ++SDNodeOrder; AssignOrderingToNode(DAG.getRoot().getNode()); From benny.kra at googlemail.com Fri Apr 1 15:09:03 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 01 Apr 2011 20:09:03 -0000 Subject: [llvm-commits] [llvm] r128731 - in /llvm/trunk/lib/Transforms/InstCombine: InstCombine.h InstCombineCasts.cpp Message-ID: <20110401200903.7A3CC2A6C12C@llvm.org> Author: d0k Date: Fri Apr 1 15:09:03 2011 New Revision: 128731 URL: http://llvm.org/viewvc/llvm-project?rev=128731&view=rev Log: InstCombine: Move (sext icmp) transforms into their own method. No intended functionality change. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombine.h llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombine.h?rev=128731&r1=128730&r2=128731&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombine.h (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombine.h Fri Apr 1 15:09:03 2011 @@ -217,6 +217,7 @@ Instruction *transformCallThroughTrampoline(CallSite CS); Instruction *transformZExtICmp(ICmpInst *ICI, Instruction &CI, bool DoXform = true); + Instruction *transformSExtICmp(ICmpInst *ICI, Instruction &CI); bool WillNotOverflowSignedAdd(Value *LHS, Value *RHS); Value *EmitGEPOffset(User *GEP); Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=128731&r1=128730&r2=128731&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Fri Apr 1 15:09:03 2011 @@ -876,6 +876,46 @@ return 0; } +/// transformSExtICmp - Transform (sext icmp) to bitwise / integer operations +/// in order to eliminate the icmp. +Instruction *InstCombiner::transformSExtICmp(ICmpInst *ICI, Instruction &CI) { + Value *Op0 = ICI->getOperand(0), *Op1 = ICI->getOperand(1); + ICmpInst::Predicate Pred = ICI->getPredicate(); + + if (ConstantInt *Op1C = dyn_cast(Op1)) { + // (x ashr x, 31 -> all ones if signed + // (x >s -1) ? -1 : 0 -> ashr x, 31 -> all ones if not signed + if ((Pred == ICmpInst::ICMP_SLT && Op1C->isZero()) || + (Pred == ICmpInst::ICMP_SGT && Op1C->isAllOnesValue())) { + + Value *Sh = ConstantInt::get(Op0->getType(), + Op0->getType()->getScalarSizeInBits()-1); + Value *In = Builder->CreateAShr(Op0, Sh, Op0->getName()+".lobit"); + if (In->getType() != CI.getType()) + In = Builder->CreateIntCast(In, CI.getType(), true/*SExt*/, "tmp"); + + if (Pred == ICmpInst::ICMP_SGT) + In = Builder->CreateNot(In, In->getName()+".not"); + return ReplaceInstUsesWith(CI, In); + } + } + + // vector (x ashr x, 31 -> all ones if signed. + if (const VectorType *VTy = dyn_cast(CI.getType())) { + if (Pred == ICmpInst::ICMP_SLT && match(Op1, m_Zero()) && + Op0->getType() == CI.getType()) { + const Type *EltTy = VTy->getElementType(); + + // splat the shift constant to a constant vector. + Constant *VSh = ConstantInt::get(VTy, EltTy->getScalarSizeInBits()-1); + Value *In = Builder->CreateAShr(Op0, VSh, Op0->getName()+".lobit"); + return ReplaceInstUsesWith(CI, In); + } + } + + return 0; +} + /// CanEvaluateSExtd - Return true if we can take the specified value /// and return it as type Ty without inserting any new casts and without /// changing the value of the common low bits. This is used by code that tries @@ -999,44 +1039,9 @@ Value *Res = Builder->CreateShl(TI->getOperand(0), ShAmt, "sext"); return BinaryOperator::CreateAShr(Res, ShAmt); } - - - // (x ashr x, 31 -> all ones if signed - // (x >s -1) ? -1 : 0 -> ashr x, 31 -> all ones if not signed - { - ICmpInst::Predicate Pred; Value *CmpLHS; ConstantInt *CmpRHS; - if (match(Src, m_ICmp(Pred, m_Value(CmpLHS), m_ConstantInt(CmpRHS)))) { - // sext (x x>>s31 true if signbit set. - // sext (x >s -1) to i32 --> (x>>s31)^-1 true if signbit clear. - if ((Pred == ICmpInst::ICMP_SLT && CmpRHS->isZero()) || - (Pred == ICmpInst::ICMP_SGT && CmpRHS->isAllOnesValue())) { - Value *Sh = ConstantInt::get(CmpLHS->getType(), - CmpLHS->getType()->getScalarSizeInBits()-1); - Value *In = Builder->CreateAShr(CmpLHS, Sh, CmpLHS->getName()+".lobit"); - if (In->getType() != CI.getType()) - In = Builder->CreateIntCast(In, CI.getType(), true/*SExt*/, "tmp"); - - if (Pred == ICmpInst::ICMP_SGT) - In = Builder->CreateNot(In, In->getName()+".not"); - return ReplaceInstUsesWith(CI, In); - } - } - } - // vector (x ashr x, 31 -> all ones if signed. - if (const VectorType *VTy = dyn_cast(DestTy)) { - ICmpInst::Predicate Pred; Value *CmpLHS; - if (match(Src, m_ICmp(Pred, m_Value(CmpLHS), m_Zero()))) { - if (Pred == ICmpInst::ICMP_SLT && CmpLHS->getType() == DestTy) { - const Type *EltTy = VTy->getElementType(); - - // splat the shift constant to a constant vector. - Constant *VSh = ConstantInt::get(VTy, EltTy->getScalarSizeInBits()-1); - Value *In = Builder->CreateAShr(CmpLHS, VSh,CmpLHS->getName()+".lobit"); - return ReplaceInstUsesWith(CI, In); - } - } - } + if (ICmpInst *ICI = dyn_cast(Src)) + return transformSExtICmp(ICI, CI); // If the input is a shl/ashr pair of a same constant, then this is a sign // extension from a smaller value. If we could trust arbitrary bitwidth From benny.kra at googlemail.com Fri Apr 1 15:09:10 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 01 Apr 2011 20:09:10 -0000 Subject: [llvm-commits] [llvm] r128732 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCasts.cpp test/Transforms/InstCombine/sext.ll Message-ID: <20110401200910.9ED192A6C12C@llvm.org> Author: d0k Date: Fri Apr 1 15:09:10 2011 New Revision: 128732 URL: http://llvm.org/viewvc/llvm-project?rev=128732&view=rev Log: InstCombine: Turn icmp + sext into bitwise/integer ops when the input has only one unknown bit. int test1(unsigned x) { return (x&8) ? 0 : -1; } int test3(unsigned x) { return (x&8) ? -1 : 0; } before (x86_64): _test1: andl $8, %edi cmpl $1, %edi sbbl %eax, %eax ret _test3: andl $8, %edi cmpl $1, %edi sbbl %eax, %eax notl %eax ret after: _test1: shrl $3, %edi andl $1, %edi leal -1(%rdi), %eax ret _test3: shll $28, %edi movl %edi, %eax sarl $31, %eax ret Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/trunk/test/Transforms/InstCombine/sext.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=128732&r1=128731&r2=128732&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Fri Apr 1 15:09:10 2011 @@ -882,6 +882,10 @@ Value *Op0 = ICI->getOperand(0), *Op1 = ICI->getOperand(1); ICmpInst::Predicate Pred = ICI->getPredicate(); + // Transforming icmps with more than one use is not profitable. + if (!ICI->hasOneUse()) + return 0; + if (ConstantInt *Op1C = dyn_cast(Op1)) { // (x ashr x, 31 -> all ones if signed // (x >s -1) ? -1 : 0 -> ashr x, 31 -> all ones if not signed @@ -898,6 +902,52 @@ In = Builder->CreateNot(In, In->getName()+".not"); return ReplaceInstUsesWith(CI, In); } + + // If we know that only one bit of the LHS of the icmp can be set and we + // have an equality comparison with zero or a power of 2, we can transform + // the icmp and sext into bitwise/integer operations. + if (ICI->isEquality() && (Op1C->isZero() || Op1C->getValue().isPowerOf2())){ + unsigned BitWidth = Op1C->getType()->getBitWidth(); + APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); + APInt TypeMask(APInt::getAllOnesValue(BitWidth)); + ComputeMaskedBits(Op0, TypeMask, KnownZero, KnownOne); + + if ((~KnownZero).isPowerOf2()) { + Value *In = ICI->getOperand(0); + + if (!Op1C->isZero() == (Pred == ICmpInst::ICMP_NE)) { + // sext ((x & 2^n) == 0) -> (x >> n) - 1 + // sext ((x & 2^n) != 2^n) -> (x >> n) - 1 + unsigned ShiftAmt = KnownZeroMask.countTrailingZeros(); + // Perform a right shift to place the desired bit in the LSB. + if (ShiftAmt) + In = Builder->CreateLShr(In, + ConstantInt::get(In->getType(), ShiftAmt)); + + // At this point "In" is either 1 or 0. Subtract 1 to turn + // {1, 0} -> {0, -1}. + In = Builder->CreateAdd(In, + ConstantInt::getAllOnesValue(In->getType()), + "sext"); + } else { + // sext ((x & 2^n) != 0) -> (x << bitwidth-n) a>> bitwidth-1 + // sext ((x & 2^n) != 2^n) -> (x << bitwidth-n) a>> bitwidth-1 + unsigned ShiftAmt = KnownZeroMask.countLeadingZeros(); + // Perform a left shift to place the desired bit in the MSB. + if (ShiftAmt) + In = Builder->CreateShl(In, + ConstantInt::get(In->getType(), ShiftAmt)); + + // Distribute the bit over the whole bit width. + In = Builder->CreateAShr(In, ConstantInt::get(In->getType(), + BitWidth - 1), "sext"); + } + + if (CI.getType() == In->getType()) + return ReplaceInstUsesWith(CI, In); + return CastInst::CreateIntegerCast(In, CI.getType(), true/*SExt*/); + } + } } // vector (x ashr x, 31 -> all ones if signed. Modified: llvm/trunk/test/Transforms/InstCombine/sext.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sext.ll?rev=128732&r1=128731&r2=128732&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/sext.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/sext.ll Fri Apr 1 15:09:10 2011 @@ -136,3 +136,51 @@ ; CHECK: sext ; CHECK: ret } + +define i32 @test13(i32 %x) nounwind { + %and = and i32 %x, 8 + %cmp = icmp eq i32 %and, 0 + %ext = sext i1 %cmp to i32 + ret i32 %ext +; CHECK: @test13 +; CHECK-NEXT: %and = lshr i32 %x, 3 +; CHECK-NEXT: %1 = and i32 %and, 1 +; CHECK-NEXT: %sext = add i32 %1, -1 +; CHECK-NEXT: ret i32 %sext +} + +define i32 @test14(i16 %x) nounwind { + %and = and i16 %x, 16 + %cmp = icmp ne i16 %and, 16 + %ext = sext i1 %cmp to i32 + ret i32 %ext +; CHECK: @test14 +; CHECK-NEXT: %and = lshr i16 %x, 4 +; CHECK-NEXT: %1 = and i16 %and, 1 +; CHECK-NEXT: %sext = add i16 %1, -1 +; CHECK-NEXT: %ext = sext i16 %sext to i32 +; CHECK-NEXT: ret i32 %ext +} + +define i32 @test15(i32 %x) nounwind { + %and = and i32 %x, 16 + %cmp = icmp ne i32 %and, 0 + %ext = sext i1 %cmp to i32 + ret i32 %ext +; CHECK: @test15 +; CHECK-NEXT: %1 = shl i32 %x, 27 +; CHECK-NEXT: %sext = ashr i32 %1, 31 +; CHECK-NEXT: ret i32 %sext +} + +define i32 @test16(i16 %x) nounwind { + %and = and i16 %x, 8 + %cmp = icmp eq i16 %and, 8 + %ext = sext i1 %cmp to i32 + ret i32 %ext +; CHECK: @test16 +; CHECK-NEXT: %1 = shl i16 %x, 12 +; CHECK-NEXT: %sext = ashr i16 %1, 15 +; CHECK-NEXT: %ext = sext i16 %sext to i32 +; CHECK-NEXT: ret i32 %ext +} From benny.kra at googlemail.com Fri Apr 1 15:15:16 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 01 Apr 2011 20:15:16 -0000 Subject: [llvm-commits] [llvm] r128733 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Message-ID: <20110401201516.80DE32A6C12C@llvm.org> Author: d0k Date: Fri Apr 1 15:15:16 2011 New Revision: 128733 URL: http://llvm.org/viewvc/llvm-project?rev=128733&view=rev Log: Fix build. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=128733&r1=128732&r2=128733&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Fri Apr 1 15:15:16 2011 @@ -912,7 +912,8 @@ APInt TypeMask(APInt::getAllOnesValue(BitWidth)); ComputeMaskedBits(Op0, TypeMask, KnownZero, KnownOne); - if ((~KnownZero).isPowerOf2()) { + APInt KnownZeroMask(~KnownZero); + if (KnownZeroMask.isPowerOf2()) { Value *In = ICI->getOperand(0); if (!Op1C->isZero() == (Pred == ICmpInst::ICMP_NE)) { From johnny.chen at apple.com Fri Apr 1 15:21:38 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 01 Apr 2011 20:21:38 -0000 Subject: [llvm-commits] [llvm] r128734 - in /llvm/trunk: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp test/MC/Disassembler/ARM/arm-tests.txt test/MC/Disassembler/ARM/invalid-LDRT-arm.txt Message-ID: <20110401202138.3DF8F2A6C12C@llvm.org> Author: johnny Date: Fri Apr 1 15:21:38 2011 New Revision: 128734 URL: http://llvm.org/viewvc/llvm-project?rev=128734&view=rev Log: Fix a LDRT/LDRBT decoding bug where for Encoding A2, if Inst{4} != 0, we should reject the instruction as invalid. Added: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128734&r1=128733&r2=128734&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Fri Apr 1 15:21:38 2011 @@ -1106,6 +1106,14 @@ MI.addOperand(MCOperand::CreateImm(Offset)); OpIdx += 1; } else { + // The opcode ARM::LDRT actually corresponds to both Encoding A1 and A2 of + // A8.6.86 LDRT. So if Inst{4} != 0 while Inst{25} (getIBit(insn)) == 1, + // we should reject this insn as invalid. + // + // Ditto for LDRBT. + if ((Opcode == ARM::LDRT || Opcode == ARM::LDRBT) && (slice(insn,4,4) == 1)) + return false; + // Disassemble the offset reg (Rm), shift type, and immediate shift length. MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, decodeRm(insn)))); Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=128734&r1=128733&r2=128734&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Fri Apr 1 15:21:38 2011 @@ -45,6 +45,9 @@ # CHECK: ldr r0, [r2], #15 0x0f 0x00 0x92 0xe4 +# CHECK: ldr r5, [r7, -r10, lsl #2] +0x0a 0x51 0x17 0xe7 + # CHECK: ldrh r0, [r2], #0 0xb0 0x00 0xd2 0xe0 Added: llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt?rev=128734&view=auto ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt (added) +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt Fri Apr 1 15:21:38 2011 @@ -0,0 +1,12 @@ +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} + +# Opcode=0 Name=PHI Format=(42) +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# ------------------------------------------------------------------------------------------------- +# | 1: 1: 1: 0| 0: 1: 1: 0| 0: 0: 1: 1| 0: 1: 1: 1| 0: 1: 0: 1| 0: 0: 0: 1| 0: 0: 0: 1| 0: 0: 0: 0| +# ------------------------------------------------------------------------------------------------- +# +# The bytes have Inst{4} = 1, so it's not an LDRT Encoding A2 instruction. +0x10 0x51 0x37 0xe6 + + From daniel at zuster.org Fri Apr 1 15:23:52 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Fri, 01 Apr 2011 20:23:52 -0000 Subject: [llvm-commits] [llvm] r128735 - /llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Message-ID: <20110401202352.862512A6C12C@llvm.org> Author: ddunbar Date: Fri Apr 1 15:23:52 2011 New Revision: 128735 URL: http://llvm.org/viewvc/llvm-project?rev=128735&view=rev Log: tlbgen/MC: StringRef's to temporary objects considered harmful. Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=128735&r1=128734&r2=128735&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Fri Apr 1 15:23:52 2011 @@ -1483,10 +1483,10 @@ MatchableInfo &II = **it; // Check if we have a custom match function. - StringRef AsmMatchConverter = II.getResultInst()->TheDef->getValueAsString( - "AsmMatchConverter"); + std::string AsmMatchConverter = + II.getResultInst()->TheDef->getValueAsString("AsmMatchConverter"); if (!AsmMatchConverter.empty()) { - std::string Signature = "ConvertCustom_" + AsmMatchConverter.str(); + std::string Signature = "ConvertCustom_" + AsmMatchConverter; II.ConversionFnKind = Signature; // Check if we have already generated this signature. From grosbach at apple.com Fri Apr 1 15:26:57 2011 From: grosbach at apple.com (Jim Grosbach) Date: Fri, 01 Apr 2011 20:26:57 -0000 Subject: [llvm-commits] [llvm] r128736 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td test/CodeGen/ARM/fpcmp-opt.ll test/CodeGen/ARM/ldrd.ll Message-ID: <20110401202657.C6E3B2A6C12C@llvm.org> Author: grosbach Date: Fri Apr 1 15:26:57 2011 New Revision: 128736 URL: http://llvm.org/viewvc/llvm-project?rev=128736&view=rev Log: LDRD/STRD instructions should print both Rt and Rt2 in the asm string. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/test/CodeGen/ARM/fpcmp-opt.ll llvm/trunk/test/CodeGen/ARM/ldrd.ll Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128736&r1=128735&r2=128736&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri Apr 1 15:26:57 2011 @@ -1649,15 +1649,11 @@ IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr", [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>; -let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1, - isCodeGenOnly = 1 in { // $dst2 doesn't exist in asmstring? -// FIXME: $dst2 isn't in the asm string as it's implied by $Rd (dst2 = Rd+1) -// how to represent that such that tblgen is happy and we don't -// mark this codegen only? +let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { // Load doubleword def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm, - IIC_iLoad_d_r, "ldrd", "\t$Rd, $addr", + IIC_iLoad_d_r, "ldrd", "\t$Rd, $dst2, $addr", []>, Requires<[IsARM, HasV5TE]>; } @@ -1792,11 +1788,10 @@ [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>; // Store doubleword -let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1, - isCodeGenOnly = 1 in // $src2 doesn't exist in asm string -def STRD : AI3str<0b1111, (outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr), +let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in +def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$src2, addrmode3:$addr), StMiscFrm, IIC_iStore_d_r, - "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>; + "strd", "\t$Rt, $src2, $addr", []>, Requires<[IsARM, HasV5TE]>; // Indexed stores def STR_PRE : AI2stridx<0, 1, (outs GPR:$Rn_wb), Modified: llvm/trunk/test/CodeGen/ARM/fpcmp-opt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fpcmp-opt.ll?rev=128736&r1=128735&r2=128736&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fpcmp-opt.ll (original) +++ llvm/trunk/test/CodeGen/ARM/fpcmp-opt.ll Fri Apr 1 15:26:57 2011 @@ -37,7 +37,7 @@ entry: ; FINITE: t2: ; FINITE-NOT: vldr -; FINITE: ldrd r0, [r0] +; FINITE: ldrd r0, r1, [r0] ; FINITE-NOT: b LBB ; FINITE: cmp r0, #0 ; FINITE: cmpeq r1, #0 Modified: llvm/trunk/test/CodeGen/ARM/ldrd.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ldrd.ll?rev=128736&r1=128735&r2=128736&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/ldrd.ll (original) +++ llvm/trunk/test/CodeGen/ARM/ldrd.ll Fri Apr 1 15:26:57 2011 @@ -9,7 +9,7 @@ define i64 @t(i64 %a) nounwind readonly { entry: -;V6: ldrd r2, [r2] +;V6: ldrd r2, r3, [r2] ;V5: ldr r{{[0-9]+}}, [r2] ;V5: ldr r{{[0-9]+}}, [r2, #4] From resistor at mac.com Fri Apr 1 16:07:39 2011 From: resistor at mac.com (Owen Anderson) Date: Fri, 01 Apr 2011 21:07:39 -0000 Subject: [llvm-commits] [llvm] r128739 - /llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Message-ID: <20110401210739.D57D92A6C12C@llvm.org> Author: resistor Date: Fri Apr 1 16:07:39 2011 New Revision: 128739 URL: http://llvm.org/viewvc/llvm-project?rev=128739&view=rev Log: When the architecture is explicitly armv6 or thumbv6, we need to mark the object file appropriately. Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=128739&r1=128738&r2=128739&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Fri Apr 1 16:07:39 2011 @@ -416,21 +416,22 @@ // FIXME: This should be in a separate file. class DarwinARMAsmBackend : public ARMAsmBackend { public: - DarwinARMAsmBackend(const Target &T) : ARMAsmBackend(T) { } - - void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, - uint64_t Value) const; + const object::mach::CPUSubtypeARM Subtype; + DarwinARMAsmBackend(const Target &T, object::mach::CPUSubtypeARM st) + : ARMAsmBackend(T), Subtype(st) { } MCObjectWriter *createObjectWriter(raw_ostream &OS) const { - // FIXME: Subtarget info should be derived. Force v7 for now. return createMachObjectWriter(new ARMMachObjectWriter( /*Is64Bit=*/false, object::mach::CTM_ARM, - object::mach::CSARM_V7), + Subtype), OS, /*IsLittleEndian=*/true); } + void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, + uint64_t Value) const; + virtual bool doesSectionRequireSymbols(const MCSection &Section) const { return false; } @@ -499,9 +500,14 @@ TargetAsmBackend *llvm::createARMAsmBackend(const Target &T, const std::string &TT) { - switch (Triple(TT).getOS()) { - case Triple::Darwin: - return new DarwinARMAsmBackend(T); + Triple TheTriple(TT); + switch (TheTriple.getOS()) { + case Triple::Darwin: { + if (TheTriple.getArchName() == "armv6" || + TheTriple.getArchName() == "thumbv6") + return new DarwinARMAsmBackend(T, object::mach::CSARM_V6); + return new DarwinARMAsmBackend(T, object::mach::CSARM_V7); + } case Triple::MinGW32: case Triple::Cygwin: case Triple::Win32: From bruno.cardoso at gmail.com Fri Apr 1 16:30:08 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Fri, 1 Apr 2011 18:30:08 -0300 Subject: [llvm-commits] MIPS patch In-Reply-To: References: Message-ID: Nice! Please commit! On Fri, Apr 1, 2011 at 4:44 PM, Akira Hatanaka wrote: > This patch simplifies logic for printing target flags. > > Index: lib/Target/Mips/MipsAsmPrinter.cpp > =================================================================== > --- lib/Target/Mips/MipsAsmPrinter.cpp? (revision 128724) > +++ lib/Target/Mips/MipsAsmPrinter.cpp? (working copy) > @@ -298,23 +298,10 @@ > ?? switch(MO.getTargetFlags()) { > ?? case MipsII::MO_GPREL:??? O << "%gp_rel("; break; > ?? case MipsII::MO_GOT_CALL: O << "%call16("; break; > -? case MipsII::MO_GOT: { > -??? const MachineOperand &LastMO = MI->getOperand(opNum-1); > -??? bool LastMOIsGP = LastMO.getType() == MachineOperand::MO_Register > -????????????????????? && LastMO.getReg() == Mips::GP; > -??? if (MI->getOpcode() == Mips::LW || LastMOIsGP) > -????? O << "%got("; > -??? else > -????? O << "%lo("; > -??? break; > +? case MipsII::MO_GOT:????? O << "%got(";??? break; > +? case MipsII::MO_ABS_HI:?? O << "%hi(";???? break; > +? case MipsII::MO_ABS_LO:?? O << "%lo(";???? break; > ?? } > -? case MipsII::MO_ABS_HILO: > -??? if (MI->getOpcode() == Mips::LUi) > -????? O << "%hi("; > -??? else > -????? O << "%lo("; > -??? break; > -? } > > ?? switch (MO.getType()) { > ???? case MachineOperand::MO_Register: > Index: lib/Target/Mips/MipsInstrInfo.h > =================================================================== > --- lib/Target/Mips/MipsInstrInfo.h (revision 128724) > +++ lib/Target/Mips/MipsInstrInfo.h (working copy) > @@ -143,10 +143,10 @@ > ???? /// for the relocatable object file being produced. > ???? MO_GPREL, > > -??? /// MO_ABS_HILO - Represents the hi or low part of an absolute symbol > +??? /// MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol > ???? /// address. > -??? MO_ABS_HILO > - > +??? MO_ABS_HI, > +??? MO_ABS_LO > ?? }; > ?} > > Index: lib/Target/Mips/MipsISelLowering.cpp > =================================================================== > --- lib/Target/Mips/MipsISelLowering.cpp? (revision 128724) > +++ lib/Target/Mips/MipsISelLowering.cpp? (working copy) > @@ -769,12 +769,13 @@ > ?????? return DAG.getNode(ISD::ADD, dl, MVT::i32, GOT, GPRelNode); > ???? } > ???? // %hi/%lo relocation > -??? SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, > -??????????????????????????????????????????? MipsII::MO_ABS_HILO); > -??? SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, VTs, &GA, 1); > -??? SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GA); > +??? SDValue GAHi = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, > +????????????????????????????????????????????? MipsII::MO_ABS_HI); > +??? SDValue GALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, > +????????????????????????????????????????????? MipsII::MO_ABS_LO); > +??? SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, VTs, &GAHi, 1); > +??? SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GALo); > ???? return DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); > - > ?? } else { > ???? SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, > ???????????????????????????????????????????? MipsII::MO_GOT); > @@ -785,7 +786,9 @@ > ???? // a load from got/GP is necessary for PIC to work. > ???? if (!GV->hasLocalLinkage() || isa(GV)) > ?????? return ResNode; > -??? SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GA); > +??? SDValue GALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, > +????????????????????????????????????????????? MipsII::MO_ABS_LO); > +??? SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GALo); > ???? return DAG.getNode(ISD::ADD, dl, MVT::i32, ResNode, Lo); > ?? } > > @@ -806,7 +809,7 @@ > ???? SDValue BAGOTOffset = DAG.getBlockAddress(BA, MVT::i32, true, > ?????????????????????????????????????????????? MipsII::MO_GOT); > ???? SDValue BALOOffset = DAG.getBlockAddress(BA, MVT::i32, true, > -???????????????????????????????????????????? MipsII::MO_ABS_HILO); > +???????????????????????????????????????????? MipsII::MO_ABS_LO); > ???? SDValue Load = DAG.getLoad(MVT::i32, dl, > ??????????????????????????????? DAG.getEntryNode(), BAGOTOffset, > ??????????????????????????????? MachinePointerInfo(), false, false, 0); > @@ -830,7 +833,7 @@ > ?? // FIXME there isn't actually debug info here > ?? DebugLoc dl = Op.getDebugLoc(); > ?? bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_; > -? unsigned char OpFlag = IsPIC ? MipsII::MO_GOT : MipsII::MO_ABS_HILO; > +? unsigned char OpFlag = IsPIC ? MipsII::MO_GOT : MipsII::MO_ABS_HI; > > ?? EVT PtrVT = Op.getValueType(); > ?? JumpTableSDNode *JT? = cast(Op); > @@ -845,7 +848,8 @@ > ????????????????????????? MachinePointerInfo(), > ????????????????????????? false, false, 0); > > -? SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, JTI); > +? SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, > MipsII::MO_ABS_LO); > +? SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, JTILo); > ?? ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); > > ?? return ResNode; > @@ -871,18 +875,22 @@ > ?? //? ResNode = DAG.getNode(ISD::ADD, MVT::i32, GOT, GPRelNode); > > ?? if (getTargetMachine().getRelocationModel() != Reloc::PIC_) { > -??? SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), > -????????????????????????????????????? N->getOffset(), MipsII::MO_ABS_HILO); > -??? SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, MVT::i32, CP); > -??? SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CP); > +??? SDValue CPHi = DAG.getTargetConstantPool(C, MVT::i32, > N->getAlignment(), > +???????????????????????????????????????????? N->getOffset(), > MipsII::MO_ABS_HI); > +??? SDValue CPLo = DAG.getTargetConstantPool(C, MVT::i32, > N->getAlignment(), > +???????????????????????????????????????????? N->getOffset(), > MipsII::MO_ABS_LO); > +??? SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, MVT::i32, CPHi); > +??? SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CPLo); > ???? ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); > ?? } else { > ???? SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), > -????????????????????????????????????? N->getOffset(), MipsII::MO_GOT); > +?????????????????????????????????????????? N->getOffset(), MipsII::MO_GOT); > ???? SDValue Load = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), > ??????????????????????????????? CP, MachinePointerInfo::getConstantPool(), > ??????????????????????????????? false, false, 0); > -??? SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CP); > +??? SDValue CPLo = DAG.getTargetConstantPool(C, MVT::i32, > N->getAlignment(), > +???????????????????????????????????????????? N->getOffset(), > MipsII::MO_ABS_LO); > +??? SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CPLo); > ???? ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, Load, Lo); > ?? } > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -- Bruno Cardoso Lopes http://www.brunocardoso.cc From ofv at wanadoo.es Fri Apr 1 16:39:38 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Fri, 01 Apr 2011 21:39:38 -0000 Subject: [llvm-commits] [llvm] r128740 - /llvm/trunk/tools/llvm-config/CMakeLists.txt Message-ID: <20110401213938.394B82A6C12C@llvm.org> Author: ofv Date: Fri Apr 1 16:39:38 2011 New Revision: 128740 URL: http://llvm.org/viewvc/llvm-project?rev=128740&view=rev Log: CMake: remove debug code from previous commit. Modified: llvm/trunk/tools/llvm-config/CMakeLists.txt Modified: llvm/trunk/tools/llvm-config/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-config/CMakeLists.txt?rev=128740&r1=128739&r2=128740&view=diff ============================================================================== --- llvm/trunk/tools/llvm-config/CMakeLists.txt (original) +++ llvm/trunk/tools/llvm-config/CMakeLists.txt Fri Apr 1 16:39:38 2011 @@ -92,10 +92,6 @@ COMMENT "Checking for cyclic dependencies between LLVM libraries.") set(C_FLGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") -message(STATUS "C_FLGS: ${C_FLGS}") -message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") -message(STATUS "LLVM_DEFINITIONS: ${LLVM_DEFINITIONS}") -message(STATUS "other: ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}") set(CXX_FLGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") set(CPP_FLGS "${CMAKE_CPP_FLAGS} ${CMAKE_CPP_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") From ahatanak at gmail.com Fri Apr 1 16:41:06 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Fri, 01 Apr 2011 21:41:06 -0000 Subject: [llvm-commits] [llvm] r128741 - in /llvm/trunk/lib/Target/Mips: MipsAsmPrinter.cpp MipsISelLowering.cpp MipsInstrInfo.h Message-ID: <20110401214106.336E42A6C12C@llvm.org> Author: ahatanak Date: Fri Apr 1 16:41:06 2011 New Revision: 128741 URL: http://llvm.org/viewvc/llvm-project?rev=128741&view=rev Log: Simplifies logic for printing target flags. Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp llvm/trunk/lib/Target/Mips/MipsInstrInfo.h Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=128741&r1=128740&r2=128741&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Fri Apr 1 16:41:06 2011 @@ -298,22 +298,9 @@ switch(MO.getTargetFlags()) { case MipsII::MO_GPREL: O << "%gp_rel("; break; case MipsII::MO_GOT_CALL: O << "%call16("; break; - case MipsII::MO_GOT: { - const MachineOperand &LastMO = MI->getOperand(opNum-1); - bool LastMOIsGP = LastMO.getType() == MachineOperand::MO_Register - && LastMO.getReg() == Mips::GP; - if (MI->getOpcode() == Mips::LW || LastMOIsGP) - O << "%got("; - else - O << "%lo("; - break; - } - case MipsII::MO_ABS_HILO: - if (MI->getOpcode() == Mips::LUi) - O << "%hi("; - else - O << "%lo("; - break; + case MipsII::MO_GOT: O << "%got("; break; + case MipsII::MO_ABS_HI: O << "%hi("; break; + case MipsII::MO_ABS_LO: O << "%lo("; break; } switch (MO.getType()) { Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=128741&r1=128740&r2=128741&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Fri Apr 1 16:41:06 2011 @@ -769,12 +769,13 @@ return DAG.getNode(ISD::ADD, dl, MVT::i32, GOT, GPRelNode); } // %hi/%lo relocation - SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, - MipsII::MO_ABS_HILO); - SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, VTs, &GA, 1); - SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GA); + SDValue GAHi = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_ABS_HI); + SDValue GALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_ABS_LO); + SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, VTs, &GAHi, 1); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GALo); return DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); - } else { SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, MipsII::MO_GOT); @@ -785,7 +786,9 @@ // a load from got/GP is necessary for PIC to work. if (!GV->hasLocalLinkage() || isa(GV)) return ResNode; - SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GA); + SDValue GALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_ABS_LO); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GALo); return DAG.getNode(ISD::ADD, dl, MVT::i32, ResNode, Lo); } @@ -806,7 +809,7 @@ SDValue BAGOTOffset = DAG.getBlockAddress(BA, MVT::i32, true, MipsII::MO_GOT); SDValue BALOOffset = DAG.getBlockAddress(BA, MVT::i32, true, - MipsII::MO_ABS_HILO); + MipsII::MO_ABS_LO); SDValue Load = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), BAGOTOffset, MachinePointerInfo(), false, false, 0); @@ -830,7 +833,7 @@ // FIXME there isn't actually debug info here DebugLoc dl = Op.getDebugLoc(); bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_; - unsigned char OpFlag = IsPIC ? MipsII::MO_GOT : MipsII::MO_ABS_HILO; + unsigned char OpFlag = IsPIC ? MipsII::MO_GOT : MipsII::MO_ABS_HI; EVT PtrVT = Op.getValueType(); JumpTableSDNode *JT = cast(Op); @@ -845,7 +848,8 @@ MachinePointerInfo(), false, false, 0); - SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, JTI); + SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MipsII::MO_ABS_LO); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, JTILo); ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); return ResNode; @@ -871,18 +875,22 @@ // ResNode = DAG.getNode(ISD::ADD, MVT::i32, GOT, GPRelNode); if (getTargetMachine().getRelocationModel() != Reloc::PIC_) { - SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), - N->getOffset(), MipsII::MO_ABS_HILO); - SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, MVT::i32, CP); - SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CP); + SDValue CPHi = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), + N->getOffset(), MipsII::MO_ABS_HI); + SDValue CPLo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), + N->getOffset(), MipsII::MO_ABS_LO); + SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, MVT::i32, CPHi); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CPLo); ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); } else { SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), - N->getOffset(), MipsII::MO_GOT); + N->getOffset(), MipsII::MO_GOT); SDValue Load = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), CP, MachinePointerInfo::getConstantPool(), false, false, 0); - SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CP); + SDValue CPLo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), + N->getOffset(), MipsII::MO_ABS_LO); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CPLo); ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, Load, Lo); } Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.h?rev=128741&r1=128740&r2=128741&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.h (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.h Fri Apr 1 16:41:06 2011 @@ -143,10 +143,10 @@ /// for the relocatable object file being produced. MO_GPREL, - /// MO_ABS_HILO - Represents the hi or low part of an absolute symbol + /// MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol /// address. - MO_ABS_HILO - + MO_ABS_HI, + MO_ABS_LO }; } From fvbommel at gmail.com Fri Apr 1 16:46:41 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Fri, 1 Apr 2011 23:46:41 +0200 Subject: [llvm-commits] [llvm] r128732 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCasts.cpp test/Transforms/InstCombine/sext.ll In-Reply-To: <20110401200910.9ED192A6C12C@llvm.org> References: <20110401200910.9ED192A6C12C@llvm.org> Message-ID: On Fri, Apr 1, 2011 at 10:09 PM, Benjamin Kramer wrote: > + ?// Transforming icmps with more than one use is not profitable. > + ?if (!ICI->hasOneUse()) > + ? ?return 0; Did you test this? Intuitively, independent icmp + ashr could be more efficient than a (sext (icmp)) with extra uses for the icmp. Then again, they may not be since they introduce an extra use of 'x'. Just a thought. > + > ? if (ConstantInt *Op1C = dyn_cast(Op1)) { > ? ? // (x ashr x, 31 ? -> all ones if signed > ? ? // (x >s -1) ? -1 : 0 -> ashr x, 31 ?-> all ones if not signed > @@ -898,6 +902,52 @@ > ? ? ? ? In = Builder->CreateNot(In, In->getName()+".not"); > ? ? ? return ReplaceInstUsesWith(CI, In); > ? ? } > + > + ? ?// If we know that only one bit of the LHS of the icmp can be set and we > + ? ?// have an equality comparison with zero or a power of 2, we can transform > + ? ?// the icmp and sext into bitwise/integer operations. > + ? ?if (ICI->isEquality() && (Op1C->isZero() || Op1C->getValue().isPowerOf2())){ > + ? ? ?unsigned BitWidth = Op1C->getType()->getBitWidth(); > + ? ? ?APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); > + ? ? ?APInt TypeMask(APInt::getAllOnesValue(BitWidth)); > + ? ? ?ComputeMaskedBits(Op0, TypeMask, KnownZero, KnownOne); > + > + ? ? ?if ((~KnownZero).isPowerOf2()) { > + ? ? ? ?Value *In = ICI->getOperand(0); > + > + ? ? ? ?if (!Op1C->isZero() == (Pred == ICmpInst::ICMP_NE)) { > + ? ? ? ? ?// sext ((x & 2^n) == 0) ? -> (x >> n) - 1 > + ? ? ? ? ?// sext ((x & 2^n) != 2^n) -> (x >> n) - 1 Did I miss where you checked whether the RHS of the and is equal to the RHS of the icmp for the second case? Or does this miscompile e.g. sext((x & 8) != 16)? (You can optimize that to -1, of course) > + ? ? ? ? ?unsigned ShiftAmt = KnownZeroMask.countTrailingZeros(); > + ? ? ? ? ?// Perform a right shift to place the desired bit in the LSB. > + ? ? ? ? ?if (ShiftAmt) > + ? ? ? ? ? ?In = Builder->CreateLShr(In, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ConstantInt::get(In->getType(), ShiftAmt)); > + > + ? ? ? ? ?// At this point "In" is either 1 or 0. Subtract 1 to turn > + ? ? ? ? ?// {1, 0} -> {0, -1}. > + ? ? ? ? ?In = Builder->CreateAdd(In, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ConstantInt::getAllOnesValue(In->getType()), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"sext"); > + ? ? ? ?} else { > + ? ? ? ? ?// sext ((x & 2^n) != 0) ? -> (x << bitwidth-n) a>> bitwidth-1 > + ? ? ? ? ?// sext ((x & 2^n) != 2^n) -> (x << bitwidth-n) a>> bitwidth-1 I think you meant '==' in the second case. And this seems to have the same issue as above, miscompiling 'sext((x & 8) == 16)' (which is 0). > + ? ? ? ? ?unsigned ShiftAmt = KnownZeroMask.countLeadingZeros(); > + ? ? ? ? ?// Perform a left shift to place the desired bit in the MSB. > + ? ? ? ? ?if (ShiftAmt) > + ? ? ? ? ? ?In = Builder->CreateShl(In, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ConstantInt::get(In->getType(), ShiftAmt)); > + > + ? ? ? ? ?// Distribute the bit over the whole bit width. > + ? ? ? ? ?In = Builder->CreateAShr(In, ConstantInt::get(In->getType(), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?BitWidth - 1), "sext"); > + ? ? ? ?} > + > + ? ? ? ?if (CI.getType() == In->getType()) > + ? ? ? ? ?return ReplaceInstUsesWith(CI, In); > + ? ? ? ?return CastInst::CreateIntegerCast(In, CI.getType(), true/*SExt*/); > + ? ? ?} > + ? ?} > ? } From fvbommel at gmail.com Fri Apr 1 16:51:37 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Fri, 1 Apr 2011 23:51:37 +0200 Subject: [llvm-commits] [llvm] r128731 - in /llvm/trunk/lib/Transforms/InstCombine: InstCombine.h InstCombineCasts.cpp In-Reply-To: <20110401200903.7A3CC2A6C12C@llvm.org> References: <20110401200903.7A3CC2A6C12C@llvm.org> Message-ID: I know you only moved this code, but I still have some comments on it: On Fri, Apr 1, 2011 at 10:09 PM, Benjamin Kramer wrote: > + ? ?// (x ashr x, 31 ? -> all ones if signed > + ? ?// (x >s -1) ? -1 : 0 -> ashr x, 31 ?-> all ones if not signed The second comment line is incorrect. The ashr should be 'not (ashr x, 31)'. > + ? ?if ((Pred == ICmpInst::ICMP_SLT && Op1C->isZero()) || > + ? ? ? ?(Pred == ICmpInst::ICMP_SGT && Op1C->isAllOnesValue())) { It seems to me that this can also be done for (x u signed_max). Unless those are canonicalized to signed comparisons elsewhere? From ahatanak at gmail.com Fri Apr 1 16:56:02 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Fri, 01 Apr 2011 21:56:02 -0000 Subject: [llvm-commits] [llvm] r128742 - /llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Message-ID: <20110401215602.CA6142A6C12C@llvm.org> Author: ahatanak Date: Fri Apr 1 16:56:02 2011 New Revision: 128742 URL: http://llvm.org/viewvc/llvm-project?rev=128742&view=rev Log: Remove redundant code. There are assignments to variables Base and Offset right after the code that is removed. Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=128742&r1=128741&r2=128742&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Fri Apr 1 16:56:02 2011 @@ -171,11 +171,6 @@ } } - if (isa(Addr.getOperand(1))) { - Base = Addr.getOperand(0); - Offset = Addr.getOperand(1); - } - Base = Addr; Offset = CurDAG->getTargetConstant(0, MVT::i32); return true; From evan.cheng at apple.com Fri Apr 1 17:09:28 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 01 Apr 2011 22:09:28 -0000 Subject: [llvm-commits] [llvm] r128743 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Message-ID: <20110401220928.522942A6C12C@llvm.org> Author: evancheng Date: Fri Apr 1 17:09:28 2011 New Revision: 128743 URL: http://llvm.org/viewvc/llvm-project?rev=128743&view=rev Log: Avoid de-referencing pass beginning of a basic block. No small test case possible. rdar://9216009 Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=128743&r1=128742&r2=128743&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Fri Apr 1 17:09:28 2011 @@ -1650,24 +1650,27 @@ unsigned BrOffset = GetOffsetOf(Br.MI) + 4 - 2; unsigned DestOffset = BBOffsets[DestBB->getNumber()]; if (BrOffset < DestOffset && (DestOffset - BrOffset) <= 126) { - MachineBasicBlock::iterator CmpMI = Br.MI; --CmpMI; - if (CmpMI->getOpcode() == ARM::tCMPi8) { - unsigned Reg = CmpMI->getOperand(0).getReg(); - Pred = llvm::getInstrPredicate(CmpMI, PredReg); - if (Pred == ARMCC::AL && - CmpMI->getOperand(1).getImm() == 0 && - isARMLowRegister(Reg)) { - MachineBasicBlock *MBB = Br.MI->getParent(); - MachineInstr *NewBR = - BuildMI(*MBB, CmpMI, Br.MI->getDebugLoc(), TII->get(NewOpc)) - .addReg(Reg).addMBB(DestBB, Br.MI->getOperand(0).getTargetFlags()); - CmpMI->eraseFromParent(); - Br.MI->eraseFromParent(); - Br.MI = NewBR; - BBSizes[MBB->getNumber()] -= 2; - AdjustBBOffsetsAfter(MBB, -2); - ++NumCBZ; - MadeChange = true; + MachineBasicBlock::iterator CmpMI = Br.MI; + if (CmpMI != Br.MI->getParent()->begin()) { + --CmpMI; + if (CmpMI->getOpcode() == ARM::tCMPi8) { + unsigned Reg = CmpMI->getOperand(0).getReg(); + Pred = llvm::getInstrPredicate(CmpMI, PredReg); + if (Pred == ARMCC::AL && + CmpMI->getOperand(1).getImm() == 0 && + isARMLowRegister(Reg)) { + MachineBasicBlock *MBB = Br.MI->getParent(); + MachineInstr *NewBR = + BuildMI(*MBB, CmpMI, Br.MI->getDebugLoc(), TII->get(NewOpc)) + .addReg(Reg).addMBB(DestBB,Br.MI->getOperand(0).getTargetFlags()); + CmpMI->eraseFromParent(); + Br.MI->eraseFromParent(); + Br.MI = NewBR; + BBSizes[MBB->getNumber()] -= 2; + AdjustBBOffsetsAfter(MBB, -2); + ++NumCBZ; + MadeChange = true; + } } } } From benny.kra at googlemail.com Fri Apr 1 17:26:28 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Sat, 2 Apr 2011 00:26:28 +0200 Subject: [llvm-commits] [llvm] r128732 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCasts.cpp test/Transforms/InstCombine/sext.ll In-Reply-To: References: <20110401200910.9ED192A6C12C@llvm.org> Message-ID: <2FD6E29A-6AF5-431D-AEC5-552777FB9CBB@googlemail.com> On 01.04.2011, at 23:46, Frits van Bommel wrote: > On Fri, Apr 1, 2011 at 10:09 PM, Benjamin Kramer > wrote: >> + // Transforming icmps with more than one use is not profitable. >> + if (!ICI->hasOneUse()) >> + return 0; > > Did you test this? > Intuitively, independent icmp + ashr could be more efficient than a > (sext (icmp)) with extra uses for the icmp. Then again, they may not > be since they introduce an extra use of 'x'. > Just a thought. sext from i1 is typically more expensive than an ashr, so you're probably right. I'll move the use check to the new optimization, which inserts multiple instructions in the common case. > >> + >> if (ConstantInt *Op1C = dyn_cast(Op1)) { >> // (x ashr x, 31 -> all ones if signed >> // (x >s -1) ? -1 : 0 -> ashr x, 31 -> all ones if not signed >> @@ -898,6 +902,52 @@ >> In = Builder->CreateNot(In, In->getName()+".not"); >> return ReplaceInstUsesWith(CI, In); >> } >> + >> + // If we know that only one bit of the LHS of the icmp can be set and we >> + // have an equality comparison with zero or a power of 2, we can transform >> + // the icmp and sext into bitwise/integer operations. >> + if (ICI->isEquality() && (Op1C->isZero() || Op1C->getValue().isPowerOf2())){ >> + unsigned BitWidth = Op1C->getType()->getBitWidth(); >> + APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); >> + APInt TypeMask(APInt::getAllOnesValue(BitWidth)); >> + ComputeMaskedBits(Op0, TypeMask, KnownZero, KnownOne); >> + >> + if ((~KnownZero).isPowerOf2()) { >> + Value *In = ICI->getOperand(0); >> + >> + if (!Op1C->isZero() == (Pred == ICmpInst::ICMP_NE)) { >> + // sext ((x & 2^n) == 0) -> (x >> n) - 1 >> + // sext ((x & 2^n) != 2^n) -> (x >> n) - 1 > > Did I miss where you checked whether the RHS of the and is equal to > the RHS of the icmp for the second case? > Or does this miscompile e.g. sext((x & 8) != 16)? > (You can optimize that to -1, of course) That's something that should be constant folded at this point. I'll add an assert to be sure. > >> + unsigned ShiftAmt = KnownZeroMask.countTrailingZeros(); >> + // Perform a right shift to place the desired bit in the LSB. >> + if (ShiftAmt) >> + In = Builder->CreateLShr(In, >> + ConstantInt::get(In->getType(), ShiftAmt)); >> + >> + // At this point "In" is either 1 or 0. Subtract 1 to turn >> + // {1, 0} -> {0, -1}. >> + In = Builder->CreateAdd(In, >> + ConstantInt::getAllOnesValue(In->getType()), >> + "sext"); >> + } else { >> + // sext ((x & 2^n) != 0) -> (x << bitwidth-n) a>> bitwidth-1 >> + // sext ((x & 2^n) != 2^n) -> (x << bitwidth-n) a>> bitwidth-1 > > I think you meant '==' in the second case. > And this seems to have the same issue as above, miscompiling 'sext((x > & 8) == 16)' (which is 0). Doh! Stupid copy and paste. > >> + unsigned ShiftAmt = KnownZeroMask.countLeadingZeros(); >> + // Perform a left shift to place the desired bit in the MSB. >> + if (ShiftAmt) >> + In = Builder->CreateShl(In, >> + ConstantInt::get(In->getType(), ShiftAmt)); >> + >> + // Distribute the bit over the whole bit width. >> + In = Builder->CreateAShr(In, ConstantInt::get(In->getType(), >> + BitWidth - 1), "sext"); >> + } >> + >> + if (CI.getType() == In->getType()) >> + return ReplaceInstUsesWith(CI, In); >> + return CastInst::CreateIntegerCast(In, CI.getType(), true/*SExt*/); >> + } >> + } >> } From benny.kra at googlemail.com Fri Apr 1 17:22:12 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 01 Apr 2011 22:22:12 -0000 Subject: [llvm-commits] [llvm] r128744 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Message-ID: <20110401222212.234FD2A6C12C@llvm.org> Author: d0k Date: Fri Apr 1 17:22:11 2011 New Revision: 128744 URL: http://llvm.org/viewvc/llvm-project?rev=128744&view=rev Log: Tweaks to the icmp+sext-to-shifts optimization to address Frits' comments: - Localize the check if an icmp has one use to a place where we know we're introducing something that's likely more expensive than a sext from i1. - Add an assert to make sure a case that would lead to a miscompilation is folded away earlier. - Fix a typo. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=128744&r1=128743&r2=128744&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Fri Apr 1 17:22:11 2011 @@ -882,10 +882,6 @@ Value *Op0 = ICI->getOperand(0), *Op1 = ICI->getOperand(1); ICmpInst::Predicate Pred = ICI->getPredicate(); - // Transforming icmps with more than one use is not profitable. - if (!ICI->hasOneUse()) - return 0; - if (ConstantInt *Op1C = dyn_cast(Op1)) { // (x ashr x, 31 -> all ones if signed // (x >s -1) ? -1 : 0 -> ashr x, 31 -> all ones if not signed @@ -906,7 +902,8 @@ // If we know that only one bit of the LHS of the icmp can be set and we // have an equality comparison with zero or a power of 2, we can transform // the icmp and sext into bitwise/integer operations. - if (ICI->isEquality() && (Op1C->isZero() || Op1C->getValue().isPowerOf2())){ + if (ICI->hasOneUse() && + ICI->isEquality() && (Op1C->isZero() || Op1C->getValue().isPowerOf2())){ unsigned BitWidth = Op1C->getType()->getBitWidth(); APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); APInt TypeMask(APInt::getAllOnesValue(BitWidth)); @@ -916,6 +913,9 @@ if (KnownZeroMask.isPowerOf2()) { Value *In = ICI->getOperand(0); + assert((Op1C->isZero() || Op1C->getValue() == KnownZeroMask) && + "Constant icmp not folded?"); + if (!Op1C->isZero() == (Pred == ICmpInst::ICMP_NE)) { // sext ((x & 2^n) == 0) -> (x >> n) - 1 // sext ((x & 2^n) != 2^n) -> (x >> n) - 1 @@ -932,7 +932,7 @@ "sext"); } else { // sext ((x & 2^n) != 0) -> (x << bitwidth-n) a>> bitwidth-1 - // sext ((x & 2^n) != 2^n) -> (x << bitwidth-n) a>> bitwidth-1 + // sext ((x & 2^n) == 2^n) -> (x << bitwidth-n) a>> bitwidth-1 unsigned ShiftAmt = KnownZeroMask.countLeadingZeros(); // Perform a left shift to place the desired bit in the MSB. if (ShiftAmt) From benny.kra at googlemail.com Fri Apr 1 17:29:18 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 01 Apr 2011 22:29:18 -0000 Subject: [llvm-commits] [llvm] r128745 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Message-ID: <20110401222919.09B9F2A6C12C@llvm.org> Author: d0k Date: Fri Apr 1 17:29:18 2011 New Revision: 128745 URL: http://llvm.org/viewvc/llvm-project?rev=128745&view=rev Log: Fix comment. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=128745&r1=128744&r2=128745&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Fri Apr 1 17:29:18 2011 @@ -883,8 +883,8 @@ ICmpInst::Predicate Pred = ICI->getPredicate(); if (ConstantInt *Op1C = dyn_cast(Op1)) { - // (x ashr x, 31 -> all ones if signed - // (x >s -1) ? -1 : 0 -> ashr x, 31 -> all ones if not signed + // (x ashr x, 31 -> all ones if negative + // (x >s -1) ? -1 : 0 -> not (ashr x, 31) -> all ones if positive if ((Pred == ICmpInst::ICMP_SLT && Op1C->isZero()) || (Pred == ICmpInst::ICMP_SGT && Op1C->isAllOnesValue())) { From benny.kra at googlemail.com Fri Apr 1 17:36:20 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Sat, 2 Apr 2011 00:36:20 +0200 Subject: [llvm-commits] [llvm] r128731 - in /llvm/trunk/lib/Transforms/InstCombine: InstCombine.h InstCombineCasts.cpp In-Reply-To: References: <20110401200903.7A3CC2A6C12C@llvm.org> Message-ID: <2CF79990-3518-4582-B318-A157DC544395@googlemail.com> On 01.04.2011, at 23:51, Frits van Bommel wrote: > I know you only moved this code, but I still have some comments on it: > > On Fri, Apr 1, 2011 at 10:09 PM, Benjamin Kramer > wrote: >> + // (x ashr x, 31 -> all ones if signed >> + // (x >s -1) ? -1 : 0 -> ashr x, 31 -> all ones if not signed > > The second comment line is incorrect. The ashr should be 'not (ashr x, 31)'. Fixed in r128745. >> + if ((Pred == ICmpInst::ICMP_SLT && Op1C->isZero()) || >> + (Pred == ICmpInst::ICMP_SGT && Op1C->isAllOnesValue())) { > > It seems to me that this can also be done for (x u > signed_max). Unless those are canonicalized to signed comparisons > elsewhere? Yeah, these two are the cases that the many possible checks for a sign bit are canonicalized into. Thanks for the great and thorough reviews :) From ahatanak at gmail.com Fri Apr 1 17:36:46 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Fri, 1 Apr 2011 15:36:46 -0700 Subject: [llvm-commits] MIPS patch Message-ID: This patch moves transformation of JmpLink and related nodes done during instruction selection to Legalize. Index: lib/Target/Mips/MipsISelDAGToDAG.cpp =================================================================== --- lib/Target/Mips/MipsISelDAGToDAG.cpp (revision 128742) +++ lib/Target/Mips/MipsISelDAGToDAG.cpp (working copy) @@ -122,7 +122,8 @@ if ((Addr.getOpcode() == ISD::TargetGlobalAddress) || (Addr.getOpcode() == ISD::TargetConstantPool) || (Addr.getOpcode() == ISD::TargetJumpTable) || - (Addr.getOpcode() == ISD::TargetBlockAddress)) { + (Addr.getOpcode() == ISD::TargetBlockAddress) || + (Addr.getOpcode() == ISD::TargetExternalSymbol)) { Base = CurDAG->getRegister(Mips::GP, MVT::i32); Offset = Addr; return true; @@ -444,61 +445,6 @@ return ResNode; // Other cases are autogenerated. break; - - /// Handle direct and indirect calls when using PIC. On PIC, when - /// GOT is smaller than about 64k (small code) the GA target is - /// loaded with only one instruction. Otherwise GA's target must - /// be loaded with 3 instructions. - case MipsISD::JmpLink: { - if (TM.getRelocationModel() == Reloc::PIC_) { - unsigned LastOpNum = Node->getNumOperands()-1; - - SDValue Chain = Node->getOperand(0); - SDValue Callee = Node->getOperand(1); - SDValue InFlag; - - // Skip the incomming flag if present - if (Node->getOperand(LastOpNum).getValueType() == MVT::Glue) - LastOpNum--; - - if ( (isa(Callee)) || - (isa(Callee)) ) - { - /// Direct call for global addresses and external symbols - SDValue GPReg = CurDAG->getRegister(Mips::GP, MVT::i32); - - // Use load to get GOT target - SDValue Ops[] = { Callee, GPReg, Chain }; - SDValue Load = SDValue(CurDAG->getMachineNode(Mips::LW, dl, MVT::i32, - MVT::Other, Ops, 3), 0); - Chain = Load.getValue(1); - - // Call target must be on T9 - Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Load, InFlag); - } else - /// Indirect call - Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Callee, InFlag); - - // Map the JmpLink operands to JALR - SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Glue); - SmallVector Ops; - Ops.push_back(CurDAG->getRegister(Mips::T9, MVT::i32)); - - for (unsigned i = 2, e = LastOpNum+1; i != e; ++i) - Ops.push_back(Node->getOperand(i)); - Ops.push_back(Chain); - Ops.push_back(Chain.getValue(1)); - - // Emit Jump and Link Register - SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, NodeTys, - &Ops[0], Ops.size()); - - // Replace Chain and InFlag - ReplaceUses(SDValue(Node, 0), SDValue(ResNode, 0)); - ReplaceUses(SDValue(Node, 1), SDValue(ResNode, 1)); - return ResNode; - } - } } // Select the default instruction Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp (revision 128741) +++ lib/Target/Mips/MipsISelLowering.cpp (working copy) @@ -1201,13 +1201,35 @@ // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol // node so that legalize doesn't hack it. unsigned char OpFlag = IsPIC ? MipsII::MO_GOT_CALL : MipsII::MO_NO_FLAG; - if (GlobalAddressSDNode *G = dyn_cast(Callee)) + bool LoadSymAddr = false; + + if (GlobalAddressSDNode *G = dyn_cast(Callee)) { Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, - getPointerTy(), 0, OpFlag); - else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) + getPointerTy(), 0, OpFlag); + LoadSymAddr = true; + } + else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) { Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(), OpFlag); + LoadSymAddr = true; + } + // Create nodes that load address of callee and copy it to T9 + if (IsPIC) { + if (LoadSymAddr) { + // load callee address + Callee = DAG.getLoad(MVT::i32, dl, Chain, Callee, + MachinePointerInfo::getGOT(), + false, false, 0); + Chain = Callee.getValue(1); + } + + // copy to T9 + Chain = DAG.getCopyToReg(Chain, dl, Mips::T9, Callee, SDValue(0, 0)); + InFlag = Chain.getValue(1); + Callee = DAG.getRegister(Mips::T9, MVT::i32); + } + // MipsJmpLink = #chain, #target_address, #opt_in_flags... // = Chain, Callee, Reg#1, Reg#2, ... // -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110401/837071d1/attachment-0001.html -------------- next part -------------- A non-text attachment was scrubbed... Name: jmplink.patch Type: text/x-patch Size: 4842 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110401/837071d1/attachment-0001.bin From johnny.chen at apple.com Fri Apr 1 17:32:51 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 01 Apr 2011 22:32:51 -0000 Subject: [llvm-commits] [llvm] r128746 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td test/MC/Disassembler/ARM/arm-tests.txt Message-ID: <20110401223251.A268F2A6C12C@llvm.org> Author: johnny Date: Fri Apr 1 17:32:51 2011 New Revision: 128746 URL: http://llvm.org/viewvc/llvm-project?rev=128746&view=rev Log: Fix the instruction table entries for AI1_adde_sube_s_irs multiclass definition so that all the instruction have: let Inst{31-27} = 0b1110; // non-predicated Before, the ARM decoder was confusing: > 0x40 0xf3 0xb8 0x80 as: Opcode=16 Name=ADCSSrs Format=ARM_FORMAT_DPSOREGFRM(5) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ------------------------------------------------------------------------------------------------- | 1: 0: 0: 0| 0: 0: 0: 0| 1: 0: 1: 1| 1: 0: 0: 0| 1: 1: 1: 1| 0: 0: 1: 1| 0: 1: 0: 0| 0: 0: 0: 0| ------------------------------------------------------------------------------------------------- adcs pc, r8, r0, asr #6 since the cond field for ADCSSrs is a wild card, and so is ADCrs, with the ADCSSrs having Inst{20} as '1'. Now, the AR decoder behaves correctly: > 0x40 0xf3 0xb8 0x80 > END Executing command: /Volumes/data/lldb/llvm/Debug+Asserts/bin/llvm-mc -disassemble -triple=arm-apple-darwin -debug-only=arm-disassembler mc-input.txt Opcode=19 Name=ADCrs Format=ARM_FORMAT_DPSOREGFRM(5) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ------------------------------------------------------------------------------------------------- | 1: 0: 0: 0| 0: 0: 0: 0| 1: 0: 1: 1| 1: 0: 0: 0| 1: 1: 1: 1| 0: 0: 1: 1| 0: 1: 0: 0| 0: 0: 0: 0| ------------------------------------------------------------------------------------------------- adcshi pc, r8, r0, asr #6 > rdar://problem/9223094 Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128746&r1=128745&r2=128746&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri Apr 1 17:32:51 2011 @@ -939,6 +939,7 @@ bits<4> Rd; bits<4> Rn; bits<12> imm; + let Inst{31-27} = 0b1110; // non-predicated let Inst{15-12} = Rd; let Inst{19-16} = Rn; let Inst{11-0} = imm; @@ -952,6 +953,7 @@ bits<4> Rd; bits<4> Rn; bits<4> Rm; + let Inst{31-27} = 0b1110; // non-predicated let Inst{11-4} = 0b00000000; let isCommutable = Commutable; let Inst{3-0} = Rm; @@ -967,6 +969,7 @@ bits<4> Rd; bits<4> Rn; bits<12> shift; + let Inst{31-27} = 0b1110; // non-predicated let Inst{11-0} = shift; let Inst{15-12} = Rd; let Inst{19-16} = Rn; Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=128746&r1=128745&r2=128746&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Fri Apr 1 17:32:51 2011 @@ -226,3 +226,10 @@ # CHECK: blx #60 0x0f 0x00 0x00 0xfa + +# CHECK-NOT: adcs r10, r8, r0, asr #6 +# CHECK: adcshi r10, r8, r0, asr #6 +0x40 0xa3 0xb8 0x80 + +# CHECK: adcshi r10, r8, r0, asr r3 +0x50 0xa3 0xb8 0x80 From johnny.chen at apple.com Fri Apr 1 18:15:51 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 01 Apr 2011 23:15:51 -0000 Subject: [llvm-commits] [llvm] r128748 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td test/MC/Disassembler/ARM/invalid-MOVs-arm.txt Message-ID: <20110401231551.280A72A6C12C@llvm.org> Author: johnny Date: Fri Apr 1 18:15:50 2011 New Revision: 128748 URL: http://llvm.org/viewvc/llvm-project?rev=128748&view=rev Log: MOVs should have Inst{19-16} as 0b0000, otherwise, the instruction is UNPREDICTABLE. rdar://problem/9224120 Added: llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128748&r1=128747&r2=128748&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri Apr 1 18:15:50 2011 @@ -2009,6 +2009,7 @@ bits<4> Rd; bits<12> src; let Inst{15-12} = Rd; + let Inst{19-16} = 0b0000; let Inst{11-0} = src; let Inst{25} = 0; } Added: llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt?rev=128748&view=auto ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt (added) +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt Fri Apr 1 18:15:50 2011 @@ -0,0 +1,17 @@ +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} + +# Opcode=0 Name=PHI Format=(42) +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# ------------------------------------------------------------------------------------------------- +# | 1: 1: 1: 1| 0: 0: 0: 1| 1: 0: 1: 1| 1: 1: 0: 0| 1: 1: 0: 1| 0: 0: 0: 1| 0: 0: 0: 0| 0: 0: 1: 0| +# ------------------------------------------------------------------------------------------------- +# To qualify as an LSL (immediate) instruction, Inst{19-16} "should" be 0b0000, instead it is = 0b1100. +# The instruction is UNPREDICTABLE, and is not a valid intruction. +# +# See also +# A8.6.88 LSL (immediate) +# A8.6.98 MOV (shifted register), and +# I.1 Instruction encoding diagrams and pseudocode +0x2 0xd1 0xbc 0xf1 + + From johnny.chen at apple.com Fri Apr 1 18:30:25 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 01 Apr 2011 23:30:25 -0000 Subject: [llvm-commits] [llvm] r128749 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td test/MC/Disassembler/ARM/invalid-MOVr-arm.txt Message-ID: <20110401233026.00BBA2A6C12C@llvm.org> Author: johnny Date: Fri Apr 1 18:30:25 2011 New Revision: 128749 URL: http://llvm.org/viewvc/llvm-project?rev=128749&view=rev Log: Fixed MOVr for "should be" encoding bits for Inst{19-16} = 0b0000. rdar://problem/9224276 Added: llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128749&r1=128748&r2=128749&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri Apr 1 18:30:25 2011 @@ -1983,6 +1983,7 @@ bits<4> Rd; bits<4> Rm; + let Inst{19-16} = 0b0000; let Inst{11-4} = 0b00000000; let Inst{25} = 0; let Inst{3-0} = Rm; Added: llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt?rev=128749&view=auto ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt (added) +++ llvm/trunk/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt Fri Apr 1 18:30:25 2011 @@ -0,0 +1,13 @@ +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} + +# Opcode=0 Name=PHI Format=(42) +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# ------------------------------------------------------------------------------------------------- +# | 1: 1: 1: 1| 0: 0: 0: 1| 1: 0: 1: 1| 1: 1: 0: 0| 1: 1: 0: 1| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 1: 0| +# ------------------------------------------------------------------------------------------------- +# To qualify as a MOV (register) instruction, Inst{19-16} "should" be 0b0000, instead it is = 0b1100. +# The instruction is UNPREDICTABLE, and is not a valid intruction. +# +# See also +# A8.6.97 MOV (register) +0x2 0xd0 0xbc 0xf1 From ahatanak at gmail.com Fri Apr 1 19:15:58 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Sat, 02 Apr 2011 00:15:58 -0000 Subject: [llvm-commits] [llvm] r128750 - in /llvm/trunk/lib/Target/Mips: MipsAsmPrinter.cpp MipsISelDAGToDAG.cpp MipsISelLowering.cpp Message-ID: <20110402001558.BF8892A6C12C@llvm.org> Author: ahatanak Date: Fri Apr 1 19:15:58 2011 New Revision: 128750 URL: http://llvm.org/viewvc/llvm-project?rev=128750&view=rev Log: Insert space before ';' to prevent warnings. Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=128750&r1=128749&r2=128750&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Fri Apr 1 19:15:58 2011 @@ -270,7 +270,7 @@ // Otherwise, check the last instruction. // Check if the last terminator is an unconditional branch. MachineBasicBlock::const_iterator I = Pred->end(); - while (I != Pred->begin() && !(--I)->getDesc().isTerminator()); + while (I != Pred->begin() && !(--I)->getDesc().isTerminator()) ; return !I->getDesc().isBarrier(); } Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=128750&r1=128749&r2=128750&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Fri Apr 1 19:15:58 2011 @@ -122,7 +122,8 @@ if ((Addr.getOpcode() == ISD::TargetGlobalAddress) || (Addr.getOpcode() == ISD::TargetConstantPool) || (Addr.getOpcode() == ISD::TargetJumpTable) || - (Addr.getOpcode() == ISD::TargetBlockAddress)) { + (Addr.getOpcode() == ISD::TargetBlockAddress) || + (Addr.getOpcode() == ISD::TargetExternalSymbol)) { Base = CurDAG->getRegister(Mips::GP, MVT::i32); Offset = Addr; return true; @@ -444,61 +445,6 @@ return ResNode; // Other cases are autogenerated. break; - - /// Handle direct and indirect calls when using PIC. On PIC, when - /// GOT is smaller than about 64k (small code) the GA target is - /// loaded with only one instruction. Otherwise GA's target must - /// be loaded with 3 instructions. - case MipsISD::JmpLink: { - if (TM.getRelocationModel() == Reloc::PIC_) { - unsigned LastOpNum = Node->getNumOperands()-1; - - SDValue Chain = Node->getOperand(0); - SDValue Callee = Node->getOperand(1); - SDValue InFlag; - - // Skip the incomming flag if present - if (Node->getOperand(LastOpNum).getValueType() == MVT::Glue) - LastOpNum--; - - if ( (isa(Callee)) || - (isa(Callee)) ) - { - /// Direct call for global addresses and external symbols - SDValue GPReg = CurDAG->getRegister(Mips::GP, MVT::i32); - - // Use load to get GOT target - SDValue Ops[] = { Callee, GPReg, Chain }; - SDValue Load = SDValue(CurDAG->getMachineNode(Mips::LW, dl, MVT::i32, - MVT::Other, Ops, 3), 0); - Chain = Load.getValue(1); - - // Call target must be on T9 - Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Load, InFlag); - } else - /// Indirect call - Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Callee, InFlag); - - // Map the JmpLink operands to JALR - SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Glue); - SmallVector Ops; - Ops.push_back(CurDAG->getRegister(Mips::T9, MVT::i32)); - - for (unsigned i = 2, e = LastOpNum+1; i != e; ++i) - Ops.push_back(Node->getOperand(i)); - Ops.push_back(Chain); - Ops.push_back(Chain.getValue(1)); - - // Emit Jump and Link Register - SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, NodeTys, - &Ops[0], Ops.size()); - - // Replace Chain and InFlag - ReplaceUses(SDValue(Node, 0), SDValue(ResNode, 0)); - ReplaceUses(SDValue(Node, 1), SDValue(ResNode, 1)); - return ResNode; - } - } } // Select the default instruction Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=128750&r1=128749&r2=128750&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Fri Apr 1 19:15:58 2011 @@ -1201,12 +1201,34 @@ // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol // node so that legalize doesn't hack it. unsigned char OpFlag = IsPIC ? MipsII::MO_GOT_CALL : MipsII::MO_NO_FLAG; - if (GlobalAddressSDNode *G = dyn_cast(Callee)) + bool LoadSymAddr = false; + + if (GlobalAddressSDNode *G = dyn_cast(Callee)) { Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, - getPointerTy(), 0, OpFlag); - else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) + getPointerTy(), 0, OpFlag); + LoadSymAddr = true; + } + else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) { Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(), OpFlag); + LoadSymAddr = true; + } + + // Create nodes that load address of callee and copy it to T9 + if (IsPIC) { + if (LoadSymAddr) { + // load callee address + Callee = DAG.getLoad(MVT::i32, dl, Chain, Callee, + MachinePointerInfo::getGOT(), + false, false, 0); + Chain = Callee.getValue(1); + } + + // copy to T9 + Chain = DAG.getCopyToReg(Chain, dl, Mips::T9, Callee, SDValue(0, 0)); + InFlag = Chain.getValue(1); + Callee = DAG.getRegister(Mips::T9, MVT::i32); + } // MipsJmpLink = #chain, #target_address, #opt_in_flags... // = Chain, Callee, Reg#1, Reg#2, ... From ahatanak at gmail.com Fri Apr 1 19:26:12 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Sat, 02 Apr 2011 00:26:12 -0000 Subject: [llvm-commits] [llvm] r128751 - in /llvm/trunk/lib/Target/Mips: MipsISelDAGToDAG.cpp MipsISelLowering.cpp Message-ID: <20110402002612.A4E962A6C12C@llvm.org> Author: ahatanak Date: Fri Apr 1 19:26:12 2011 New Revision: 128751 URL: http://llvm.org/viewvc/llvm-project?rev=128751&view=rev Log: Undo changes mistakenly made in revision 128750. Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=128751&r1=128750&r2=128751&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Fri Apr 1 19:26:12 2011 @@ -122,8 +122,7 @@ if ((Addr.getOpcode() == ISD::TargetGlobalAddress) || (Addr.getOpcode() == ISD::TargetConstantPool) || (Addr.getOpcode() == ISD::TargetJumpTable) || - (Addr.getOpcode() == ISD::TargetBlockAddress) || - (Addr.getOpcode() == ISD::TargetExternalSymbol)) { + (Addr.getOpcode() == ISD::TargetBlockAddress)) { Base = CurDAG->getRegister(Mips::GP, MVT::i32); Offset = Addr; return true; @@ -445,6 +444,61 @@ return ResNode; // Other cases are autogenerated. break; + + /// Handle direct and indirect calls when using PIC. On PIC, when + /// GOT is smaller than about 64k (small code) the GA target is + /// loaded with only one instruction. Otherwise GA's target must + /// be loaded with 3 instructions. + case MipsISD::JmpLink: { + if (TM.getRelocationModel() == Reloc::PIC_) { + unsigned LastOpNum = Node->getNumOperands()-1; + + SDValue Chain = Node->getOperand(0); + SDValue Callee = Node->getOperand(1); + SDValue InFlag; + + // Skip the incomming flag if present + if (Node->getOperand(LastOpNum).getValueType() == MVT::Glue) + LastOpNum--; + + if ( (isa(Callee)) || + (isa(Callee)) ) + { + /// Direct call for global addresses and external symbols + SDValue GPReg = CurDAG->getRegister(Mips::GP, MVT::i32); + + // Use load to get GOT target + SDValue Ops[] = { Callee, GPReg, Chain }; + SDValue Load = SDValue(CurDAG->getMachineNode(Mips::LW, dl, MVT::i32, + MVT::Other, Ops, 3), 0); + Chain = Load.getValue(1); + + // Call target must be on T9 + Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Load, InFlag); + } else + /// Indirect call + Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Callee, InFlag); + + // Map the JmpLink operands to JALR + SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Glue); + SmallVector Ops; + Ops.push_back(CurDAG->getRegister(Mips::T9, MVT::i32)); + + for (unsigned i = 2, e = LastOpNum+1; i != e; ++i) + Ops.push_back(Node->getOperand(i)); + Ops.push_back(Chain); + Ops.push_back(Chain.getValue(1)); + + // Emit Jump and Link Register + SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, NodeTys, + &Ops[0], Ops.size()); + + // Replace Chain and InFlag + ReplaceUses(SDValue(Node, 0), SDValue(ResNode, 0)); + ReplaceUses(SDValue(Node, 1), SDValue(ResNode, 1)); + return ResNode; + } + } } // Select the default instruction Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=128751&r1=128750&r2=128751&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Fri Apr 1 19:26:12 2011 @@ -1201,34 +1201,12 @@ // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol // node so that legalize doesn't hack it. unsigned char OpFlag = IsPIC ? MipsII::MO_GOT_CALL : MipsII::MO_NO_FLAG; - bool LoadSymAddr = false; - - if (GlobalAddressSDNode *G = dyn_cast(Callee)) { + if (GlobalAddressSDNode *G = dyn_cast(Callee)) Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, - getPointerTy(), 0, OpFlag); - LoadSymAddr = true; - } - else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) { + getPointerTy(), 0, OpFlag); + else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(), OpFlag); - LoadSymAddr = true; - } - - // Create nodes that load address of callee and copy it to T9 - if (IsPIC) { - if (LoadSymAddr) { - // load callee address - Callee = DAG.getLoad(MVT::i32, dl, Chain, Callee, - MachinePointerInfo::getGOT(), - false, false, 0); - Chain = Callee.getValue(1); - } - - // copy to T9 - Chain = DAG.getCopyToReg(Chain, dl, Mips::T9, Callee, SDValue(0, 0)); - InFlag = Chain.getValue(1); - Callee = DAG.getRegister(Mips::T9, MVT::i32); - } // MipsJmpLink = #chain, #target_address, #opt_in_flags... // = Chain, Callee, Reg#1, Reg#2, ... From johnny.chen at apple.com Fri Apr 1 21:24:54 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Sat, 02 Apr 2011 02:24:54 -0000 Subject: [llvm-commits] [llvm] r128757 - in /llvm/trunk: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp test/MC/Disassembler/ARM/arm-tests.txt Message-ID: <20110402022454.E32492A6C12C@llvm.org> Author: johnny Date: Fri Apr 1 21:24:54 2011 New Revision: 128757 URL: http://llvm.org/viewvc/llvm-project?rev=128757&view=rev Log: Fixed a bug in disassembly of STR_POST, where the immediate is the second operand in am2offset; instead of the second operand in addrmode_imm12. rdar://problem/9225289 Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128757&r1=128756&r2=128757&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Fri Apr 1 21:24:54 2011 @@ -1098,12 +1098,20 @@ OpIdx += 1; } - // Disassemble the 12-bit immediate offset, which is the second operand in - // $addrmode_imm12 => (ops GPR:$base, i32imm:$offsimm). - // unsigned Imm12 = slice(insn, 11, 0); - int Offset = AddrOpcode == ARM_AM::add ? 1 * Imm12 : -1 * Imm12; - MI.addOperand(MCOperand::CreateImm(Offset)); + if (Opcode == ARM::LDRBi12 || Opcode == ARM::LDRi12 || + Opcode == ARM::STRBi12 || Opcode == ARM::STRi12) { + // Disassemble the 12-bit immediate offset, which is the second operand in + // $addrmode_imm12 => (ops GPR:$base, i32imm:$offsimm). + int Offset = AddrOpcode == ARM_AM::add ? 1 * Imm12 : -1 * Imm12; + MI.addOperand(MCOperand::CreateImm(Offset)); + } else { + // Disassemble the 12-bit immediate offset, which is the second operand in + // $am2offset => (ops GPR, i32imm). + unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift, + IndexMode); + MI.addOperand(MCOperand::CreateImm(Offset)); + } OpIdx += 1; } else { // The opcode ARM::LDRT actually corresponds to both Encoding A1 and A2 of Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=128757&r1=128756&r2=128757&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Fri Apr 1 21:24:54 2011 @@ -233,3 +233,6 @@ # CHECK: adcshi r10, r8, r0, asr r3 0x50 0xa3 0xb8 0x80 + +# CHECK: streq r1, [sp], #-1567 +0x1f 0x16 0xd 0x4 From zwarich at apple.com Fri Apr 1 21:40:26 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sat, 02 Apr 2011 02:40:26 -0000 Subject: [llvm-commits] [llvm] r128758 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <20110402024026.4C8962A6C12C@llvm.org> Author: zwarich Date: Fri Apr 1 21:40:26 2011 New Revision: 128758 URL: http://llvm.org/viewvc/llvm-project?rev=128758&view=rev Log: Add a RemoveFromWorklist method to DCI. This is needed to do some complicated transformations in target-specific DAG combines without causing DAGCombiner to delete the same node twice. If you know of a better way to avoid this (see my next patch for an example), please let me know. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=128758&r1=128757&r2=128758&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Fri Apr 1 21:40:26 2011 @@ -927,6 +927,7 @@ bool isCalledByLegalizer() const { return CalledByLegalizer; } void AddToWorklist(SDNode *N); + void RemoveFromWorklist(SDNode *N); SDValue CombineTo(SDNode *N, const std::vector &To, bool AddTo = true); SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=128758&r1=128757&r2=128758&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Apr 1 21:40:26 2011 @@ -319,6 +319,10 @@ ((DAGCombiner*)DC)->AddToWorkList(N); } +void TargetLowering::DAGCombinerInfo::RemoveFromWorklist(SDNode *N) { + ((DAGCombiner*)DC)->removeFromWorkList(N); +} + SDValue TargetLowering::DAGCombinerInfo:: CombineTo(SDNode *N, const std::vector &To, bool AddTo) { return ((DAGCombiner*)DC)->CombineTo(N, &To[0], To.size(), AddTo); From zwarich at apple.com Fri Apr 1 21:40:43 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sat, 02 Apr 2011 02:40:43 -0000 Subject: [llvm-commits] [llvm] r128759 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/fp-arg-shuffle.ll Message-ID: <20110402024043.7532F2A6C12C@llvm.org> Author: zwarich Date: Fri Apr 1 21:40:43 2011 New Revision: 128759 URL: http://llvm.org/viewvc/llvm-project?rev=128759&view=rev Log: Do some peephole optimizations to remove pointless VMOVs from Neon to integer registers that arise from argument shuffling with the soft float ABI. These instructions are particularly slow on Cortex A8. This fixes one half of . Added: llvm/trunk/test/CodeGen/ARM/fp-arg-shuffle.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=128759&r1=128758&r2=128759&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Apr 1 21:40:43 2011 @@ -5561,6 +5561,37 @@ SDValue InDouble = N->getOperand(0); if (InDouble.getOpcode() == ARMISD::VMOVDRR) return DCI.CombineTo(N, InDouble.getOperand(0), InDouble.getOperand(1)); + + // vmovrrd(load f64) -> (load i32), (load i32) + SDNode *InNode = InDouble.getNode(); + if (ISD::isNormalLoad(InNode) && InNode->hasOneUse() && + InNode->getValueType(0) == MVT::f64 && + InNode->getOperand(1).getOpcode() == ISD::FrameIndex && + !cast(InNode)->isVolatile()) { + // TODO: Should this be done for non-FrameIndex operands? + LoadSDNode *LD = cast(InNode); + + SelectionDAG &DAG = DCI.DAG; + DebugLoc DL = LD->getDebugLoc(); + SDValue BasePtr = LD->getBasePtr(); + SDValue NewLD1 = DAG.getLoad(MVT::i32, DL, LD->getChain(), BasePtr, + LD->getPointerInfo(), LD->isVolatile(), + LD->isNonTemporal(), LD->getAlignment()); + + SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr, + DAG.getConstant(4, MVT::i32)); + SDValue NewLD2 = DAG.getLoad(MVT::i32, DL, NewLD1.getValue(1), OffsetPtr, + LD->getPointerInfo(), LD->isVolatile(), + LD->isNonTemporal(), + std::min(4U, LD->getAlignment() / 2)); + + DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewLD2.getValue(1)); + SDValue Result = DCI.CombineTo(N, NewLD1, NewLD2); + DCI.RemoveFromWorklist(LD); + DAG.DeleteNode(LD); + return Result; + } + return SDValue(); } Added: llvm/trunk/test/CodeGen/ARM/fp-arg-shuffle.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fp-arg-shuffle.ll?rev=128759&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fp-arg-shuffle.ll (added) +++ llvm/trunk/test/CodeGen/ARM/fp-arg-shuffle.ll Fri Apr 1 21:40:43 2011 @@ -0,0 +1,11 @@ +; RUN: llc < %s -march=arm -mattr=+neon -float-abi=soft | FileCheck %s + +; CHECK: function1 +; CHECK-NOT: vmov r +define double @function1(double %a, double %b, double %c, double %d, double %e, double %f) nounwind noinline ssp { +entry: + %call = tail call double @function2(double %f, double %e, double %d, double %c, double %b, double %a) nounwind + ret double %call +} + +declare double @function2(double, double, double, double, double, double) From eli.friedman at gmail.com Fri Apr 1 22:46:56 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Fri, 1 Apr 2011 20:46:56 -0700 Subject: [llvm-commits] [llvm] r128759 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/fp-arg-shuffle.ll In-Reply-To: <20110402024043.7532F2A6C12C@llvm.org> References: <20110402024043.7532F2A6C12C@llvm.org> Message-ID: On Fri, Apr 1, 2011 at 7:40 PM, Cameron Zwarich wrote: > Author: zwarich > Date: Fri Apr ?1 21:40:43 2011 > New Revision: 128759 > > URL: http://llvm.org/viewvc/llvm-project?rev=128759&view=rev > Log: > Do some peephole optimizations to remove pointless VMOVs from Neon to integer > registers that arise from argument shuffling with the soft float ABI. These > instructions are particularly slow on Cortex A8. This fixes one half of > . > > Added: > ? ?llvm/trunk/test/CodeGen/ARM/fp-arg-shuffle.ll > Modified: > ? ?llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > > Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=128759&r1=128758&r2=128759&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Apr ?1 21:40:43 2011 > @@ -5561,6 +5561,37 @@ > ? SDValue InDouble = N->getOperand(0); > ? if (InDouble.getOpcode() == ARMISD::VMOVDRR) > ? ? return DCI.CombineTo(N, InDouble.getOperand(0), InDouble.getOperand(1)); > + > + ?// vmovrrd(load f64) -> (load i32), (load i32) > + ?SDNode *InNode = InDouble.getNode(); > + ?if (ISD::isNormalLoad(InNode) && InNode->hasOneUse() && > + ? ? ?InNode->getValueType(0) == MVT::f64 && > + ? ? ?InNode->getOperand(1).getOpcode() == ISD::FrameIndex && > + ? ? ?!cast(InNode)->isVolatile()) { > + ? ?// TODO: Should this be done for non-FrameIndex operands? > + ? ?LoadSDNode *LD = cast(InNode); > + > + ? ?SelectionDAG &DAG = DCI.DAG; > + ? ?DebugLoc DL = LD->getDebugLoc(); > + ? ?SDValue BasePtr = LD->getBasePtr(); > + ? ?SDValue NewLD1 = DAG.getLoad(MVT::i32, DL, LD->getChain(), BasePtr, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LD->getPointerInfo(), LD->isVolatile(), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LD->isNonTemporal(), LD->getAlignment()); > + > + ? ?SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?DAG.getConstant(4, MVT::i32)); > + ? ?SDValue NewLD2 = DAG.getLoad(MVT::i32, DL, NewLD1.getValue(1), OffsetPtr, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LD->getPointerInfo(), LD->isVolatile(), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LD->isNonTemporal(), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? std::min(4U, LD->getAlignment() / 2)); > + > + ? ?DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewLD2.getValue(1)); > + ? ?SDValue Result = DCI.CombineTo(N, NewLD1, NewLD2); > + ? ?DCI.RemoveFromWorklist(LD); > + ? ?DAG.DeleteNode(LD); The reason why RemoveFromWorklist didn't exist is that you don't need it; unlike in IR, you don't have to erase a dead instruction. (The nature of the DAG datastructure is that a node with no uses is automatically dead.) -Eli From zwarich at apple.com Fri Apr 1 23:14:27 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Fri, 01 Apr 2011 21:14:27 -0700 Subject: [llvm-commits] [llvm] r128759 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/fp-arg-shuffle.ll In-Reply-To: References: <20110402024043.7532F2A6C12C@llvm.org> Message-ID: On 2011-04-01, at 8:46 PM, Eli Friedman wrote: > The reason why RemoveFromWorklist didn't exist is that you don't need > it; unlike in IR, you don't have to erase a dead instruction. (The > nature of the DAG datastructure is that a node with no uses is > automatically dead.) That's what I thought at first, but it's apparently not true. If you remove that extra code from my patch, then another ARM test case fails because a store has a dead user of its chain value. There is special logic all throughout DAGCombiner to explicitly kill dead nodes and remove them from the worklist. Cameron From stoklund at 2pi.dk Sat Apr 2 01:03:32 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Sat, 02 Apr 2011 06:03:32 -0000 Subject: [llvm-commits] [llvm] r128763 - in /llvm/trunk: include/llvm/CodeGen/SlotIndexes.h lib/CodeGen/SlotIndexes.cpp Message-ID: <20110402060332.23E312A6C12C@llvm.org> Author: stoklund Date: Sat Apr 2 01:03:31 2011 New Revision: 128763 URL: http://llvm.org/viewvc/llvm-project?rev=128763&view=rev Log: Use basic block numbers as indexes when mapping slot index ranges. This is more compact and faster than using DenseMap. Modified: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h llvm/trunk/lib/CodeGen/SlotIndexes.cpp Modified: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SlotIndexes.h?rev=128763&r1=128762&r2=128763&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SlotIndexes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Sat Apr 2 01:03:31 2011 @@ -337,15 +337,12 @@ typedef DenseMap Mi2IndexMap; Mi2IndexMap mi2iMap; - /// MBB2IdxMap - The indexes of the first and last instructions in the - /// specified basic block. - typedef DenseMap > MBB2IdxMap; - MBB2IdxMap mbb2IdxMap; + /// MBBRanges - Map MBB number to (start, stop) indexes. + SmallVector, 8> MBBRanges; /// Idx2MBBMap - Sorted list of pairs of index of first instruction /// and MBB id. - std::vector idx2MBBMap; + SmallVector idx2MBBMap; // IndexListEntry allocator. BumpPtrAllocator ileAllocator; @@ -509,12 +506,16 @@ return nextNonNull; } + /// Return the (start,end) range of the given basic block number. + const std::pair & + getMBBRange(unsigned Num) const { + return MBBRanges[Num]; + } + /// Return the (start,end) range of the given basic block. const std::pair & - getMBBRange(const MachineBasicBlock *mbb) const { - MBB2IdxMap::const_iterator itr = mbb2IdxMap.find(mbb); - assert(itr != mbb2IdxMap.end() && "MBB not found in maps."); - return itr->second; + getMBBRange(const MachineBasicBlock *MBB) const { + return getMBBRange(MBB->getNumber()); } /// Returns the first index in the given basic block. @@ -529,10 +530,10 @@ /// Returns the basic block which the given index falls in. MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { - std::vector::const_iterator I = + SmallVectorImpl::const_iterator I = std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), index); // Take the pair containing the index - std::vector::const_iterator J = + SmallVectorImpl::const_iterator J = ((I != idx2MBBMap.end() && I->first > index) || (I == idx2MBBMap.end() && idx2MBBMap.size()>0)) ? (I-1): I; @@ -544,7 +545,7 @@ bool findLiveInMBBs(SlotIndex start, SlotIndex end, SmallVectorImpl &mbbs) const { - std::vector::const_iterator itr = + SmallVectorImpl::const_iterator itr = std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); bool resVal = false; @@ -564,7 +565,7 @@ assert(start < end && "Backwards ranges not allowed."); - std::vector::const_iterator itr = + SmallVectorImpl::const_iterator itr = std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); if (itr == idx2MBBMap.end()) { @@ -596,11 +597,6 @@ assert(mbb != 0 && "Instr must be added to function."); - MBB2IdxMap::iterator mbbRangeItr = mbb2IdxMap.find(mbb); - - assert(mbbRangeItr != mbb2IdxMap.end() && - "Instruction's parent MBB has not been added to SlotIndexes."); - MachineBasicBlock::iterator miItr(mi); IndexListEntry *newEntry; // Get previous index, considering that not all instructions are indexed. @@ -608,7 +604,7 @@ for (;;) { // If mi is at the mbb beginning, get the prev index from the mbb. if (miItr == mbb->begin()) { - prevEntry = &mbbRangeItr->second.first.entry(); + prevEntry = &getMBBStartIdx(mbb).entry(); break; } // Otherwise rewind until we find a mapped instruction. @@ -689,21 +685,14 @@ SlotIndex startIdx(startEntry, SlotIndex::LOAD); SlotIndex endIdx(nextEntry, SlotIndex::LOAD); - mbb2IdxMap.insert( - std::make_pair(mbb, std::make_pair(startIdx, endIdx))); + assert(unsigned(mbb->getNumber()) == MBBRanges.size() && + "Blocks must be added in order"); + MBBRanges.push_back(std::make_pair(startIdx, endIdx)); idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb)); - if (MachineFunction::iterator(mbb) != mbb->getParent()->begin()) { - // Have to update the end index of the previous block. - MachineBasicBlock *priorMBB = - llvm::prior(MachineFunction::iterator(mbb)); - mbb2IdxMap[priorMBB].second = startIdx; - } - renumberIndexes(); std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); - } }; Modified: llvm/trunk/lib/CodeGen/SlotIndexes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SlotIndexes.cpp?rev=128763&r1=128762&r2=128763&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SlotIndexes.cpp (original) +++ llvm/trunk/lib/CodeGen/SlotIndexes.cpp Sat Apr 2 01:03:31 2011 @@ -32,7 +32,7 @@ void SlotIndexes::releaseMemory() { mi2iMap.clear(); - mbb2IdxMap.clear(); + MBBRanges.clear(); idx2MBBMap.clear(); clearList(); } @@ -58,13 +58,15 @@ "Index list non-empty at initial numbering?"); assert(idx2MBBMap.empty() && "Index -> MBB mapping non-empty at initial numbering?"); - assert(mbb2IdxMap.empty() && + assert(MBBRanges.empty() && "MBB -> Index mapping non-empty at initial numbering?"); assert(mi2iMap.empty() && "MachineInstr -> Index mapping non-empty at initial numbering?"); functionSize = 0; unsigned index = 0; + MBBRanges.resize(mf->getNumBlockIDs()); + idx2MBBMap.reserve(mf->size()); push_back(createEntry(0, index)); @@ -94,10 +96,8 @@ // We insert one blank instructions between basic blocks. push_back(createEntry(0, index += SlotIndex::InstrDist)); - SlotIndex blockEndIndex(back(), SlotIndex::LOAD); - mbb2IdxMap.insert( - std::make_pair(mbb, std::make_pair(blockStartIndex, blockEndIndex))); - + MBBRanges[mbb->getNumber()].first = blockStartIndex; + MBBRanges[mbb->getNumber()].second = SlotIndex(back(), SlotIndex::LOAD); idx2MBBMap.push_back(IdxMBBPair(blockStartIndex, mbb)); } @@ -158,11 +158,9 @@ } } - for (MBB2IdxMap::const_iterator itr = mbb2IdxMap.begin(); - itr != mbb2IdxMap.end(); ++itr) { - dbgs() << "MBB " << itr->first->getNumber() << " (" << itr->first << ") - [" - << itr->second.first << ", " << itr->second.second << "]\n"; - } + for (unsigned i = 0, e = MBBRanges.size(); i != e; ++i) + dbgs() << "BB#" << i << "\t[" << MBBRanges[i].first << ';' + << MBBRanges[i].second << ")\n"; } // Print a SlotIndex to a raw_ostream. From stoklund at 2pi.dk Sat Apr 2 01:03:35 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Sat, 02 Apr 2011 06:03:35 -0000 Subject: [llvm-commits] [llvm] r128764 - in /llvm/trunk: include/llvm/ADT/IntervalMap.h lib/CodeGen/CMakeLists.txt lib/CodeGen/InterferenceCache.cpp lib/CodeGen/InterferenceCache.h lib/CodeGen/RegAllocGreedy.cpp Message-ID: <20110402060336.065E62A6C12D@llvm.org> Author: stoklund Date: Sat Apr 2 01:03:35 2011 New Revision: 128764 URL: http://llvm.org/viewvc/llvm-project?rev=128764&view=rev Log: Add an InterferenceCache class for caching per-block interference ranges. When the greedy register allocator is splitting multiple global live ranges, it tends to look at the same interference data many times. The InterferenceCache class caches queries for unaltered LiveIntervalUnions. Added: llvm/trunk/lib/CodeGen/InterferenceCache.cpp llvm/trunk/lib/CodeGen/InterferenceCache.h Modified: llvm/trunk/include/llvm/ADT/IntervalMap.h llvm/trunk/lib/CodeGen/CMakeLists.txt llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Modified: llvm/trunk/include/llvm/ADT/IntervalMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/IntervalMap.h?rev=128764&r1=128763&r2=128764&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/IntervalMap.h (original) +++ llvm/trunk/include/llvm/ADT/IntervalMap.h Sat Apr 2 01:03:35 2011 @@ -1328,6 +1328,10 @@ /// const_iterator - Create an iterator that isn't pointing anywhere. const_iterator() : map(0) {} + /// setMap - Change the map iterated over. This call must be followed by a + /// call to goToBegin(), goToEnd(), or find() + void setMap(const IntervalMap &m) { map = const_cast(&m); } + /// valid - Return true if the current position is valid, false for end(). bool valid() const { return path.valid(); } Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=128764&r1=128763&r2=128764&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Sat Apr 2 01:03:35 2011 @@ -19,6 +19,7 @@ GCStrategy.cpp IfConversion.cpp InlineSpiller.cpp + InterferenceCache.cpp IntrinsicLowering.cpp LLVMTargetMachine.cpp LatencyPriorityQueue.cpp Added: llvm/trunk/lib/CodeGen/InterferenceCache.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InterferenceCache.cpp?rev=128764&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/InterferenceCache.cpp (added) +++ llvm/trunk/lib/CodeGen/InterferenceCache.cpp Sat Apr 2 01:03:35 2011 @@ -0,0 +1,139 @@ +//===-- InterferenceCache.h - Caching per-block interference ---*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// InterferenceCache remembers per-block interference in LiveIntervalUnions. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "regalloc" +#include "InterferenceCache.h" +#include "llvm/Target/TargetRegisterInfo.h" + +using namespace llvm; + +void InterferenceCache::init(MachineFunction *mf, + LiveIntervalUnion *liuarray, + SlotIndexes *indexes, + const TargetRegisterInfo *tri) { + MF = mf; + LIUArray = liuarray; + TRI = tri; + PhysRegEntries.assign(TRI->getNumRegs(), 0); + for (unsigned i = 0; i != CacheEntries; ++i) + Entries[i].clear(indexes); +} + +InterferenceCache::Entry *InterferenceCache::get(unsigned PhysReg) { + unsigned E = PhysRegEntries[PhysReg]; + if (E < CacheEntries && Entries[E].getPhysReg() == PhysReg) { + if (!Entries[E].valid(LIUArray, TRI)) + Entries[E].revalidate(); + return &Entries[E]; + } + // No valid entry exists, pick the next round-robin entry. + E = RoundRobin; + if (++RoundRobin == CacheEntries) + RoundRobin = 0; + Entries[E].reset(PhysReg, LIUArray, TRI, MF); + PhysRegEntries[PhysReg] = E; + return &Entries[E]; +} + +/// revalidate - LIU contents have changed, update tags. +void InterferenceCache::Entry::revalidate() { + // Invalidate all block entries. + ++Tag; + // Invalidate all iterators. + PrevPos = SlotIndex(); + for (unsigned i = 0, e = Aliases.size(); i != e; ++i) + Aliases[i].second = Aliases[i].first->getTag(); +} + +void InterferenceCache::Entry::reset(unsigned physReg, + LiveIntervalUnion *LIUArray, + const TargetRegisterInfo *TRI, + const MachineFunction *MF) { + // LIU's changed, invalidate cache. + ++Tag; + PhysReg = physReg; + Blocks.resize(MF->getNumBlockIDs()); + Aliases.clear(); + for (const unsigned *AS = TRI->getOverlaps(PhysReg); *AS; ++AS) { + LiveIntervalUnion *LIU = LIUArray + *AS; + Aliases.push_back(std::make_pair(LIU, LIU->getTag())); + } + + // Reset iterators. + PrevPos = SlotIndex(); + unsigned e = Aliases.size(); + Iters.resize(e); + for (unsigned i = 0; i != e; ++i) + Iters[i].setMap(Aliases[i].first->getMap()); +} + +bool InterferenceCache::Entry::valid(LiveIntervalUnion *LIUArray, + const TargetRegisterInfo *TRI) { + unsigned i = 0, e = Aliases.size(); + for (const unsigned *AS = TRI->getOverlaps(PhysReg); *AS; ++AS, ++i) { + LiveIntervalUnion *LIU = LIUArray + *AS; + if (i == e || Aliases[i].first != LIU) + return false; + if (LIU->changedSince(Aliases[i].second)) + return false; + } + return i == e; +} + +void InterferenceCache::Entry::update(unsigned MBBNum) { + BlockInterference *BI = &Blocks[MBBNum]; + BI->Tag = Tag; + BI->First = BI->Last = SlotIndex(); + + SlotIndex Start, Stop; + tie(Start, Stop) = Indexes->getMBBRange(MBBNum); + + // Use advanceTo only when possible. + if (!PrevPos.isValid() || Start < PrevPos) + for (unsigned i = 0, e = Iters.size(); i != e; ++i) + Iters[i].find(Start); + else + for (unsigned i = 0, e = Iters.size(); i != e; ++i) + Iters[i].advanceTo(Start); + PrevPos = Start; + + // Check for first interference. + for (unsigned i = 0, e = Iters.size(); i != e; ++i) { + Iter &I = Iters[i]; + if (!I.valid()) + continue; + SlotIndex StartI = I.start(); + if (StartI >= Stop) + continue; + if (!BI->First.isValid() || StartI < BI->First) + BI->First = StartI; + } + + // No interference in block. + if (!BI->First.isValid()) + return; + + // Check for last interference. + for (unsigned i = 0, e = Iters.size(); i != e; ++i) { + Iter &I = Iters[i]; + if (!I.valid() || I.start() >= Stop) + continue; + I.advanceTo(Stop); + if (!I.valid() || I.start() >= Stop) + --I; + SlotIndex StopI = I.stop(); + if (!BI->Last.isValid() || StopI > BI->Last) + BI->Last = StopI; + } + PrevPos = Stop; +} Added: llvm/trunk/lib/CodeGen/InterferenceCache.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InterferenceCache.h?rev=128764&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/InterferenceCache.h (added) +++ llvm/trunk/lib/CodeGen/InterferenceCache.h Sat Apr 2 01:03:35 2011 @@ -0,0 +1,159 @@ +//===-- InterferenceCache.h - Caching per-block interference ---*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// InterferenceCache remembers per-block interference in LiveIntervalUnions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_INTERFERENCECACHE +#define LLVM_CODEGEN_INTERFERENCECACHE + +#include "LiveIntervalUnion.h" + +namespace llvm { + +class InterferenceCache { + const TargetRegisterInfo *TRI; + LiveIntervalUnion *LIUArray; + SlotIndexes *Indexes; + MachineFunction *MF; + + /// BlockInterference - information about the interference in a single basic + /// block. + struct BlockInterference { + BlockInterference() : Tag(0) {} + unsigned Tag; + SlotIndex First; + SlotIndex Last; + }; + + /// Entry - A cache entry containing interference information for all aliases + /// of PhysReg in all basic blocks. + class Entry { + /// PhysReg - The register currently represented. + unsigned PhysReg; + + /// Tag - Cache tag is changed when any of the underlying LiveIntervalUnions + /// change. + unsigned Tag; + + /// Indexes - Mapping block numbers to SlotIndex ranges. + SlotIndexes *Indexes; + + /// PrevPos - The previous position the iterators were moved to. + SlotIndex PrevPos; + + /// AliasTags - A LiveIntervalUnion pointer and tag for each alias of + /// PhysReg. + SmallVector, 8> Aliases; + + typedef LiveIntervalUnion::SegmentIter Iter; + + /// Iters - an iterator for each alias + SmallVector Iters; + + /// Blocks - Interference for each block in the function. + SmallVector Blocks; + + /// update - Recompute Blocks[MBBNum] + void update(unsigned MBBNum); + + public: + Entry() : PhysReg(0), Tag(0), Indexes(0) {} + + void clear(SlotIndexes *indexes) { + PhysReg = 0; + Indexes = indexes; + } + + unsigned getPhysReg() const { return PhysReg; } + + void revalidate(); + + /// valid - Return true if this is a valid entry for physReg. + bool valid(LiveIntervalUnion *LIUArray, const TargetRegisterInfo *TRI); + + /// reset - Initialize entry to represent physReg's aliases. + void reset(unsigned physReg, + LiveIntervalUnion *LIUArray, + const TargetRegisterInfo *TRI, + const MachineFunction *MF); + + /// get - Return an up to date BlockInterference. + BlockInterference *get(unsigned MBBNum) { + if (Blocks[MBBNum].Tag != Tag) + update(MBBNum); + return &Blocks[MBBNum]; + } + }; + + // We don't keep a cache entry for every physical register, that would use too + // much memory. Instead, a fixed number of cache entries are used in a round- + // robin manner. + enum { CacheEntries = 32 }; + + // Point to an entry for each physreg. The entry pointed to may not be up to + // date, and it may have been reused for a different physreg. + SmallVector PhysRegEntries; + + // Next round-robin entry to be picked. + unsigned RoundRobin; + + // The actual cache entries. + Entry Entries[CacheEntries]; + + // get - Get a valid entry for PhysReg. + Entry *get(unsigned PhysReg); + +public: + InterferenceCache() : TRI(0), LIUArray(0), Indexes(0), MF(0), RoundRobin(0) {} + + /// init - Prepare cache for a new function. + void init(MachineFunction*, LiveIntervalUnion*, SlotIndexes*, + const TargetRegisterInfo *); + + /// Cursor - The primary query interface for the block interference cache. + class Cursor { + Entry *CacheEntry; + BlockInterference *Current; + public: + /// Cursor - Create a cursor for the interference allocated to PhysReg and + /// all its aliases. + Cursor(InterferenceCache &Cache, unsigned PhysReg) + : CacheEntry(Cache.get(PhysReg)), Current(0) {} + + /// moveTo - Move cursor to basic block MBBNum. + void moveToBlock(unsigned MBBNum) { + Current = CacheEntry->get(MBBNum); + } + + /// hasInterference - Return true if the current block has any interference. + bool hasInterference() { + return Current->First.isValid(); + } + + /// first - Return the starting index of the first interfering range in the + /// current block. + SlotIndex first() { + return Current->First; + } + + /// last - Return the ending index of the last interfering range in the + /// current block. + SlotIndex last() { + return Current->Last; + } + }; + + friend class Cursor; +}; + +} // namespace llvm + +#endif Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=128764&r1=128763&r2=128764&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Sat Apr 2 01:03:35 2011 @@ -14,7 +14,7 @@ #define DEBUG_TYPE "regalloc" #include "AllocationOrder.h" -#include "LiveIntervalUnion.h" +#include "InterferenceCache.h" #include "LiveRangeEdit.h" #include "RegAllocBase.h" #include "Spiller.h" From stoklund at 2pi.dk Sat Apr 2 01:03:38 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Sat, 02 Apr 2011 06:03:38 -0000 Subject: [llvm-commits] [llvm] r128765 - /llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Message-ID: <20110402060338.422B22A6C12E@llvm.org> Author: stoklund Date: Sat Apr 2 01:03:38 2011 New Revision: 128765 URL: http://llvm.org/viewvc/llvm-project?rev=128765&view=rev Log: Use InterferenceCache in RegAllocGreedy. Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=128765&r1=128764&r2=128765&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Sat Apr 2 01:03:38 2011 @@ -119,15 +119,15 @@ std::auto_ptr SA; std::auto_ptr SE; + /// Cached per-block interference maps + InterferenceCache IntfCache; + /// All basic blocks where the current register is live. SmallVector SplitConstraints; - typedef std::pair IndexPair; - /// Global live range splitting candidate info. struct GlobalSplitCandidate { unsigned PhysReg; - SmallVector Interference; BitVector LiveBundles; }; @@ -168,9 +168,7 @@ void LRE_WillShrinkVirtReg(unsigned); void LRE_DidCloneVirtReg(unsigned, unsigned); - void mapGlobalInterference(unsigned, SmallVectorImpl&); - float calcSplitConstraints(const SmallVectorImpl&); - + float calcSplitConstraints(unsigned); float calcGlobalSplitCost(const BitVector&); void splitAroundRegion(LiveInterval&, unsigned, const BitVector&, SmallVectorImpl&); @@ -407,96 +405,53 @@ // Region Splitting //===----------------------------------------------------------------------===// -/// mapGlobalInterference - Compute a map of the interference from PhysReg and -/// its aliases in each block in SA->LiveBlocks. -/// If LiveBlocks[i] is live-in, Ranges[i].first is the first interference. -/// If LiveBlocks[i] is live-out, Ranges[i].second is the last interference. -void RAGreedy::mapGlobalInterference(unsigned PhysReg, - SmallVectorImpl &Ranges) { - Ranges.assign(SA->LiveBlocks.size(), IndexPair()); - LiveInterval &VirtReg = const_cast(SA->getParent()); - for (const unsigned *AI = TRI->getOverlaps(PhysReg); *AI; ++AI) { - if (!query(VirtReg, *AI).checkInterference()) - continue; - LiveIntervalUnion::SegmentIter IntI = - PhysReg2LiveUnion[*AI].find(VirtReg.beginIndex()); - if (!IntI.valid()) - continue; - for (unsigned i = 0, e = SA->LiveBlocks.size(); i != e; ++i) { - const SplitAnalysis::BlockInfo &BI = SA->LiveBlocks[i]; - IndexPair &IP = Ranges[i]; - - // Skip interference-free blocks. - if (IntI.start() >= BI.Stop) - continue; - - // First interference in block. - if (BI.LiveIn) { - IntI.advanceTo(BI.Start); - if (!IntI.valid()) - break; - if (IntI.start() >= BI.Stop) - continue; - if (!IP.first.isValid() || IntI.start() < IP.first) - IP.first = IntI.start(); - } - - // Last interference in block. - if (BI.LiveOut) { - IntI.advanceTo(BI.Stop); - if (!IntI.valid() || IntI.start() >= BI.Stop) - --IntI; - if (IntI.stop() <= BI.Start) - continue; - if (!IP.second.isValid() || IntI.stop() > IP.second) - IP.second = IntI.stop(); - } - } - } -} - /// calcSplitConstraints - Fill out the SplitConstraints vector based on the -/// interference pattern in Intf. Return the static cost of this split, -/// assuming that all preferences in SplitConstraints are met. -float RAGreedy::calcSplitConstraints(const SmallVectorImpl &Intf) { +/// interference pattern in Physreg and its aliases. Return the static cost of +/// this split, assuming that all preferences in SplitConstraints are met. +float RAGreedy::calcSplitConstraints(unsigned PhysReg) { + InterferenceCache::Cursor Intf(IntfCache, PhysReg); + // Reset interference dependent info. SplitConstraints.resize(SA->LiveBlocks.size()); float StaticCost = 0; for (unsigned i = 0, e = SA->LiveBlocks.size(); i != e; ++i) { SplitAnalysis::BlockInfo &BI = SA->LiveBlocks[i]; SpillPlacement::BlockConstraint &BC = SplitConstraints[i]; - IndexPair IP = Intf[i]; BC.Number = BI.MBB->getNumber(); + Intf.moveToBlock(BC.Number); BC.Entry = (BI.Uses && BI.LiveIn) ? SpillPlacement::PrefReg : SpillPlacement::DontCare; BC.Exit = (BI.Uses && BI.LiveOut) ? SpillPlacement::PrefReg : SpillPlacement::DontCare; + if (!Intf.hasInterference()) + continue; + // Number of spill code instructions to insert. unsigned Ins = 0; // Interference for the live-in value. - if (IP.first.isValid()) { - if (IP.first <= BI.Start) + if (BI.LiveIn) { + if (Intf.first() <= BI.Start) BC.Entry = SpillPlacement::MustSpill, Ins += BI.Uses; else if (!BI.Uses) BC.Entry = SpillPlacement::PrefSpill; - else if (IP.first < BI.FirstUse) + else if (Intf.first() < BI.FirstUse) BC.Entry = SpillPlacement::PrefSpill, ++Ins; - else if (IP.first < (BI.LiveThrough ? BI.LastUse : BI.Kill)) + else if (Intf.first() < (BI.LiveThrough ? BI.LastUse : BI.Kill)) ++Ins; } // Interference for the live-out value. - if (IP.second.isValid()) { - if (IP.second >= BI.LastSplitPoint) + if (BI.LiveOut) { + if (Intf.last() >= BI.LastSplitPoint) BC.Exit = SpillPlacement::MustSpill, Ins += BI.Uses; else if (!BI.Uses) BC.Exit = SpillPlacement::PrefSpill; - else if (IP.second > BI.LastUse) + else if (Intf.last() > BI.LastUse) BC.Exit = SpillPlacement::PrefSpill, ++Ins; - else if (IP.second > (BI.LiveThrough ? BI.FirstUse : BI.Def)) + else if (Intf.last() > (BI.LiveThrough ? BI.FirstUse : BI.Def)) ++Ins; } @@ -553,10 +508,7 @@ dbgs() << ".\n"; }); - // First compute interference ranges in the live blocks. - SmallVector InterferenceRanges; - mapGlobalInterference(PhysReg, InterferenceRanges); - + InterferenceCache::Cursor Intf(IntfCache, PhysReg); LiveRangeEdit LREdit(VirtReg, NewVRegs, this); SE->reset(LREdit); @@ -573,20 +525,21 @@ if (!BI.LiveOut || !RegOut) continue; - IndexPair &IP = InterferenceRanges[i]; + Intf.moveToBlock(BI.MBB->getNumber()); DEBUG(dbgs() << "BB#" << BI.MBB->getNumber() << " -> EB#" << Bundles->getBundle(BI.MBB->getNumber(), 1) << " [" << BI.Start << ';' << BI.LastSplitPoint << '-' - << BI.Stop << ") intf [" << IP.first << ';' << IP.second + << BI.Stop << ") intf [" << Intf.first() << ';' << Intf.last() << ')'); // The interference interval should either be invalid or overlap MBB. - assert((!IP.first.isValid() || IP.first < BI.Stop) && "Bad interference"); - assert((!IP.second.isValid() || IP.second > BI.Start) + assert((!Intf.hasInterference() || Intf.first() < BI.Stop) + && "Bad interference"); + assert((!Intf.hasInterference() || Intf.last() > BI.Start) && "Bad interference"); // Check interference leaving the block. - if (!IP.second.isValid()) { + if (!Intf.hasInterference()) { // Block is interference-free. DEBUG(dbgs() << ", no interference"); if (!BI.Uses) { @@ -615,9 +568,9 @@ } // Block has interference. - DEBUG(dbgs() << ", interference to " << IP.second); + DEBUG(dbgs() << ", interference to " << Intf.last()); - if (!BI.LiveThrough && IP.second <= BI.Def) { + if (!BI.LiveThrough && Intf.last() <= BI.Def) { // The interference doesn't reach the outgoing segment. DEBUG(dbgs() << " doesn't affect def from " << BI.Def << '\n'); SE->useIntv(BI.Def, BI.Stop); @@ -629,16 +582,16 @@ // No uses in block, avoid interference by reloading as late as possible. DEBUG(dbgs() << ", no uses.\n"); SlotIndex SegStart = SE->enterIntvAtEnd(*BI.MBB); - assert(SegStart >= IP.second && "Couldn't avoid interference"); + assert(SegStart >= Intf.last() && "Couldn't avoid interference"); continue; } - if (IP.second.getBoundaryIndex() < BI.LastUse) { + if (Intf.last().getBoundaryIndex() < BI.LastUse) { // There are interference-free uses at the end of the block. // Find the first use that can get the live-out register. SmallVectorImpl::const_iterator UI = std::lower_bound(SA->UseSlots.begin(), SA->UseSlots.end(), - IP.second.getBoundaryIndex()); + Intf.last().getBoundaryIndex()); assert(UI != SA->UseSlots.end() && "Couldn't find last use"); SlotIndex Use = *UI; assert(Use <= BI.LastUse && "Couldn't find last use"); @@ -646,7 +599,7 @@ if (Use.getBaseIndex() <= BI.LastSplitPoint) { DEBUG(dbgs() << ", free use at " << Use << ".\n"); SlotIndex SegStart = SE->enterIntvBefore(Use); - assert(SegStart >= IP.second && "Couldn't avoid interference"); + assert(SegStart >= Intf.last() && "Couldn't avoid interference"); assert(SegStart < BI.LastSplitPoint && "Impossible split point"); SE->useIntv(SegStart, BI.Stop); continue; @@ -656,7 +609,7 @@ // Interference is after the last use. DEBUG(dbgs() << " after last use.\n"); SlotIndex SegStart = SE->enterIntvAtEnd(*BI.MBB); - assert(SegStart >= IP.second && "Couldn't avoid interference"); + assert(SegStart >= Intf.last() && "Couldn't avoid interference"); } // Now all defs leading to live bundles are handled, do everything else. @@ -670,14 +623,13 @@ continue; // We have an incoming register. Check for interference. - IndexPair &IP = InterferenceRanges[i]; - + Intf.moveToBlock(BI.MBB->getNumber()); DEBUG(dbgs() << "EB#" << Bundles->getBundle(BI.MBB->getNumber(), 0) << " -> BB#" << BI.MBB->getNumber() << " [" << BI.Start << ';' << BI.LastSplitPoint << '-' << BI.Stop << ')'); // Check interference entering the block. - if (!IP.first.isValid()) { + if (!Intf.hasInterference()) { // Block is interference-free. DEBUG(dbgs() << ", no interference"); if (!BI.Uses) { @@ -724,9 +676,9 @@ } // Block has interference. - DEBUG(dbgs() << ", interference from " << IP.first); + DEBUG(dbgs() << ", interference from " << Intf.first()); - if (!BI.LiveThrough && IP.first >= BI.Kill) { + if (!BI.LiveThrough && Intf.first() >= BI.Kill) { // The interference doesn't reach the outgoing segment. DEBUG(dbgs() << " doesn't affect kill at " << BI.Kill << '\n'); SE->useIntv(BI.Start, BI.Kill); @@ -737,20 +689,20 @@ // No uses in block, avoid interference by spilling as soon as possible. DEBUG(dbgs() << ", no uses.\n"); SlotIndex SegEnd = SE->leaveIntvAtTop(*BI.MBB); - assert(SegEnd <= IP.first && "Couldn't avoid interference"); + assert(SegEnd <= Intf.first() && "Couldn't avoid interference"); continue; } - if (IP.first.getBaseIndex() > BI.FirstUse) { + if (Intf.first().getBaseIndex() > BI.FirstUse) { // There are interference-free uses at the beginning of the block. // Find the last use that can get the register. SmallVectorImpl::const_iterator UI = std::lower_bound(SA->UseSlots.begin(), SA->UseSlots.end(), - IP.first.getBaseIndex()); + Intf.first().getBaseIndex()); assert(UI != SA->UseSlots.begin() && "Couldn't find first use"); SlotIndex Use = (--UI)->getBoundaryIndex(); DEBUG(dbgs() << ", free use at " << *UI << ".\n"); SlotIndex SegEnd = SE->leaveIntvAfter(Use); - assert(SegEnd <= IP.first && "Couldn't avoid interference"); + assert(SegEnd <= Intf.first() && "Couldn't avoid interference"); SE->useIntv(BI.Start, SegEnd); continue; } @@ -758,7 +710,7 @@ // Interference is before the first use. DEBUG(dbgs() << " before first use.\n"); SlotIndex SegEnd = SE->leaveIntvAtTop(*BI.MBB); - assert(SegEnd <= IP.first && "Couldn't avoid interference"); + assert(SegEnd <= Intf.first() && "Couldn't avoid interference"); } SE->closeIntv(); @@ -785,8 +737,7 @@ GlobalCand.resize(Cand+1); GlobalCand[Cand].PhysReg = PhysReg; - mapGlobalInterference(PhysReg, GlobalCand[Cand].Interference); - float Cost = calcSplitConstraints(GlobalCand[Cand].Interference); + float Cost = calcSplitConstraints(PhysReg); DEBUG(dbgs() << PrintReg(PhysReg, TRI) << "\tstatic = " << Cost); if (BestReg && Cost >= BestCost) { DEBUG(dbgs() << " higher.\n"); @@ -1213,6 +1164,7 @@ SE.reset(new SplitEditor(*SA, *LIS, *VRM, *DomTree)); LRStage.clear(); LRStage.resize(MRI->getNumVirtRegs()); + IntfCache.init(MF, &PhysReg2LiveUnion[0], Indexes, TRI); allocatePhysRegs(); addMBBLiveIns(MF); From bruno.cardoso at gmail.com Sat Apr 2 01:13:36 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Sat, 2 Apr 2011 03:13:36 -0300 Subject: [llvm-commits] MIPS patch In-Reply-To: References: Message-ID: LGTM! :) On Fri, Apr 1, 2011 at 7:36 PM, Akira Hatanaka wrote: > This patch moves transformation of JmpLink and related nodes done during > instruction selection to Legalize. > > Index: lib/Target/Mips/MipsISelDAGToDAG.cpp > =================================================================== > --- lib/Target/Mips/MipsISelDAGToDAG.cpp? (revision 128742) > +++ lib/Target/Mips/MipsISelDAGToDAG.cpp? (working copy) > @@ -122,7 +122,8 @@ > ???? if ((Addr.getOpcode() == ISD::TargetGlobalAddress) || > ???????? (Addr.getOpcode() == ISD::TargetConstantPool) || > ???????? (Addr.getOpcode() == ISD::TargetJumpTable) || > -??????? (Addr.getOpcode() == ISD::TargetBlockAddress)) { > +??????? (Addr.getOpcode() == ISD::TargetBlockAddress) || > +??????? (Addr.getOpcode() == ISD::TargetExternalSymbol)) { > ?????? Base?? = CurDAG->getRegister(Mips::GP, MVT::i32); > ?????? Offset = Addr; > ?????? return true; > @@ -444,61 +445,6 @@ > ???????? return ResNode; > ?????? // Other cases are autogenerated. > ?????? break; > - > -??? /// Handle direct and indirect calls when using PIC. On PIC, when > -??? /// GOT is smaller than about 64k (small code) the GA target is > -??? /// loaded with only one instruction. Otherwise GA's target must > -??? /// be loaded with 3 instructions. > -??? case MipsISD::JmpLink: { > -????? if (TM.getRelocationModel() == Reloc::PIC_) { > -??????? unsigned LastOpNum = Node->getNumOperands()-1; > - > -??????? SDValue Chain? = Node->getOperand(0); > -??????? SDValue Callee = Node->getOperand(1); > -??????? SDValue InFlag; > - > -??????? // Skip the incomming flag if present > -??????? if (Node->getOperand(LastOpNum).getValueType() == MVT::Glue) > -????????? LastOpNum--; > - > -??????? if ( (isa(Callee)) || > -???????????? (isa(Callee)) ) > -??????? { > -????????? /// Direct call for global addresses and external symbols > -????????? SDValue GPReg = CurDAG->getRegister(Mips::GP, MVT::i32); > - > -????????? // Use load to get GOT target > -????????? SDValue Ops[] = { Callee, GPReg, Chain }; > -????????? SDValue Load = SDValue(CurDAG->getMachineNode(Mips::LW, dl, > MVT::i32, > -???????????????????????????????????? MVT::Other, Ops, 3), 0); > -????????? Chain = Load.getValue(1); > - > -????????? // Call target must be on T9 > -????????? Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Load, InFlag); > -??????? } else > -????????? /// Indirect call > -????????? Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Callee, > InFlag); > - > -??????? // Map the JmpLink operands to JALR > -??????? SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Glue); > -??????? SmallVector Ops; > -??????? Ops.push_back(CurDAG->getRegister(Mips::T9, MVT::i32)); > - > -??????? for (unsigned i = 2, e = LastOpNum+1; i != e; ++i) > -????????? Ops.push_back(Node->getOperand(i)); > -??????? Ops.push_back(Chain); > -??????? Ops.push_back(Chain.getValue(1)); > - > -??????? // Emit Jump and Link Register > -??????? SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, NodeTys, > -????????????????????????????????? &Ops[0], Ops.size()); > - > -??????? // Replace Chain and InFlag > -??????? ReplaceUses(SDValue(Node, 0), SDValue(ResNode, 0)); > -??????? ReplaceUses(SDValue(Node, 1), SDValue(ResNode, 1)); > -??????? return ResNode; > -????? } > -??? } > ?? } > > ?? // Select the default instruction > Index: lib/Target/Mips/MipsISelLowering.cpp > =================================================================== > --- lib/Target/Mips/MipsISelLowering.cpp? (revision 128741) > +++ lib/Target/Mips/MipsISelLowering.cpp? (working copy) > @@ -1201,13 +1201,35 @@ > ?? // direct call is) turn it into a > TargetGlobalAddress/TargetExternalSymbol > ?? // node so that legalize doesn't hack it. > ?? unsigned char OpFlag = IsPIC ? MipsII::MO_GOT_CALL : MipsII::MO_NO_FLAG; > -? if (GlobalAddressSDNode *G = dyn_cast(Callee)) > +? bool LoadSymAddr = false; > + > +? if (GlobalAddressSDNode *G = dyn_cast(Callee)) { > ???? Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, > -??????????????????????????????? getPointerTy(), 0, OpFlag); > -? else if (ExternalSymbolSDNode *S = > dyn_cast(Callee)) > +??????????????????????????????????????? getPointerTy(), 0, OpFlag); > +??? LoadSymAddr = true; > +? } > +? else if (ExternalSymbolSDNode *S = > dyn_cast(Callee)) { > ???? Callee = DAG.getTargetExternalSymbol(S->getSymbol(), > ???????????????????????????????? getPointerTy(), OpFlag); > +??? LoadSymAddr = true; > +? } > > +? // Create nodes that load address of callee and copy it to T9 > +? if (IsPIC) { > +??? if (LoadSymAddr) { > +????? // load callee address > +????? Callee = DAG.getLoad(MVT::i32, dl, Chain, Callee, > +??????????????????????????????????????? MachinePointerInfo::getGOT(), > +??????????????????????????????????????? false, false, 0); > +????? Chain = Callee.getValue(1); > +??? } > + > +??? // copy to T9 > +??? Chain = DAG.getCopyToReg(Chain, dl, Mips::T9, Callee, SDValue(0, 0)); > +??? InFlag = Chain.getValue(1); > +??? Callee = DAG.getRegister(Mips::T9, MVT::i32); > +? } > + > ?? // MipsJmpLink = #chain, #target_address, #opt_in_flags... > ?? //???????????? = Chain, Callee, Reg#1, Reg#2, ... > ?? // > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -- Bruno Cardoso Lopes http://www.brunocardoso.cc From eli.friedman at gmail.com Sat Apr 2 01:50:39 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Fri, 1 Apr 2011 23:50:39 -0700 Subject: [llvm-commits] [llvm] r128759 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/fp-arg-shuffle.ll In-Reply-To: References: <20110402024043.7532F2A6C12C@llvm.org> Message-ID: On Fri, Apr 1, 2011 at 9:14 PM, Cameron Zwarich wrote: > On 2011-04-01, at 8:46 PM, Eli Friedman wrote: > >> The reason why RemoveFromWorklist didn't exist is that you don't need >> it; unlike in IR, you don't have to erase a dead instruction. ?(The >> nature of the DAG datastructure is that a node with no uses is >> automatically dead.) > > That's what I thought at first, but it's apparently not true. If you remove that extra code from my patch, then another ARM test case fails because a store has a dead user of its chain value. There is special logic all throughout DAGCombiner to explicitly kill dead nodes and remove them from the worklist. You're right; I've never made a change that had an issue like that, but I don't think I've had changes with explicit calls to ReplaceAllUsesOfValueWith. The invariants in ISel tend to be messy... -Eli From Brice.Lin at gmail.com Sat Apr 2 02:09:48 2011 From: Brice.Lin at gmail.com (Brice Lin) Date: Sat, 02 Apr 2011 07:09:48 -0000 Subject: [llvm-commits] [poolalloc] r128766 - in /poolalloc/trunk/lib/AssistDS: TypeChecks.cpp TypeChecks.h Message-ID: <20110402070948.818C72A6C12C@llvm.org> Author: bglin2 Date: Sat Apr 2 02:09:48 2011 New Revision: 128766 URL: http://llvm.org/viewvc/llvm-project?rev=128766&view=rev Log: Initial commit for runtime type check insertion pass. Added: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp poolalloc/trunk/lib/AssistDS/TypeChecks.h Added: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=128766&view=auto ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (added) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Sat Apr 2 02:09:48 2011 @@ -0,0 +1,133 @@ +//===------------ TypeChecks.cpp - Insert runtime type checks -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass inserts checks to enforce type safety during runtime. +// +//===----------------------------------------------------------------------===// + +#include "TypeChecks.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Module.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/Support/InstIterator.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +char TypeChecks::ID = 0; +static RegisterPass TC("typechecks", "Insert runtime type checks", false, true); + +// Incorporate one type and all of its subtypes into the collection of used types. +void TypeChecks::IncorporateType(const Type *Ty) { + // If Ty doesn't already exist in the used types map, add it now. Otherwise, return. + if (UsedTypes[Ty] != 0) { + return; + } + + UsedTypes[Ty] = maxType; + ++maxType; + + // Make sure to add any types this type references now. + for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); I != E; ++I) { + IncorporateType(*I); + } +} + +// Incorporate all of the types used by this value. +void TypeChecks::IncorporateValue(const Value *V) { + IncorporateType(V->getType()); + UsedValues[V] = V->getType(); + + // If this is a constant, it could be using other types. + if (const Constant *C = dyn_cast(V)) { + if (!isa(C)) { + for (User::const_op_iterator OI = C->op_begin(), OE = C->op_end(); OI != OE; ++OI) { + IncorporateValue(*OI); + } + } + } +} + +bool TypeChecks::runOnModule(Module &M) { + // Flags whether we modified the module. + bool modified = false; + + UsedTypes.clear(); // Reset if run multiple times. + maxType = 1; + + // Loop over global variables, incorporating their types. + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { + IncorporateType(I->getType()); + if (I->hasInitializer()) { + IncorporateValue(I->getInitializer()); + } + } + + for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) { + IncorporateType(MI->getType()); + Function &F = *MI; + + // Loop over all of the instructions in the function, adding their return type as well as the types of their operands. + for (inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE; ++II) { + Instruction &I = *II; + + IncorporateType(I.getType()); // Incorporate the type of the instruction. + for (User::op_iterator OI = I.op_begin(), OE = I.op_end(); OI != OE; ++OI) { + IncorporateValue(*OI); // Insert instruction operand types. + } + + if (StoreInst *SI = dyn_cast(&I)) { + modified |= visitStoreInst(M, *SI); + } + } + } + + return modified; +} + +// Print the types found in the module. If the optional Module parameter is +// passed in, then the types are printed symbolically if possible, using the +// symbol table from the module. +void TypeChecks::print(raw_ostream &OS, const Module *M) const { + OS << "Types in use by this module:\n"; + for (std::map::const_iterator I = UsedTypes.begin(), E = UsedTypes.end(); I != E; ++I) { + OS << " "; + WriteTypeSymbolic(OS, I->first, M); + OS << '\n'; + } + + OS << "\nValues in use by this module:\n"; + for (std::map::const_iterator I = UsedValues.begin(), E = UsedValues.end(); I != E; ++I) { + OS << " " << I->first << " = "; + WriteTypeSymbolic(OS, I->second, M); + OS << '\n'; + } + + OS << "\nNumber of types: " << maxType << '\n'; +} + +// Insert runtime checks before all store instructions. +bool TypeChecks::visitStoreInst(Module &M, StoreInst &SI) { + const Type *Int8Ty = IntegerType::getInt8Ty(M.getContext()); + const Type *Int32Ty = IntegerType::getInt32Ty(M.getContext()); + PointerType *VoidPtrTy = PointerType::getUnqual(Int8Ty); + + CastInst *BCI = BitCastInst::CreatePointerCast(SI.getPointerOperand(), VoidPtrTy, "", &SI); + + std::vector Args; + Args.push_back(BCI); + Args.push_back(ConstantInt::get(Int32Ty, UsedTypes[SI.getOperand(0)->getType()])); // SI.getValueOperand() + + // Create the call to the runtime check, and place it before the store instruction. + Constant *F = M.getOrInsertFunction("trackStoreInst", Int8Ty, VoidPtrTy, Int32Ty, NULL); + CallInst::Create(F, Args.begin(), Args.end(), "", &SI); + + return true; +} Added: poolalloc/trunk/lib/AssistDS/TypeChecks.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.h?rev=128766&view=auto ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.h (added) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.h Sat Apr 2 02:09:48 2011 @@ -0,0 +1,58 @@ +//===------------- TypeChecks.h - Insert runtime type checks --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass inserts checks to enforce type safety during runtime. +// +//===----------------------------------------------------------------------===// + +#ifndef TYPE_CHECKS_H +#define TYPE_CHECKS_H + +#include "llvm/Instructions.h" +#include "llvm/Pass.h" + +#include + +namespace llvm { + +class Type; +class Value; + +class TypeChecks : public ModulePass { +private: + unsigned int maxType; + std::map UsedTypes; + std::map UsedValues; + + // Incorporate one type and all of its subtypes into the collection of used types. + void IncorporateType(const Type *Ty); + + // Incorporate all of the types used by this value. + void IncorporateValue(const Value *V); + +public: + static char ID; + TypeChecks() : ModulePass(&ID) {} + virtual bool runOnModule(Module &M); + virtual void print(raw_ostream &OS, const Module *M) const; + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + } + + bool visitStoreInst(Module &M, StoreInst &SI); + + // Return the map containing all of the types used in the module. + const std::map &getTypes() const { + return UsedTypes; + } +}; + +} // End llvm namespace + +#endif From clchiou at gmail.com Sat Apr 2 03:51:39 2011 From: clchiou at gmail.com (Che-Liang Chiou) Date: Sat, 02 Apr 2011 08:51:39 -0000 Subject: [llvm-commits] [llvm] r128767 - in /llvm/trunk: lib/Target/PTX/PTXInstrInfo.cpp lib/Target/PTX/PTXInstrInfo.td test/CodeGen/PTX/setp.ll Message-ID: <20110402085139.7F0582A6C12C@llvm.org> Author: clchiou Date: Sat Apr 2 03:51:39 2011 New Revision: 128767 URL: http://llvm.org/viewvc/llvm-project?rev=128767&view=rev Log: ptx: support setp's 4-operand format Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp llvm/trunk/lib/Target/PTX/PTXInstrInfo.td llvm/trunk/test/CodeGen/PTX/setp.ll Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp?rev=128767&r1=128766&r2=128767&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp Sat Apr 2 03:51:39 2011 @@ -130,42 +130,37 @@ bool PTXInstrInfo:: SubsumesPredicate(const SmallVectorImpl &Pred1, const SmallVectorImpl &Pred2) const { - // TODO Implement SubsumesPredicate - // Returns true if the first specified predicate subsumes the second, - // e.g. GE subsumes GT. - return false; + const MachineOperand &PredReg1 = Pred1[0]; + const MachineOperand &PredReg2 = Pred2[0]; + if (PredReg1.getReg() != PredReg2.getReg()) + return false; + + const MachineOperand &PredOp1 = Pred1[1]; + const MachineOperand &PredOp2 = Pred2[1]; + if (PredOp1.getImm() != PredOp2.getImm()) + return false; + + return true; } bool PTXInstrInfo:: DefinesPredicate(MachineInstr *MI, std::vector &Pred) const { - // TODO Implement DefinesPredicate - // If the specified instruction defines any predicate or condition code - // register(s) used for predication, returns true as well as the definition - // predicate(s) by reference. - - switch (MI->getOpcode()) { - default: - return false; - case PTX::SETPEQu32rr: - case PTX::SETPEQu32ri: - case PTX::SETPNEu32rr: - case PTX::SETPNEu32ri: - case PTX::SETPLTu32rr: - case PTX::SETPLTu32ri: - case PTX::SETPLEu32rr: - case PTX::SETPLEu32ri: - case PTX::SETPGTu32rr: - case PTX::SETPGTu32ri: - case PTX::SETPGEu32rr: - case PTX::SETPGEu32ri: { - const MachineOperand &MO = MI->getOperand(0); - assert(MO.isReg() && RI.getRegClass(MO.getReg()) == &PTX::PredsRegClass); - Pred.push_back(MO); - Pred.push_back(MachineOperand::CreateImm(PTX::PRED_NORMAL)); - return true; - } - } + // If an instruction sets a predicate register, it defines a predicate. + + // TODO supprot 5-operand format of setp instruction + + if (MI->getNumOperands() < 1) + return false; + + const MachineOperand &MO = MI->getOperand(0); + + if (!MO.isReg() || RI.getRegClass(MO.getReg()) != &PTX::PredsRegClass) + return false; + + Pred.push_back(MO); + Pred.push_back(MachineOperand::CreateImm(PTX::PRED_NORMAL)); + return true; } // branch support Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.td?rev=128767&r1=128766&r2=128767&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Sat Apr 2 03:51:39 2011 @@ -325,14 +325,66 @@ multiclass PTX_SETP { + // TODO 1. support floating-point 2. support 5-operand format: p|q, a, b, c + def rr - : InstPTX<(outs Preds:$d), (ins RC:$a, RC:$b), - !strconcat("setp.", cmpstr, ".", regclsname, "\t$d, $a, $b"), - [(set Preds:$d, (setcc RC:$a, RC:$b, cmp))]>; + : InstPTX<(outs Preds:$p), (ins RC:$a, RC:$b), + !strconcat("setp.", cmpstr, ".", regclsname, "\t$p, $a, $b"), + [(set Preds:$p, (setcc RC:$a, RC:$b, cmp))]>; def ri - : InstPTX<(outs Preds:$d), (ins RC:$a, immcls:$b), - !strconcat("setp.", cmpstr, ".", regclsname, "\t$d, $a, $b"), - [(set Preds:$d, (setcc RC:$a, imm:$b, cmp))]>; + : InstPTX<(outs Preds:$p), (ins RC:$a, immcls:$b), + !strconcat("setp.", cmpstr, ".", regclsname, "\t$p, $a, $b"), + [(set Preds:$p, (setcc RC:$a, imm:$b, cmp))]>; + + def rr_and_r + : InstPTX<(outs Preds:$p), (ins RC:$a, RC:$b, Preds:$c), + !strconcat("setp.", cmpstr, ".and.", regclsname, "\t$p, $a, $b, $c"), + [(set Preds:$p, (and (setcc RC:$a, RC:$b, cmp), Preds:$c))]>; + def ri_and_r + : InstPTX<(outs Preds:$p), (ins RC:$a, immcls:$b, Preds:$c), + !strconcat("setp.", cmpstr, ".and.", regclsname, "\t$p, $a, $b, $c"), + [(set Preds:$p, (and (setcc RC:$a, imm:$b, cmp), Preds:$c))]>; + def rr_or_r + : InstPTX<(outs Preds:$p), (ins RC:$a, RC:$b, Preds:$c), + !strconcat("setp.", cmpstr, ".or.", regclsname, "\t$p, $a, $b, $c"), + [(set Preds:$p, (or (setcc RC:$a, RC:$b, cmp), Preds:$c))]>; + def ri_or_r + : InstPTX<(outs Preds:$p), (ins RC:$a, immcls:$b, Preds:$c), + !strconcat("setp.", cmpstr, ".or.", regclsname, "\t$p, $a, $b, $c"), + [(set Preds:$p, (or (setcc RC:$a, imm:$b, cmp), Preds:$c))]>; + def rr_xor_r + : InstPTX<(outs Preds:$p), (ins RC:$a, RC:$b, Preds:$c), + !strconcat("setp.", cmpstr, ".xor.", regclsname, "\t$p, $a, $b, $c"), + [(set Preds:$p, (xor (setcc RC:$a, RC:$b, cmp), Preds:$c))]>; + def ri_xor_r + : InstPTX<(outs Preds:$p), (ins RC:$a, immcls:$b, Preds:$c), + !strconcat("setp.", cmpstr, ".xor.", regclsname, "\t$p, $a, $b, $c"), + [(set Preds:$p, (xor (setcc RC:$a, imm:$b, cmp), Preds:$c))]>; + + def rr_and_not_r + : InstPTX<(outs Preds:$p), (ins RC:$a, RC:$b, Preds:$c), + !strconcat("setp.", cmpstr, ".and.", regclsname, "\t$p, $a, $b, !$c"), + [(set Preds:$p, (and (setcc RC:$a, RC:$b, cmp), (not Preds:$c)))]>; + def ri_and_not_r + : InstPTX<(outs Preds:$p), (ins RC:$a, immcls:$b, Preds:$c), + !strconcat("setp.", cmpstr, ".and.", regclsname, "\t$p, $a, $b, !$c"), + [(set Preds:$p, (and (setcc RC:$a, imm:$b, cmp), (not Preds:$c)))]>; + def rr_or_not_r + : InstPTX<(outs Preds:$p), (ins RC:$a, RC:$b, Preds:$c), + !strconcat("setp.", cmpstr, ".or.", regclsname, "\t$p, $a, $b, !$c"), + [(set Preds:$p, (or (setcc RC:$a, RC:$b, cmp), (not Preds:$c)))]>; + def ri_or_not_r + : InstPTX<(outs Preds:$p), (ins RC:$a, immcls:$b, Preds:$c), + !strconcat("setp.", cmpstr, ".or.", regclsname, "\t$p, $a, $b, !$c"), + [(set Preds:$p, (or (setcc RC:$a, imm:$b, cmp), (not Preds:$c)))]>; + def rr_xor_not_r + : InstPTX<(outs Preds:$p), (ins RC:$a, RC:$b, Preds:$c), + !strconcat("setp.", cmpstr, ".xor.", regclsname, "\t$p, $a, $b, !$c"), + [(set Preds:$p, (xor (setcc RC:$a, RC:$b, cmp), (not Preds:$c)))]>; + def ri_xor_not_r + : InstPTX<(outs Preds:$p), (ins RC:$a, immcls:$b, Preds:$c), + !strconcat("setp.", cmpstr, ".xor.", regclsname, "\t$p, $a, $b, !$c"), + [(set Preds:$p, (xor (setcc RC:$a, imm:$b, cmp), (not Preds:$c)))]>; } multiclass PTX_LD { @@ -602,6 +654,10 @@ // defm LDp : PTX_LD_ALL<"ld.param", load_parameter>; // TODO: Do something with st.param if/when it is needed. +def CVT_pred_u32 + : InstPTX<(outs Preds:$d), (ins RRegu32:$a), "cvt.pred.u32\t$d, $a", + [(set Preds:$d, (trunc RRegu32:$a))]>; + def CVT_u32_pred : InstPTX<(outs RRegu32:$d), (ins Preds:$a), "cvt.u32.pred\t$d, $a", [(set RRegu32:$d, (zext Preds:$a))]>; Modified: llvm/trunk/test/CodeGen/PTX/setp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/setp.ll?rev=128767&r1=128766&r2=128767&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PTX/setp.ll (original) +++ llvm/trunk/test/CodeGen/PTX/setp.ll Sat Apr 2 03:51:39 2011 @@ -107,3 +107,28 @@ %z = zext i1 %p to i32 ret i32 %z } + +define ptx_device i32 @test_setp_4_op_format_1(i32 %x, i32 %y, i32 %u, i32 %v) { +; CHECK: setp.gt.u32 p0, r3, r4; +; CHECK-NEXT: setp.eq.and.u32 p0, r1, r2, p0; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %c = icmp eq i32 %x, %y + %d = icmp ugt i32 %u, %v + %e = and i1 %c, %d + %z = zext i1 %e to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_4_op_format_2(i32 %x, i32 %y, i32 %w) { +; CHECK: cvt.pred.u32 p0, r3; +; CHECK-NEXT: setp.eq.and.u32 p0, r1, r2, !p0; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %c = trunc i32 %w to i1 + %d = icmp eq i32 %x, %y + %e = xor i1 %c, 1 + %f = and i1 %d, %e + %z = zext i1 %f to i32 + ret i32 %z +} From 6yearold at gmail.com Sat Apr 2 07:14:53 2011 From: 6yearold at gmail.com (arrowdodger) Date: Sat, 2 Apr 2011 16:14:53 +0400 Subject: [llvm-commits] [PATCH][CMake] Handle turning off LLVM_ENABLE_FFI. Message-ID: If someone first configure build with LLVM_ENABLE_FFI=1 and then turn it off, the build will fail in lib/ExecutionEngine/Interpreter because Interpreter will try still to #include , but there are no include_directories(${FFI_INCLUDE_DIR}) now. This patch unset()'s HAVE_FFI_H and HAVE_FFI_FFI_H from cache file if LLVM_ENABLE_FFI=0. This forces CMake to update config.h. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110402/641bcc73/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: config-ix.ffi.patch Type: text/x-patch Size: 578 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110402/641bcc73/attachment.bin From ofv at wanadoo.es Sat Apr 2 08:21:13 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Sat, 02 Apr 2011 13:21:13 -0000 Subject: [llvm-commits] [llvm] r128769 - /llvm/trunk/cmake/config-ix.cmake Message-ID: <20110402132113.5A5CE2A6C12C@llvm.org> Author: ofv Date: Sat Apr 2 08:21:12 2011 New Revision: 128769 URL: http://llvm.org/viewvc/llvm-project?rev=128769&view=rev Log: Handle changing of LLVM_ENABLE_FFI. If someone first configure build with LLVM_ENABLE_FFI=1 and then turn it off, the build will fail in lib/ExecutionEngine/Interpreter because Interpreter will try still to #include , but there are no include_directories(${FFI_INCLUDE_DIR}) now. This patch unset()'s HAVE_FFI_H and HAVE_FFI_FFI_H from cache file if LLVM_ENABLE_FFI=0. This forces CMake to update config.h. Patch by arrowdodger! Modified: llvm/trunk/cmake/config-ix.cmake Modified: llvm/trunk/cmake/config-ix.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=128769&r1=128768&r2=128769&view=diff ============================================================================== --- llvm/trunk/cmake/config-ix.cmake (original) +++ llvm/trunk/cmake/config-ix.cmake Sat Apr 2 08:21:12 2011 @@ -271,6 +271,10 @@ check_symbol_exists(ffi_call ${FFI_HEADER} HAVE_FFI_CALL) list(REMOVE_ITEM CMAKE_REQUIRED_INCLUDES ${FFI_INCLUDE_PATH}) list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES ${FFI_LIBRARY_PATH}) +else() + unset(HAVE_FFI_FFI_H CACHE) + unset(HAVE_FFI_H CACHE) + unset(HAVE_FFI_CALL CACHE) endif( LLVM_ENABLE_FFI ) # Define LLVM_MULTITHREADED if gcc atomic builtins exists. From ofv at wanadoo.es Sat Apr 2 08:26:26 2011 From: ofv at wanadoo.es (=?utf-8?Q?=C3=93scar_Fuentes?=) Date: Sat, 02 Apr 2011 15:26:26 +0200 Subject: [llvm-commits] [PATCH][CMake] Handle turning off LLVM_ENABLE_FFI. References: Message-ID: <87pqp4ss1p.fsf@wanadoo.es> arrowdodger <6yearold at gmail.com> writes: > If someone first configure build with LLVM_ENABLE_FFI=1 and then turn it > off, the build will fail in lib/ExecutionEngine/Interpreter because > Interpreter will try still to #include , but there are no > include_directories(${FFI_INCLUDE_DIR}) now. > This patch unset()'s HAVE_FFI_H and HAVE_FFI_FFI_H from cache file if > LLVM_ENABLE_FFI=0. This forces CMake to update config.h. Applied. Thanks. From baldrick at free.fr Sat Apr 2 12:08:23 2011 From: baldrick at free.fr (Duncan Sands) Date: Sat, 02 Apr 2011 17:08:23 -0000 Subject: [llvm-commits] [dragonegg] r128772 - in /dragonegg/trunk: Backend.cpp Constants.cpp Convert.cpp DefaultABI.cpp Internals.h Types.cpp x86/Target.cpp Message-ID: <20110402170824.173382A6C12C@llvm.org> Author: baldrick Date: Sat Apr 2 12:08:23 2011 New Revision: 128772 URL: http://llvm.org/viewvc/llvm-project?rev=128772&view=rev Log: See if the alignment assertion in ConvertInitializer now survives the buildbots. While there, factor fatal error handling code. Modified: dragonegg/trunk/Backend.cpp dragonegg/trunk/Constants.cpp dragonegg/trunk/Convert.cpp dragonegg/trunk/DefaultABI.cpp dragonegg/trunk/Internals.h dragonegg/trunk/Types.cpp dragonegg/trunk/x86/Target.cpp Modified: dragonegg/trunk/Backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Backend.cpp?rev=128772&r1=128771&r2=128772&view=diff ============================================================================== --- dragonegg/trunk/Backend.cpp (original) +++ dragonegg/trunk/Backend.cpp Sat Apr 2 12:08:23 2011 @@ -38,8 +38,6 @@ #include "llvm/Assembly/PrintModulePass.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/CodeGen/RegAllocRegistry.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FormattedStream.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/StandardPasses.h" #include "llvm/Target/SubtargetFeature.h" @@ -738,10 +736,8 @@ InitializeOutputStreams(false); if (TheTarget->addPassesToEmitFile(*PM, FormattedOutStream, TargetMachine::CGFT_AssemblyFile, - OptLevel, DisableVerify)) { - errs() << "Error interfacing to target machine!\n"; - exit(1); - } + OptLevel, DisableVerify)) + DieAbjectly("Error interfacing to target machine!"); } if (HasPerFunctionPasses) { @@ -841,10 +837,8 @@ InitializeOutputStreams(false); if (TheTarget->addPassesToEmitFile(*PM, FormattedOutStream, TargetMachine::CGFT_AssemblyFile, - OptLevel, DisableVerify)) { - errs() << "Error interfacing to target machine!\n"; - exit(1); - } + OptLevel, DisableVerify)) + DieAbjectly("Error interfacing to target machine!"); } } @@ -1210,15 +1204,13 @@ return V; #ifdef ENABLE_CHECKING - // Check that we are not being given an automatic variable. + // Check that we are not being given an automatic variable or a type or label. // A weak alias has TREE_PUBLIC set but not the other bits. - if (TREE_CODE(decl) == PARM_DECL || TREE_CODE(decl) == RESULT_DECL - || (TREE_CODE(decl) == VAR_DECL && !TREE_STATIC(decl) && - !TREE_PUBLIC(decl) && !DECL_EXTERNAL(decl) && !DECL_REGISTER(decl))) - abort(); - // And that we were not given a type or a label. */ - else if (TREE_CODE(decl) == TYPE_DECL || TREE_CODE(decl) == LABEL_DECL) - abort (); + if (TREE_CODE(decl) == PARM_DECL || TREE_CODE(decl) == RESULT_DECL || + TREE_CODE(decl) == TYPE_DECL || TREE_CODE(decl) == LABEL_DECL || + (TREE_CODE(decl) == VAR_DECL && !TREE_STATIC(decl) && + !TREE_PUBLIC(decl) && !DECL_EXTERNAL(decl) && !DECL_REGISTER(decl))) + DieAbjectly("Cannot make a global for this kind of declaration!", decl); #endif if (errorcount || sorrycount) Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=128772&r1=128771&r2=128772&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Sat Apr 2 12:08:23 2011 @@ -30,7 +30,6 @@ // LLVM headers #include "llvm/GlobalVariable.h" #include "llvm/LLVMContext.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Host.h" #include "llvm/Target/TargetData.h" @@ -288,7 +287,7 @@ switch (Ty->getTypeID()) { default: - llvm_unreachable("Unsupported type!"); + DieAbjectly("Unsupported type!"); case Type::PointerTyID: { // Cast to an integer with the same number of bits and return that. const IntegerType *IntTy = getTargetData().getIntPtrType(Context); @@ -400,7 +399,7 @@ switch (Ty->getTypeID()) { default: - llvm_unreachable("Unsupported type!"); + DieAbjectly("Unsupported type!"); case Type::IntegerTyID: { unsigned BitWidth = Ty->getPrimitiveSizeInBits(); unsigned StoreSize = getTargetData().getTypeStoreSizeInBits(Ty); @@ -1090,9 +1089,7 @@ Constant *Init; switch (TREE_CODE(exp)) { default: - debug_tree(exp); - assert(0 && "Unknown constant to convert!"); - abort(); + DieAbjectly("Unknown constant to convert!", exp); case COMPLEX_CST: case INTEGER_CST: case REAL_CST: @@ -1135,18 +1132,14 @@ if (Ty->isSized()) { uint64_t InitSize = getTargetData().getTypeAllocSizeInBits(Init->getType()); uint64_t TypeSize = getTargetData().getTypeAllocSizeInBits(Ty); - if (InitSize < TypeSize) { - debug_tree(exp); - llvm_unreachable("Constant too small for type!"); - } - if (isInt64(TREE_TYPE(exp), true) && InitSize != TypeSize) { - debug_tree(exp); - llvm_unreachable("Constant too big for type!"); - } - } -// FIXME: This check fails when building libdecnumber (self-host build). -// assert(getTargetData().getABITypeAlignment(Init->getType()) * 8 <= -// TYPE_ALIGN(TREE_TYPE(exp)) && "Constant over aligned!"); + if (InitSize < TypeSize) + DieAbjectly("Constant too small for type!", exp); + if (isInt64(TREE_TYPE(exp), true) && InitSize != TypeSize) + DieAbjectly("Constant too big for type!", exp); + } + if (getTargetData().getABITypeAlignment(Init->getType()) * 8 > + TYPE_ALIGN(TREE_TYPE(exp))) + DieAbjectly("Constant over aligned!", exp); #endif return Init; @@ -1306,9 +1299,7 @@ switch (TREE_CODE(exp)) { default: - debug_tree(exp); - assert(false && "Unknown constant to take the address of!"); - abort(); + DieAbjectly("Unknown constant to take the address of!", exp); case COMPLEX_CST: case FIXED_CST: case INTEGER_CST: Modified: dragonegg/trunk/Convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Convert.cpp?rev=128772&r1=128771&r2=128772&view=diff ============================================================================== --- dragonegg/trunk/Convert.cpp (original) +++ dragonegg/trunk/Convert.cpp Sat Apr 2 12:08:23 2011 @@ -31,7 +31,6 @@ #include "llvm/Module.h" #include "llvm/Support/CFG.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Host.h" #include "llvm/Target/TargetLowering.h" #include "llvm/ADT/Statistic.h" @@ -70,11 +69,6 @@ STATISTIC(NumBasicBlocks, "Number of basic blocks converted"); STATISTIC(NumStatements, "Number of gimple statements converted"); -/// dump - Print a gimple statement to standard error. -void dump(gimple stmt) { - print_gimple_stmt(stderr, stmt, 0, TDF_RAW); -} - /// getINTEGER_CSTVal - Return the specified INTEGER_CST value as a uint64_t. /// uint64_t getINTEGER_CSTVal(tree exp) { @@ -267,7 +261,7 @@ switch (TREE_CODE(decl)) { default: - llvm_unreachable("Unhandled local declaration!"); + DieAbjectly("Unhandled local declaration!", decl); case RESULT_DECL: case VAR_DECL: @@ -1018,8 +1012,7 @@ NameDef->replaceAllUsesWith(UndefValue::get(NameDef->getType())); delete NameDef; } else { - debug_tree(I->first); - llvm_unreachable("SSA name never defined!"); + DieAbjectly("SSA name never defined!", I->first); } } @@ -1133,6 +1126,9 @@ } switch (gimple_code(stmt)) { + default: + DieAbjectly("Unhandled GIMPLE statement during LLVM emission!", stmt); + case GIMPLE_ASM: RenderGIMPLE_ASM(stmt); break; @@ -1177,10 +1173,6 @@ case GIMPLE_SWITCH: RenderGIMPLE_SWITCH(stmt); break; - - default: - dump(stmt); - llvm_unreachable("Unhandled GIMPLE statement during LLVM emission!"); } } @@ -1246,8 +1238,7 @@ switch (TREE_CODE(exp)) { default: - debug_tree(exp); - llvm_unreachable("Unhandled lvalue expression!"); + DieAbjectly("Unhandled lvalue expression!", exp); case PARM_DECL: case VAR_DECL: @@ -1321,11 +1312,6 @@ // ... Utility Functions ... //===----------------------------------------------------------------------===// -void TreeToLLVM::TODO(tree exp) { - if (exp) debug_tree(exp); - llvm_unreachable("Unhandled tree node"); -} - /// CastToAnyType - Cast the specified value to the specified type making no /// assumptions about the types of the arguments. This creates an inferred cast. Value *TreeToLLVM::CastToAnyType(Value *V, bool VisSigned, @@ -1781,11 +1767,8 @@ if (DECL_SIZE(decl) == 0) { // Variable with incomplete type. if (DECL_INITIAL(decl) == 0) return; // Error message was already done; now avoid a crash. - else { - // "An initializer is going to decide the size of this array."?? - TODO(decl); - abort(); - } + else + DieAbjectly("Initializer will decide the size of this array?", decl); } else if (TREE_CODE(DECL_SIZE_UNIT(decl)) == INTEGER_CST) { // Variable of fixed size that goes on the stack. Ty = ConvertType(type); @@ -2451,11 +2434,8 @@ case ARRAY_TYPE: case RECORD_TYPE: default: - if (elt && VEC_length(constructor_elt, elt)) { - // We don't handle elements yet. - - TODO(exp); - } + if (elt && VEC_length(constructor_elt, elt)) + DieAbjectly("We don't handle elements yet!", exp); return 0; case QUAL_UNION_TYPE: case UNION_TYPE: @@ -4560,7 +4540,7 @@ switch(DECL_FUNCTION_CODE(fndecl)) { case BUILT_IN_LOCK_RELEASE_16: // not handled; should use SSE on x86 default: - abort(); + DieAbjectly("Not handled; should use SSE on x86!"); case BUILT_IN_LOCK_RELEASE_1: Ty = Type::getInt8Ty(Context); break; case BUILT_IN_LOCK_RELEASE_2: @@ -5717,7 +5697,7 @@ LValue LV(ConstantPointerNull::get(PTy), 1); return LV; } - llvm_unreachable("Referencing decl that hasn't been laid out"); + DieAbjectly("Referencing decl that hasn't been laid out!", exp); } const Type *Ty = ConvertType(TREE_TYPE(exp)); @@ -5891,17 +5871,14 @@ /// an LLVM constant. Creates no code, only constants. Constant *TreeToLLVM::EmitRegisterConstant(tree reg) { #ifndef NDEBUG - if (!is_gimple_constant(reg)) { - debug_tree(reg); - llvm_unreachable("Not a gimple constant!"); - } + if (!is_gimple_constant(reg)) + DieAbjectly("Not a gimple constant!", reg); #endif assert(is_gimple_reg_type(TREE_TYPE(reg)) && "Not of register type!"); switch (TREE_CODE(reg)) { default: - debug_tree(reg); - llvm_unreachable("Unhandled GIMPLE constant!"); + DieAbjectly("Unhandled GIMPLE constant!", reg); case INTEGER_CST: return EmitIntegerRegisterConstant(reg); @@ -7491,7 +7468,7 @@ switch (region->type) { default: - llvm_unreachable("Unexpected region type!"); + DieAbjectly("Unexpected region type!"); case ERT_ALLOWED_EXCEPTIONS: { // Filter. BasicBlock *Dest = getLabelDeclBlock(region->u.allowed.label); @@ -7751,8 +7728,7 @@ Value *RHS = 0; switch (code) { default: - dump(stmt); - llvm_unreachable("Unhandled GIMPLE assignment!"); + DieAbjectly("Unhandled GIMPLE assignment!", stmt); // Unary expressions. case ABS_EXPR: Modified: dragonegg/trunk/DefaultABI.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/DefaultABI.cpp?rev=128772&r1=128771&r2=128772&view=diff ============================================================================== --- dragonegg/trunk/DefaultABI.cpp (original) +++ dragonegg/trunk/DefaultABI.cpp Sat Apr 2 12:08:23 2011 @@ -160,10 +160,8 @@ else if (const Type* ScalarTy = LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN(type, &Offset)) C.HandleAggregateResultAsScalar(ScalarTy, Offset); - else { - assert(0 && "Unable to determine how to return this aggregate!"); - abort(); - } + else + DieAbjectly("Unable to determine how to return this aggregate!"); } } else { // If the function is returning a struct or union, we pass the pointer to @@ -291,8 +289,7 @@ C.ExitField(); } } else { - assert(0 && "unknown aggregate type!"); - abort(); + DieAbjectly("Unknown aggregate type!"); } } Modified: dragonegg/trunk/Internals.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Internals.h?rev=128772&r1=128771&r2=128772&view=diff ============================================================================== --- dragonegg/trunk/Internals.h (original) +++ dragonegg/trunk/Internals.h Sat Apr 2 12:08:23 2011 @@ -28,6 +28,8 @@ #include "llvm/Intrinsics.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SetVector.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/Support/IRBuilder.h" #include "llvm/Support/TargetFolder.h" @@ -35,6 +37,11 @@ union gimple_statement_d; union tree_node; +extern "C" { +extern void debug_gimple_stmt(union gimple_statement_d *); +extern void debug_tree(union tree_node *); +} + namespace llvm { class Module; class GlobalVariable; @@ -103,6 +110,20 @@ extern Constant* ConvertMetadataStringToGV(const char *str); +inline void DieAbjectly(const char *Message) { + llvm_unreachable(Message); +} + +inline void DieAbjectly(const char *Message, union gimple_statement_d *stmt) { + if (stmt) debug_gimple_stmt(stmt); + DieAbjectly(Message); +} + +inline void DieAbjectly(const char *Message, union tree_node *exp) { + if (exp) debug_tree(exp); + DieAbjectly(Message); +} + /// AddAnnotateAttrsToGlobal - Adds decls that have a /// annotate attribute to a vector to be emitted later. extern void AddAnnotateAttrsToGlobal(GlobalValue *GV, tree_node *decl); @@ -460,8 +481,6 @@ /// the address of the result. LValue EmitLV(tree_node *exp); - void TODO(tree_node *exp = 0); - /// CastToAnyType - Cast the specified value to the specified type regardless /// of the types involved. This is an inferred cast. Value *CastToAnyType (Value *V, bool VSigned, const Type *Ty, bool TySigned); Modified: dragonegg/trunk/Types.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Types.cpp?rev=128772&r1=128771&r2=128772&view=diff ============================================================================== --- dragonegg/trunk/Types.cpp (original) +++ dragonegg/trunk/Types.cpp Sat Apr 2 12:08:23 2011 @@ -78,7 +78,7 @@ errs() << "LLVM: "; Ty->print(errs()); errs() << " (" << LLVMSize << " bits)\n"; - llvm_unreachable("LLVM type size doesn't match GCC type size!"); + DieAbjectly("LLVM type size doesn't match GCC type size!"); } } #endif @@ -561,9 +561,7 @@ switch (TREE_CODE(type)) { default: - fprintf(stderr, "Unknown type to compare:\n"); - debug_tree(type); - abort(); + DieAbjectly("Unknown type to compare!", type); case VOID_TYPE: case BOOLEAN_TYPE: case ENUMERAL_TYPE: @@ -672,8 +670,7 @@ switch (TREE_CODE(type)) { default: - debug_tree(type); - llvm_unreachable("Unknown type to convert!"); + DieAbjectly("Unknown type to convert!", type); case VOID_TYPE: Ty = SET_TYPE_LLVM(type, Type::getVoidTy(Context)); @@ -709,8 +706,7 @@ if ((Ty = GET_TYPE_LLVM(type))) return Ty; switch (TYPE_PRECISION(type)) { default: - debug_tree(type); - llvm_unreachable("Unknown FP type!"); + DieAbjectly("Unknown FP type!", type); case 32: Ty = SET_TYPE_LLVM(type, Type::getFloatTy(Context)); break; case 64: Ty = SET_TYPE_LLVM(type, Type::getDoubleTy(Context)); break; case 80: Ty = SET_TYPE_LLVM(type, Type::getX86_FP80Ty(Context)); break; Modified: dragonegg/trunk/x86/Target.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/x86/Target.cpp?rev=128772&r1=128771&r2=128772&view=diff ============================================================================== --- dragonegg/trunk/x86/Target.cpp (original) +++ dragonegg/trunk/x86/Target.cpp Sat Apr 2 12:08:23 2011 @@ -27,7 +27,6 @@ // LLVM headers #include "llvm/Module.h" -#include "llvm/Support/ErrorHandling.h" // System headers #include @@ -755,7 +754,8 @@ } } } - llvm_unreachable("Builtin not implemented!"); + DieAbjectly("Builtin not implemented!", stmt); + return false; } /* These are defined in i386.c */ From baldrick at free.fr Sat Apr 2 12:14:47 2011 From: baldrick at free.fr (Duncan Sands) Date: Sat, 02 Apr 2011 17:14:47 -0000 Subject: [llvm-commits] [dragonegg] r128774 - /dragonegg/trunk/Internals.h Message-ID: <20110402171447.1490E2A6C12C@llvm.org> Author: baldrick Date: Sat Apr 2 12:14:46 2011 New Revision: 128774 URL: http://llvm.org/viewvc/llvm-project?rev=128774&view=rev Log: Add comment describing this method. Modified: dragonegg/trunk/Internals.h Modified: dragonegg/trunk/Internals.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Internals.h?rev=128774&r1=128773&r2=128774&view=diff ============================================================================== --- dragonegg/trunk/Internals.h (original) +++ dragonegg/trunk/Internals.h Sat Apr 2 12:14:46 2011 @@ -110,15 +110,15 @@ extern Constant* ConvertMetadataStringToGV(const char *str); +/// DieAbjectly - An unrecoverable fatal error occurred - throw in the towel, +/// give up the ghost, quit miserably. inline void DieAbjectly(const char *Message) { llvm_unreachable(Message); } - inline void DieAbjectly(const char *Message, union gimple_statement_d *stmt) { if (stmt) debug_gimple_stmt(stmt); DieAbjectly(Message); } - inline void DieAbjectly(const char *Message, union tree_node *exp) { if (exp) debug_tree(exp); DieAbjectly(Message); From daniel at zuster.org Sat Apr 2 12:46:25 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Sat, 02 Apr 2011 17:46:25 -0000 Subject: [llvm-commits] [zorg] r128775 - /zorg/trunk/lnt/lnt/testing/util/compilers.py Message-ID: <20110402174625.31FBC2A6C12C@llvm.org> Author: ddunbar Date: Sat Apr 2 12:46:25 2011 New Revision: 128775 URL: http://llvm.org/viewvc/llvm-project?rev=128775&view=rev Log: lnt.testing.util.compilers: Add some rudimentary support for interrogating icc. Modified: zorg/trunk/lnt/lnt/testing/util/compilers.py Modified: zorg/trunk/lnt/lnt/testing/util/compilers.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/testing/util/compilers.py?rev=128775&r1=128774&r2=128775&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/testing/util/compilers.py (original) +++ zorg/trunk/lnt/lnt/testing/util/compilers.py Sat Apr 2 12:46:25 2011 @@ -18,29 +18,43 @@ cc_version = capture([cc, '-v', '-E'] + cc_flags + ['-x', 'c', '/dev/null', '-###'], include_stderr=True).strip() - version_ln = None - cc_target = None + + # Check if this is icc, which isn't going to cooperate with most of our + # interrogation. This has only been tested for icc 11.1, it isn't + # particularly robust. cc1_binary = None - for ln in cc_version.split('\n'): - if ' version ' in ln: - version_ln = ln - elif ln.startswith('Target:'): - cc_target = ln.split(':',1)[1].strip() - elif 'cc1' in ln or 'clang-cc' in ln: - m = re.match(r' "([^"]*)".*"-E".*', ln) - if not m: - error("unable to determine cc1 binary: %r: %r" % (cc, ln)) - cc1_binary, = m.groups() - if version_ln is None: - error("unable to find compiler version: %r: %r" % (cc, cc_version)) - if cc_target is None: - error("unable to find compiler target: %r: %r" % (cc, cc_version)) - if cc1_binary is None: - error("unable to find compiler cc1 binary: %r: %r" % (cc, cc_version)) - m = re.match(r'(.*) version ([^ ]*) (\([^(]*\))(.*)', version_ln) - if not m: - error("unable to determine compiler version: %r: %r" % (cc, version_ln)) - cc_name,cc_version_num,cc_build_string,cc_extra = m.groups() + if cc_version.startswith('icc: command line warning'): + cc_name = 'icc' + cc_version = capture([cc, '-v'], include_stderr=True).strip() + cc_version_num = cc_version + if cc_version_num.startswith('Version '): + cc_version_num = cc_version_num.split(' ', 1)[1] + cc_target = capture([cc, '-dumpmachine']).strip() + else: + version_ln = None + cc_target = None + for ln in cc_version.split('\n'): + if ' version ' in ln: + version_ln = ln + elif ln.startswith('Target:'): + cc_target = ln.split(':',1)[1].strip() + elif 'cc1' in ln or 'clang-cc' in ln: + m = re.match(r' "([^"]*)".*"-E".*', ln) + if not m: + error("unable to determine cc1 binary: %r: %r" % (cc, ln)) + cc1_binary, = m.groups() + if version_ln is None: + error("unable to find compiler version: %r: %r" % (cc, cc_version)) + if cc_target is None: + error("unable to find compiler target: %r: %r" % (cc, cc_version)) + if cc1_binary is None: + error("unable to find compiler cc1 binary: %r: %r" % ( + cc, cc_version)) + m = re.match(r'(.*) version ([^ ]*) (\([^(]*\))(.*)', version_ln) + if not m: + error("unable to determine compiler version: %r: %r" % ( + cc, version_ln)) + cc_name,cc_version_num,cc_build_string,cc_extra = m.groups() # Compute normalized compiler name and type. We try to grab source # revisions, branches, and tags when possible. @@ -49,7 +63,11 @@ cc_src_revision = None cc_src_tag = None llvm_capable = False - if (cc_name, cc_extra) == ('gcc',''): + if cc_name == 'icc': + cc_norm_name = 'icc' + cc_build = 'PROD' + + elif (cc_name, cc_extra) == ('gcc',''): cc_norm_name = 'gcc' m = re.match(r'\(Apple Inc. build ([0-9]*)\)', cc_build_string) if m: @@ -129,19 +147,19 @@ cc_exec_hash = hashlib.sha1() cc_exec_hash.update(open(cc,'rb').read()) - cc1_exec_hash = hashlib.sha1() - cc1_exec_hash.update(open(cc1_binary,'rb').read()) - info = { 'cc_build' : cc_build, 'cc_name' : cc_norm_name, 'cc_version_number' : cc_version_num, 'cc_target' : cc_target, 'cc_version' :cc_version, 'cc_exec_hash' : cc_exec_hash.hexdigest(), - 'cc1_exec_hash' : cc1_exec_hash.hexdigest(), 'cc_as_version' : cc_as_version, 'cc_ld_version' : cc_ld_version, } + if cc1_binary is not None: + cc1_exec_hash = hashlib.sha1() + cc1_exec_hash.update(open(cc1_binary,'rb').read()) + info['cc1_exec_hash'] = cc1_exec_hash.hexdigest() if cc_src_tag is not None: info['cc_src_tag'] = cc_src_tag if cc_src_revision is not None: From benny.kra at googlemail.com Sat Apr 2 13:50:58 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Sat, 02 Apr 2011 18:50:58 -0000 Subject: [llvm-commits] [llvm] r128777 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Message-ID: <20110402185058.DFD262A6C12C@llvm.org> Author: d0k Date: Sat Apr 2 13:50:58 2011 New Revision: 128777 URL: http://llvm.org/viewvc/llvm-project?rev=128777&view=rev Log: While SimplifyDemandedBits constant folds this, we can't rely on it here. It's possible to craft an input that hits the recursion limits in a way that SimplifyDemandedBits doesn't simplify the icmp but ComputeMaskedBits can infer which bits are zero. No test case as it depends on too many other things. Fixes PR9609. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=128777&r1=128776&r2=128777&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Sat Apr 2 13:50:58 2011 @@ -913,8 +913,13 @@ if (KnownZeroMask.isPowerOf2()) { Value *In = ICI->getOperand(0); - assert((Op1C->isZero() || Op1C->getValue() == KnownZeroMask) && - "Constant icmp not folded?"); + // If the icmp tests for a known zero bit we can constant fold it. + if (!Op1C->isZero() && Op1C->getValue() != KnownZeroMask) { + Value *V = Pred == ICmpInst::ICMP_NE ? + ConstantInt::getAllOnesValue(CI.getType()) : + ConstantInt::getNullValue(CI.getType()); + return ReplaceInstUsesWith(CI, V); + } if (!Op1C->isZero() == (Pred == ICmpInst::ICMP_NE)) { // sext ((x & 2^n) == 0) -> (x >> n) - 1 From aggarwa4 at illinois.edu Sat Apr 2 14:02:57 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Sat, 02 Apr 2011 19:02:57 -0000 Subject: [llvm-commits] [poolalloc] r128778 - /poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp Message-ID: <20110402190257.D61812A6C12C@llvm.org> Author: aggarwa4 Date: Sat Apr 2 14:02:57 2011 New Revision: 128778 URL: http://llvm.org/viewvc/llvm-project?rev=128778&view=rev Log: Added braces, to disambiguate if-else pairs. Compiler warnings. Modified: poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp Modified: poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp?rev=128778&r1=128777&r2=128778&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp Sat Apr 2 14:02:57 2011 @@ -45,45 +45,56 @@ } bool TypeAnalysis::isCopyingLoad(LoadInst *LI){ - if(LI->getNumUses() == 1) + if(LI->getNumUses() == 1) { if(StoreInst *SI = dyn_cast(LI->use_begin())) { - if(SI->getOperand(0) == LI) + if(SI->getOperand(0) == LI) { return true; + } } else if(InsertValueInst *IV = dyn_cast(LI->use_begin())) { - if(IV->getInsertedValueOperand() == LI) + if(IV->getInsertedValueOperand() == LI) { return true; + } } + } return false; } bool TypeAnalysis::isCopyingLoad(ExtractValueInst * EI) { - if(EI->getNumUses() == 1) + if(EI->getNumUses() == 1) { if(StoreInst *SI = dyn_cast(EI->use_begin())) { - if(SI->getOperand(0) == EI) + if(SI->getOperand(0) == EI) { return true; + } } else if(InsertValueInst *IV = dyn_cast(EI->use_begin())) { - if(IV->getInsertedValueOperand() == EI) + if(IV->getInsertedValueOperand() == EI) { return true; + } } + } return false; } bool TypeAnalysis::isCopyingStore(StoreInst *SI) { - if(SI->getOperand(0)->getNumUses() == 1) - if(isa(SI->getOperand(0))) + if(SI->getOperand(0)->getNumUses() == 1) { + if(isa(SI->getOperand(0))) { return true; - else if(isa(SI->getOperand(0))) + } + else if(isa(SI->getOperand(0))) { return true; - + } + } return false; } bool TypeAnalysis::isCopyingStore(InsertValueInst *IVI) { - if(IVI->getInsertedValueOperand()->getNumUses() == 1) - if(isa(IVI->getInsertedValueOperand())) + if(IVI->getInsertedValueOperand()->getNumUses() == 1) { + if(isa(IVI->getInsertedValueOperand())) { return true; - else if(isa(IVI->getInsertedValueOperand())) + } + else if(isa(IVI->getInsertedValueOperand())) { return true; + } + } return false; } From eli.friedman at gmail.com Sat Apr 2 17:11:56 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Sat, 02 Apr 2011 22:11:56 -0000 Subject: [llvm-commits] [llvm] r128781 - /llvm/trunk/lib/Analysis/ValueTracking.cpp Message-ID: <20110402221156.7B6DD2A6C12C@llvm.org> Author: efriedma Date: Sat Apr 2 17:11:56 2011 New Revision: 128781 URL: http://llvm.org/viewvc/llvm-project?rev=128781&view=rev Log: Don't assume something which might be a constant expression is an instruction. Based on PR9429, but no testcase because I can't figure out how to trigger it anymore given other changes to the relevant code. Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=128781&r1=128780&r2=128781&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ValueTracking.cpp (original) +++ llvm/trunk/lib/Analysis/ValueTracking.cpp Sat Apr 2 17:11:56 2011 @@ -729,9 +729,9 @@ // copying a sign bit (sdiv int_min, 2). if (match(V, m_LShr(m_Value(), m_Value())) || match(V, m_UDiv(m_Value(), m_Value()))) { - BinaryOperator *BO = cast(V); - if (BO->isExact()) - return isPowerOfTwo(BO->getOperand(0), TD, Depth); + PossiblyExactOperator *PEO = cast(V); + if (PEO->isExact()) + return isPowerOfTwo(PEO->getOperand(0), TD, Depth); } return false; From eli.friedman at gmail.com Sat Apr 2 17:45:17 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Sat, 02 Apr 2011 22:45:17 -0000 Subject: [llvm-commits] [llvm] r128782 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/Utils/Local.cpp test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll Message-ID: <20110402224517.C24E52A6C12C@llvm.org> Author: efriedma Date: Sat Apr 2 17:45:17 2011 New Revision: 128782 URL: http://llvm.org/viewvc/llvm-project?rev=128782&view=rev Log: PR9446: RecursivelyDeleteTriviallyDeadInstructions can delete the instruction after the given instruction; make sure to handle that case correctly. (It's difficult to trigger; the included testcase involves a dead block, but I don't think that's a requirement.) While I'm here, get rid of the unnecessary warning about SimplifyInstructionsInBlock, since it should work correctly as far as I know. Added: llvm/trunk/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=128782&r1=128781&r2=128782&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Sat Apr 2 17:45:17 2011 @@ -74,10 +74,6 @@ /// /// This returns true if it changed the code, note that it can delete /// instructions in other blocks as well in this block. -/// -/// WARNING: Do not use this function on unreachable blocks, as recursive -/// simplification is not able to handle corner-case scenarios that can -/// arise in them. bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0); //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=128782&r1=128781&r2=128782&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Sat Apr 2 17:45:17 2011 @@ -332,8 +332,11 @@ BI = BB->begin(); continue; } - + + WeakVH BIHandle(BI); MadeChange |= RecursivelyDeleteTriviallyDeadInstructions(Inst); + if (BIHandle != BI) + BI = BB->begin(); } return MadeChange; } Added: llvm/trunk/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll?rev=128782&view=auto ============================================================================== --- llvm/trunk/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll (added) +++ llvm/trunk/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll Sat Apr 2 17:45:17 2011 @@ -0,0 +1,32 @@ +; RUN: opt < %s -jump-threading +; PR9446 +; Just check that it doesn't crash + +define void @int327() nounwind { +entry: + unreachable + +for.cond: ; preds = %for.cond4 + %tobool3 = icmp eq i8 undef, 0 + br i1 %tobool3, label %for.cond23, label %for.cond4 + +for.cond4: ; preds = %for.cond + br label %for.cond + +for.cond23: ; preds = %for.body28, %for.cond23, %for.cond + %conv321 = phi i32 [ %conv32, %for.body28 ], [ 0, %for.cond ], [ %conv321, %for.cond23 ] + %l_266.0 = phi i32 [ %phitmp, %for.body28 ], [ 0, %for.cond ], [ 0, %for.cond23 ] + %cmp26 = icmp eq i32 %l_266.0, 0 + br i1 %cmp26, label %for.body28, label %for.cond23 + +for.body28: ; preds = %for.cond23 + %and = and i32 %conv321, 1 + %conv32 = zext i8 undef to i32 + %add = add nsw i32 %l_266.0, 1 + %phitmp = and i32 %add, 255 + br label %for.cond23 + +if.end43: ; No predecessors! + ret void +} + From baldrick at free.fr Sun Apr 3 01:18:53 2011 From: baldrick at free.fr (Duncan Sands) Date: Sun, 03 Apr 2011 06:18:53 -0000 Subject: [llvm-commits] [dragonegg] r128786 - /dragonegg/trunk/Constants.cpp Message-ID: <20110403061853.B0B482A6C12C@llvm.org> Author: baldrick Date: Sun Apr 3 01:18:53 2011 New Revision: 128786 URL: http://llvm.org/viewvc/llvm-project?rev=128786&view=rev Log: Turn this check back off again: it still blows up. Modified: dragonegg/trunk/Constants.cpp Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=128786&r1=128785&r2=128786&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Sun Apr 3 01:18:53 2011 @@ -1137,9 +1137,10 @@ if (isInt64(TREE_TYPE(exp), true) && InitSize != TypeSize) DieAbjectly("Constant too big for type!", exp); } - if (getTargetData().getABITypeAlignment(Init->getType()) * 8 > - TYPE_ALIGN(TREE_TYPE(exp))) - DieAbjectly("Constant over aligned!", exp); +// FIXME: This check fails when building libdecnumber (self-host build). +// if (getTargetData().getABITypeAlignment(Init->getType()) * 8 > +// TYPE_ALIGN(TREE_TYPE(exp))) +// DieAbjectly("Constant over aligned!", exp); #endif return Init; From pichet2000 at gmail.com Sun Apr 3 06:29:22 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Sun, 3 Apr 2011 07:29:22 -0400 Subject: [llvm-commits] [llvm] r128782 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/Utils/Local.cpp test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll In-Reply-To: <20110402224517.C24E52A6C12C@llvm.org> References: <20110402224517.C24E52A6C12C@llvm.org> Message-ID: On Sat, Apr 2, 2011 at 6:45 PM, Eli Friedman wrote: > Author: efriedma > Date: Sat Apr ?2 17:45:17 2011 > New Revision: 128782 > > URL: http://llvm.org/viewvc/llvm-project?rev=128782&view=rev > Log: > PR9446: RecursivelyDeleteTriviallyDeadInstructions can delete the instruction > after the given instruction; make sure to handle that case correctly. > (It's difficult to trigger; the included testcase involves a dead > block, but I don't think that's a requirement.) > > While I'm here, get rid of the unnecessary warning about > SimplifyInstructionsInBlock, since it should work correctly as far as I know. > > > Added: > ? ?llvm/trunk/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll > Modified: > ? ?llvm/trunk/include/llvm/Transforms/Utils/Local.h > ? ?llvm/trunk/lib/Transforms/Utils/Local.cpp hi, This commit is making 3 clang tests to crash on Win32 using MSVC 2010. any ideas? 4> ******************** 4> Failing Tests (3): 4> Clang :: CodeGenCXX/temp-order.cpp 4> Clang :: CodeGenObjC/exceptions.m 4> Clang :: CodeGenObjC/synchronized.m From 6yearold at gmail.com Sun Apr 3 06:41:29 2011 From: 6yearold at gmail.com (arrowdodger) Date: Sun, 3 Apr 2011 15:41:29 +0400 Subject: [llvm-commits] [PATCH][CMake] Fixes for modules/LLVM.cmake Message-ID: There are some typos in LLVM.cmake file and this patch fixes them. While there, export LLVM_ON_UNIX variable too. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110403/c92d81a1/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm.cmake.patch Type: text/x-patch Size: 585 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110403/c92d81a1/attachment.bin From ofv at wanadoo.es Sun Apr 3 11:00:48 2011 From: ofv at wanadoo.es (=?utf-8?Q?=C3=93scar_Fuentes?=) Date: Sun, 03 Apr 2011 18:00:48 +0200 Subject: [llvm-commits] [PATCH][CMake] Fixes for modules/LLVM.cmake References: Message-ID: <877hbbs4sv.fsf@wanadoo.es> arrowdodger <6yearold at gmail.com> writes: > There are some typos in LLVM.cmake file and this patch fixes them. > While there, export LLVM_ON_UNIX variable too. > > Index: cmake/modules/LLVM.cmake > =================================================================== > --- cmake/modules/LLVM.cmake (revision 128786) > +++ cmake/modules/LLVM.cmake (working copy) > @@ -20,10 +20,9 @@ > > set(LLVM_ENABLE_PIC @LLVM_ENABLE_PIC@) > > -set(LLVM_ENABLE_THREADS @LLVM_ENABLE_THREADS) > - Why do you remove LLVM_ENABLE_THREADS ? [snip] From 6yearold at gmail.com Sun Apr 3 11:12:37 2011 From: 6yearold at gmail.com (arrowdodger) Date: Sun, 3 Apr 2011 20:12:37 +0400 Subject: [llvm-commits] [PATCH][CMake] Fixes for modules/LLVM.cmake In-Reply-To: <877hbbs4sv.fsf@wanadoo.es> References: <877hbbs4sv.fsf@wanadoo.es> Message-ID: On Sun, Apr 3, 2011 at 8:00 PM, ?scar Fuentes wrote: > Why do you remove LLVM_ENABLE_THREADS ? > It is already in there at line 17. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110403/e2a89f3a/attachment.html From Brice.Lin at gmail.com Sun Apr 3 11:09:09 2011 From: Brice.Lin at gmail.com (Brice Lin) Date: Sun, 03 Apr 2011 16:09:09 -0000 Subject: [llvm-commits] [poolalloc] r128788 - in /poolalloc/trunk/runtime: Makefile TypeTrack/ TypeTrack/Makefile TypeTrack/TypeRuntime.c Message-ID: <20110403160909.66DC32A6C12C@llvm.org> Author: bglin2 Date: Sun Apr 3 11:09:09 2011 New Revision: 128788 URL: http://llvm.org/viewvc/llvm-project?rev=128788&view=rev Log: Initial commit for the 1:1 shadow memory (implemented with mmap) runtime used by the dynamic type checking pass. Added: poolalloc/trunk/runtime/TypeTrack/ poolalloc/trunk/runtime/TypeTrack/Makefile poolalloc/trunk/runtime/TypeTrack/TypeRuntime.c Modified: poolalloc/trunk/runtime/Makefile Modified: poolalloc/trunk/runtime/Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/Makefile?rev=128788&r1=128787&r2=128788&view=diff ============================================================================== --- poolalloc/trunk/runtime/Makefile (original) +++ poolalloc/trunk/runtime/Makefile Sun Apr 3 11:09:09 2011 @@ -6,6 +6,6 @@ # # List all of the subdirectories that we will compile. # -DIRS=FreeListAllocator FL2Allocator PreRT +DIRS=FreeListAllocator FL2Allocator PreRT TypeTrack include $(LEVEL)/Makefile.common Added: poolalloc/trunk/runtime/TypeTrack/Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/TypeTrack/Makefile?rev=128788&view=auto ============================================================================== --- poolalloc/trunk/runtime/TypeTrack/Makefile (added) +++ poolalloc/trunk/runtime/TypeTrack/Makefile Sun Apr 3 11:09:09 2011 @@ -0,0 +1,7 @@ +LEVEL = ../.. + +SHARED_LIBRARY = 1 +LOADABLE_MODULE = 1 +LIBRARYNAME = typechecks_rt + +include $(LEVEL)/Makefile.common Added: poolalloc/trunk/runtime/TypeTrack/TypeRuntime.c URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/TypeTrack/TypeRuntime.c?rev=128788&view=auto ============================================================================== --- poolalloc/trunk/runtime/TypeTrack/TypeRuntime.c (added) +++ poolalloc/trunk/runtime/TypeTrack/TypeRuntime.c Sun Apr 3 11:09:09 2011 @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +#define SIZE ((size_t)(sizeof(unsigned int)) * (size_t)(4294967296)) + +unsigned int *shadow_begin; + +/** + * Initialize the shadow memory which records the 1:1 mapping of addresses to types. + */ +void shadowInit() { + shadow_begin = (unsigned int *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, -1, 0); + + if (shadow_begin == MAP_FAILED) { + fprintf(stderr, "Failed to map the shadow memory!"); + fflush(stderr); + assert(0 && "MAP_FAILED"); + } +} + +/** + * Unmap the shadow memory which records the 1:1 mapping of addresses to types. + */ +void shadowUnmap() { + if (munmap(shadow_begin, SIZE) == -1) { + fprintf(stderr, "Failed to unmap the shadow memory!"); + fflush(stderr); + } +} + +/** + * Check the loaded type against the type recorded in the shadow memory. + * + * Note: currently does not handle GEPs. + */ +int trackLoadInst(void *ptr, unsigned int typeNumber) { + uintptr_t p = (uintptr_t)ptr; + p &= 0xFFFFFFFF; + printf("Load: %p, %p = %u | expecting %u\n", ptr, (void *)p, typeNumber, shadow_begin[p]); + + return 0; +} + +/** + * Record the stored type and address in the shadow memory. + * + * Note: currently does not handle GEPs. + */ +int trackStoreInst(void *ptr, unsigned int typeNumber) { + uintptr_t p = (uintptr_t)ptr; + p &= 0xFFFFFFFF; + shadow_begin[p] = typeNumber; +#if 0 + printf("Store: %p, %p = %u\n", ptr, (void *)p, typeNumber); +#endif + + return 0; +} From ofv at wanadoo.es Sun Apr 3 11:12:38 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Sun, 03 Apr 2011 16:12:38 -0000 Subject: [llvm-commits] [llvm] r128789 - /llvm/trunk/cmake/modules/LLVM.cmake Message-ID: <20110403161238.392E22A6C12C@llvm.org> Author: ofv Date: Sun Apr 3 11:12:38 2011 New Revision: 128789 URL: http://llvm.org/viewvc/llvm-project?rev=128789&view=rev Log: Fix typos on LLVM.cmake. Export LLVM_ON_UNIX & LLVM_ON_WIN32. Patch by arrowdodger! Modified: llvm/trunk/cmake/modules/LLVM.cmake Modified: llvm/trunk/cmake/modules/LLVM.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVM.cmake?rev=128789&r1=128788&r2=128789&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVM.cmake (original) +++ llvm/trunk/cmake/modules/LLVM.cmake Sun Apr 3 11:12:38 2011 @@ -20,10 +20,10 @@ set(LLVM_ENABLE_PIC @LLVM_ENABLE_PIC@) -set(LLVM_ENABLE_THREADS @LLVM_ENABLE_THREADS) - set(HAVE_LIBDL @HAVE_LIBDL@) -set(HAVE_LIBPTHREAD @HAVE_LIBPTHREAD) +set(HAVE_LIBPTHREAD @HAVE_LIBPTHREAD@) +set(LLVM_ON_UNIX @LLVM_ON_UNIX@) +set(LLVM_ON_WIN32 @LLVM_ON_WIN32@) # We try to include using the current setting of CMAKE_MODULE_PATH, # which suppossedly was filled by the user with the directory where From ofv at wanadoo.es Sun Apr 3 11:19:02 2011 From: ofv at wanadoo.es (=?utf-8?Q?=C3=93scar_Fuentes?=) Date: Sun, 03 Apr 2011 18:19:02 +0200 Subject: [llvm-commits] [PATCH][CMake] Fixes for modules/LLVM.cmake References: <877hbbs4sv.fsf@wanadoo.es> Message-ID: <87wrjbqpe1.fsf@wanadoo.es> arrowdodger <6yearold at gmail.com> writes: >> Why do you remove LLVM_ENABLE_THREADS ? > > It is already in there at line 17. I see. Committed. Thanks for cleaning up that mess. BTW, I added LLVM_ON_WIN32 too. From aggarwa4 at illinois.edu Sun Apr 3 11:21:39 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Sun, 03 Apr 2011 16:21:39 -0000 Subject: [llvm-commits] [poolalloc] r128790 - /poolalloc/trunk/lib/AssistDS/CMakeLists.txt Message-ID: <20110403162139.4B8302A6C12C@llvm.org> Author: aggarwa4 Date: Sun Apr 3 11:21:39 2011 New Revision: 128790 URL: http://llvm.org/viewvc/llvm-project?rev=128790&view=rev Log: Added the new files. Modified: poolalloc/trunk/lib/AssistDS/CMakeLists.txt Modified: poolalloc/trunk/lib/AssistDS/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/CMakeLists.txt?rev=128790&r1=128789&r2=128790&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/CMakeLists.txt (original) +++ poolalloc/trunk/lib/AssistDS/CMakeLists.txt Sun Apr 3 11:21:39 2011 @@ -1,6 +1,16 @@ add_llvm_library(AssistDS + ArgCast.cpp + ArgSimplify.cpp Devirt.cpp FuncSpec.cpp IndCloner.cpp + Int2PtrCmp.cpp + MergeArrayIndexGEP.cpp + MergeGEP.cpp SVADevirt.cpp + SimplifyGEP.cpp + SimplifyMRV.cpp + TestGEP.cpp + TypeAnalysis.cpp + VarArgsFunc.cpp ) From eli.friedman at gmail.com Sun Apr 3 13:42:53 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Sun, 3 Apr 2011 11:42:53 -0700 Subject: [llvm-commits] [llvm] r128782 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/Utils/Local.cpp test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll In-Reply-To: References: <20110402224517.C24E52A6C12C@llvm.org> Message-ID: On Sun, Apr 3, 2011 at 4:29 AM, Francois Pichet wrote: > On Sat, Apr 2, 2011 at 6:45 PM, Eli Friedman wrote: >> Author: efriedma >> Date: Sat Apr ?2 17:45:17 2011 >> New Revision: 128782 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=128782&view=rev >> Log: >> PR9446: RecursivelyDeleteTriviallyDeadInstructions can delete the instruction >> after the given instruction; make sure to handle that case correctly. >> (It's difficult to trigger; the included testcase involves a dead >> block, but I don't think that's a requirement.) >> >> While I'm here, get rid of the unnecessary warning about >> SimplifyInstructionsInBlock, since it should work correctly as far as I know. >> >> >> Added: >> ? ?llvm/trunk/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll >> Modified: >> ? ?llvm/trunk/include/llvm/Transforms/Utils/Local.h >> ? ?llvm/trunk/lib/Transforms/Utils/Local.cpp > > hi, > > This commit is making 3 clang tests to crash on Win32 using MSVC 2010. > any ideas? > > 4> ?******************** > 4> ?Failing Tests (3): > 4> ? ? ?Clang :: CodeGenCXX/temp-order.cpp > 4> ? ? ?Clang :: CodeGenObjC/exceptions.m > 4> ? ? ?Clang :: CodeGenObjC/synchronized.m No idea off the top of my head... this change should only have an effect in cases where we would have accessed freed memory otherwise. -Eli From Brice.Lin at gmail.com Sun Apr 3 14:24:11 2011 From: Brice.Lin at gmail.com (Brice Lin) Date: Sun, 03 Apr 2011 19:24:11 -0000 Subject: [llvm-commits] [poolalloc] r128791 - in /poolalloc/trunk/runtime: DynamicTypeChecks/ TypeTrack/ Message-ID: <20110403192411.BF5862A6C12C@llvm.org> Author: bglin2 Date: Sun Apr 3 14:24:11 2011 New Revision: 128791 URL: http://llvm.org/viewvc/llvm-project?rev=128791&view=rev Log: Renamed runtime directory TypeTrack to DynamicTypeChecks. Added: poolalloc/trunk/runtime/DynamicTypeChecks/ - copied from r128788, poolalloc/trunk/runtime/TypeTrack/ Removed: poolalloc/trunk/runtime/TypeTrack/ From baldrick at free.fr Sun Apr 3 14:44:18 2011 From: baldrick at free.fr (Duncan Sands) Date: Sun, 03 Apr 2011 19:44:18 -0000 Subject: [llvm-commits] [dragonegg] r128792 - /dragonegg/trunk/Constants.cpp Message-ID: <20110403194418.561672A6C12C@llvm.org> Author: baldrick Date: Sun Apr 3 14:44:18 2011 New Revision: 128792 URL: http://llvm.org/viewvc/llvm-project?rev=128792&view=rev Log: Have default initialized struct fields turn up as a zero of the appropriate type rather than an array of bytes. This makes the IR easier to read but probably doesn't otherwise matter. Modified: dragonegg/trunk/Constants.cpp Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=128792&r1=128791&r2=128792&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Sun Apr 3 14:44:18 2011 @@ -739,11 +739,13 @@ /// the constant in which case any extra bits have an undefined value. class FieldContents { SignedRange R; // The range of bits occupied by the constant. - Constant *C; // The constant. May be null, in which case all bits are zero. + Constant *C; // The constant. May be null if the range is empty. int Starts; // The first bit of the constant is positioned at this offset. FieldContents(SignedRange r, Constant *c, int starts) - : R(r), C(c), Starts(starts) {} + : R(r), C(c), Starts(starts) { + assert((R.empty() || C) && "Need constant when range not empty!"); + } /// getAsBits - Return the bits in the range as an integer (or null if the /// range is empty). @@ -751,8 +753,6 @@ if (R.empty()) return 0; const Type *IntTy = IntegerType::get(Context, R.getWidth()); - if (!C) // Implicit zero. - return Constant::getNullValue(IntTy); return InterpretAsType(C, IntTy, R.getFirst() - Starts); } @@ -760,7 +760,8 @@ /// constant properly represents the bits in the range and so can be handed to /// the user as is. bool isSafeToReturnContentsDirectly(const TargetData &TD) const { - // Implicit zeros need to be made explicit before being passed to the user. + // If there is no constant (allowed when the range is empty) then one needs + // to be created. if (!C) return false; // If the first bit of the constant is not the first bit of the range then @@ -778,16 +779,11 @@ /// FieldContents - Default constructor: empty bit range. FieldContents() : R(), C(0), Starts(0) {} - /// getConstant - Fill the range [first, last) with the given constant. - static FieldContents getConstant(int first, int last, Constant *c) { + /// get - Fill the range [first, last) with the given constant. + static FieldContents get(int first, int last, Constant *c) { return FieldContents(SignedRange(first, last), c, first); } - /// getZero - Fill the range [first, last) with zero. - static FieldContents getZero(int first, int last) { - return getConstant(first, last, 0); - } - /// getRange - Return the range occupied by this field. SignedRange getRange() const { return R; } @@ -809,18 +805,16 @@ /// in the range then just return it. if (isSafeToReturnContentsDirectly(TD)) return C; - assert(R.getWidth() % BITS_PER_UNIT == 0 && "Boundaries not aligned?"); - unsigned Units = R.getWidth() / BITS_PER_UNIT; - // If this was an implicit zero then make it an explicit zero. This also - // handles the case of an empty range holding a constant of non-zero size. - if (!C || R.empty()) { - // Return an array of zero bytes. Remember the returned value as an - // optimization in case we are called again. - C = Constant::getNullValue(GetUnitType(Context, Units)); - Starts = R.empty() ? 0 : R.getFirst(); + // If the range is empty then return a constant with zero size. + if (R.empty()) { + // Return an empty array. Remember the returned value as an optimization + // in case we are called again. + C = Constant::getNullValue(GetUnitType(Context, 0)); assert(isSafeToReturnContentsDirectly(TD) && "Unit over aligned?"); return C; } + assert(R.getWidth() % BITS_PER_UNIT == 0 && "Boundaries not aligned?"); + unsigned Units = R.getWidth() / BITS_PER_UNIT; // Turn the contents into a bunch of bits. Remember the returned value as // an optimization in case we are called again. // TODO: If the contents only need to be truncated and have struct or array @@ -878,6 +872,7 @@ assert(FirstBit <= TypeSize && "Field off end of type!"); // Determine the width of the field. uint64_t BitWidth; + const Type *FieldTy = ConvertType(TREE_TYPE(field)); if (isInt64(DECL_SIZE(field), true)) { // The field has a size and it is a constant, so use it. Note that // this size may be smaller than the type size. For example, if the @@ -888,7 +883,6 @@ } else { // If the field has variable or unknown size then use the size of the // LLVM type instead as it gives the minimum size the field may have. - const Type *FieldTy = ConvertType(TREE_TYPE(field)); if (!FieldTy->isSized()) // An incomplete type - this field cannot be default initialized. continue; @@ -898,8 +892,11 @@ } uint64_t LastBit = FirstBit + BitWidth; - // Zero the bits occupied by the field. - Layout.AddInterval(FieldContents::getZero(FirstBit, LastBit)); + // Zero the bits occupied by the field. It is safe to use FieldTy here as + // it is guaranteed to cover all parts of the GCC type that can be default + // initialized. This makes for nicer IR than just using a bunch of bytes. + Constant *Zero = Constant::getNullValue(FieldTy); + Layout.AddInterval(FieldContents::get(FirstBit, LastBit, Zero)); } } @@ -935,7 +932,7 @@ uint64_t LastBit = FirstBit + BitWidth; // Set the bits occupied by the field to the initial value. - Layout.AddInterval(FieldContents::getConstant(FirstBit, LastBit, Init)); + Layout.AddInterval(FieldContents::get(FirstBit, LastBit, Init)); } // Force all fields to begin and end on a byte boundary. This automagically From fvbommel at gmail.com Sun Apr 3 14:46:29 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sun, 03 Apr 2011 19:46:29 -0000 Subject: [llvm-commits] [llvm] r128793 - in /llvm/trunk/include/llvm/Support: ConstantFolder.h IRBuilder.h NoFolder.h Message-ID: <20110403194629.14F452A6C12C@llvm.org> Author: fvbommel Date: Sun Apr 3 14:46:28 2011 New Revision: 128793 URL: http://llvm.org/viewvc/llvm-project?rev=128793&view=rev Log: Remove the LLVMContext& arguments from *Folder constructors, as they don't seem to be used anywhere. Modified: llvm/trunk/include/llvm/Support/ConstantFolder.h llvm/trunk/include/llvm/Support/IRBuilder.h llvm/trunk/include/llvm/Support/NoFolder.h Modified: llvm/trunk/include/llvm/Support/ConstantFolder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ConstantFolder.h?rev=128793&r1=128792&r2=128793&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/ConstantFolder.h (original) +++ llvm/trunk/include/llvm/Support/ConstantFolder.h Sun Apr 3 14:46:28 2011 @@ -22,12 +22,10 @@ namespace llvm { -class LLVMContext; - /// ConstantFolder - Create constants with minimum, target independent, folding. class ConstantFolder { public: - explicit ConstantFolder(LLVMContext &) {} + explicit ConstantFolder() {} //===--------------------------------------------------------------------===// // Binary Operators Modified: llvm/trunk/include/llvm/Support/IRBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IRBuilder.h?rev=128793&r1=128792&r2=128793&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/IRBuilder.h (original) +++ llvm/trunk/include/llvm/Support/IRBuilder.h Sun Apr 3 14:46:28 2011 @@ -301,7 +301,7 @@ : IRBuilderBase(C), Inserter(I), Folder(F) { } - explicit IRBuilder(LLVMContext &C) : IRBuilderBase(C), Folder(C) { + explicit IRBuilder(LLVMContext &C) : IRBuilderBase(C), Folder() { } explicit IRBuilder(BasicBlock *TheBB, const T &F) @@ -310,12 +310,12 @@ } explicit IRBuilder(BasicBlock *TheBB) - : IRBuilderBase(TheBB->getContext()), Folder(Context) { + : IRBuilderBase(TheBB->getContext()), Folder() { SetInsertPoint(TheBB); } explicit IRBuilder(Instruction *IP) - : IRBuilderBase(IP->getContext()), Folder(Context) { + : IRBuilderBase(IP->getContext()), Folder() { SetInsertPoint(IP); } @@ -325,7 +325,7 @@ } IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) - : IRBuilderBase(TheBB->getContext()), Folder(Context) { + : IRBuilderBase(TheBB->getContext()), Folder() { SetInsertPoint(TheBB, IP); } Modified: llvm/trunk/include/llvm/Support/NoFolder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/NoFolder.h?rev=128793&r1=128792&r2=128793&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/NoFolder.h (original) +++ llvm/trunk/include/llvm/Support/NoFolder.h Sun Apr 3 14:46:28 2011 @@ -27,12 +27,10 @@ namespace llvm { -class LLVMContext; - /// NoFolder - Create "constants" (actually, instructions) with no folding. class NoFolder { public: - explicit NoFolder(LLVMContext &) {} + explicit NoFolder() {} //===--------------------------------------------------------------------===// // Binary Operators From Brice.Lin at gmail.com Sun Apr 3 15:01:34 2011 From: Brice.Lin at gmail.com (Brice Lin) Date: Sun, 03 Apr 2011 20:01:34 -0000 Subject: [llvm-commits] [poolalloc] r128794 - in /poolalloc/trunk/lib/AssistDS: TypeChecks.cpp TypeChecks.h Message-ID: <20110403200134.399372A6C12C@llvm.org> Author: bglin2 Date: Sun Apr 3 15:01:34 2011 New Revision: 128794 URL: http://llvm.org/viewvc/llvm-project?rev=128794&view=rev Log: Modified the dynamic check insertion pass to call the shadow memory runtime functions. Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp poolalloc/trunk/lib/AssistDS/TypeChecks.h Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=128794&r1=128793&r2=128794&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Sun Apr 3 15:01:34 2011 @@ -24,6 +24,11 @@ char TypeChecks::ID = 0; static RegisterPass TC("typechecks", "Insert runtime type checks", false, true); +static const Type *VoidTy = 0; +static const Type *Int8Ty = 0; +static const Type *Int32Ty = 0; +static const PointerType *VoidPtrTy = 0; + // Incorporate one type and all of its subtypes into the collection of used types. void TypeChecks::IncorporateType(const Type *Ty) { // If Ty doesn't already exist in the used types map, add it now. Otherwise, return. @@ -56,8 +61,13 @@ } bool TypeChecks::runOnModule(Module &M) { - // Flags whether we modified the module. - bool modified = false; + bool modified = false; // Flags whether we modified the module. + bool firstSI = true; + + VoidTy = IntegerType::getVoidTy(M.getContext()); + Int8Ty = IntegerType::getInt8Ty(M.getContext()); + Int32Ty = IntegerType::getInt32Ty(M.getContext()); + VoidPtrTy = PointerType::getUnqual(Int8Ty); UsedTypes.clear(); // Reset if run multiple times. maxType = 1; @@ -84,7 +94,20 @@ } if (StoreInst *SI = dyn_cast(&I)) { + if (firstSI) { + modified |= initShadow(M, *SI); + firstSI = false; + } + modified |= visitStoreInst(M, *SI); + } else if (LoadInst *LI = dyn_cast(&I)) { + // Unlikely, but just in case + if (firstSI) { + modified |= initShadowLI(M, *LI); + firstSI = false; + } + + modified |= visitLoadInst(M, *LI); } } } @@ -113,20 +136,60 @@ OS << "\nNumber of types: " << maxType << '\n'; } +// Initialize the shadow memory which contains the 1:1 mapping. +bool TypeChecks::initShadow(Module &M, StoreInst &SI) { + // Create the call to the runtime initialization function and place it before the store instruction. + Constant *F = M.getOrInsertFunction("shadowInit", VoidTy, NULL); + CallInst::Create(F, "", &SI); + + return true; +} + +// Initialize the shadow memory which contains the 1:1 mapping. +bool TypeChecks::initShadowLI(Module &M, LoadInst &LI) { + // Create the call to the runtime initialization function and place it before the load instruction. + Constant *F = M.getOrInsertFunction("shadowInit", VoidTy, NULL); + CallInst::Create(F, "", &LI); + + return true; +} + +// Initialize the shadow memory which contains the 1:1 mapping. +bool TypeChecks::unmapShadow(Module &M, Instruction &I) { + // Create the call to the runtime shadow memory unmap function and place it before any exiting instruction. + Constant *F = M.getOrInsertFunction("shadowUnmap", VoidTy, NULL); + CallInst::Create(F, "", &I); + + return true; +} + +// Insert runtime checks before all load instructions. +bool TypeChecks::visitLoadInst(Module &M, LoadInst &LI) { + // Cast the pointer operand to i8* for the runtime function. + CastInst *BCI = BitCastInst::CreatePointerCast(LI.getPointerOperand(), VoidPtrTy, "", &LI); + + std::vector Args; + Args.push_back(BCI); + Args.push_back(ConstantInt::get(Int32Ty, UsedTypes[LI.getType()])); + + // Create the call to the runtime check and place it before the load instruction. + Constant *F = M.getOrInsertFunction("trackLoadInst", Int32Ty, VoidPtrTy, Int32Ty, NULL); + CallInst::Create(F, Args.begin(), Args.end(), "", &LI); + + return true; +} + // Insert runtime checks before all store instructions. bool TypeChecks::visitStoreInst(Module &M, StoreInst &SI) { - const Type *Int8Ty = IntegerType::getInt8Ty(M.getContext()); - const Type *Int32Ty = IntegerType::getInt32Ty(M.getContext()); - PointerType *VoidPtrTy = PointerType::getUnqual(Int8Ty); - + // Cast the pointer operand to i8* for the runtime function. CastInst *BCI = BitCastInst::CreatePointerCast(SI.getPointerOperand(), VoidPtrTy, "", &SI); std::vector Args; Args.push_back(BCI); Args.push_back(ConstantInt::get(Int32Ty, UsedTypes[SI.getOperand(0)->getType()])); // SI.getValueOperand() - // Create the call to the runtime check, and place it before the store instruction. - Constant *F = M.getOrInsertFunction("trackStoreInst", Int8Ty, VoidPtrTy, Int32Ty, NULL); + // Create the call to the runtime check and place it before the store instruction. + Constant *F = M.getOrInsertFunction("trackStoreInst", Int32Ty, VoidPtrTy, Int32Ty, NULL); CallInst::Create(F, Args.begin(), Args.end(), "", &SI); return true; Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.h?rev=128794&r1=128793&r2=128794&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.h (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.h Sun Apr 3 15:01:34 2011 @@ -45,6 +45,10 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { } + bool initShadow(Module &M, StoreInst &SI); + bool initShadowLI(Module &M, LoadInst &LI); + bool unmapShadow(Module &M, Instruction &I); + bool visitLoadInst(Module &M, LoadInst &LI); bool visitStoreInst(Module &M, StoreInst &SI); // Return the map containing all of the types used in the module. From Brice.Lin at gmail.com Sun Apr 3 15:03:41 2011 From: Brice.Lin at gmail.com (Brice Lin) Date: Sun, 03 Apr 2011 20:03:41 -0000 Subject: [llvm-commits] [poolalloc] r128795 - /poolalloc/trunk/runtime/Makefile Message-ID: <20110403200341.0FF712A6C12C@llvm.org> Author: bglin2 Date: Sun Apr 3 15:03:40 2011 New Revision: 128795 URL: http://llvm.org/viewvc/llvm-project?rev=128795&view=rev Log: Renamed runtime directory TypeTrack to DynamicTypeChecks. Modified: poolalloc/trunk/runtime/Makefile Modified: poolalloc/trunk/runtime/Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/Makefile?rev=128795&r1=128794&r2=128795&view=diff ============================================================================== --- poolalloc/trunk/runtime/Makefile (original) +++ poolalloc/trunk/runtime/Makefile Sun Apr 3 15:03:40 2011 @@ -6,6 +6,6 @@ # # List all of the subdirectories that we will compile. # -DIRS=FreeListAllocator FL2Allocator PreRT TypeTrack +DIRS=FreeListAllocator FL2Allocator PreRT DynamicTypeChecks include $(LEVEL)/Makefile.common From echristo at apple.com Sun Apr 3 17:34:07 2011 From: echristo at apple.com (Eric Christopher) Date: Sun, 03 Apr 2011 22:34:07 -0000 Subject: [llvm-commits] [llvm] r128798 - in /llvm/trunk: include/llvm-c/Object.h lib/VMCore/CMakeLists.txt lib/VMCore/Object.cpp Message-ID: <20110403223407.6D7E62A6C12C@llvm.org> Author: echristo Date: Sun Apr 3 17:34:07 2011 New Revision: 128798 URL: http://llvm.org/viewvc/llvm-project?rev=128798&view=rev Log: Add a set of C bindings for the Object interface. Patch by Patrick Walton! Added: llvm/trunk/include/llvm-c/Object.h llvm/trunk/lib/VMCore/Object.cpp Modified: llvm/trunk/lib/VMCore/CMakeLists.txt Added: llvm/trunk/include/llvm-c/Object.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Object.h?rev=128798&view=auto ============================================================================== --- llvm/trunk/include/llvm-c/Object.h (added) +++ llvm/trunk/include/llvm-c/Object.h Sun Apr 3 17:34:07 2011 @@ -0,0 +1,77 @@ +/*===-- llvm-c/Object.h - Object Lib C Iface --------------------*- C++ -*-===*/ +/* */ +/* The LLVM Compiler Infrastructure */ +/* */ +/* This file is distributed under the University of Illinois Open Source */ +/* License. See LICENSE.TXT for details. */ +/* */ +/*===----------------------------------------------------------------------===*/ +/* */ +/* This header declares the C interface to libLLVMObject.a, which */ +/* implements object file reading and writing. */ +/* */ +/* Many exotic languages can interoperate with C code but have a harder time */ +/* with C++ due to name mangling. So in addition to C, this interface enables */ +/* tools written in such languages. */ +/* */ +/*===----------------------------------------------------------------------===*/ + +#ifndef LLVM_C_OBJECT_H +#define LLVM_C_OBJECT_H + +#include "llvm-c/Core.h" +#include "llvm/Config/llvm-config.h" + +#ifdef __cplusplus +#include "llvm/Object/ObjectFile.h" + +extern "C" { +#endif + + +typedef struct LLVMOpaqueObjectFile *LLVMObjectFileRef; + +typedef struct LLVMOpaqueSectionIterator *LLVMSectionIteratorRef; + +LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf); +void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile); + +LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile); +void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI); +LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile, + LLVMSectionIteratorRef SI); +void LLVMMoveToNextSection(LLVMSectionIteratorRef SI); +const char *LLVMGetSectionName(LLVMSectionIteratorRef SI); +uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI); +const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI); + + +#ifdef __cplusplus +} + +namespace llvm { + namespace object { + inline ObjectFile *unwrap(LLVMObjectFileRef OF) { + return reinterpret_cast(OF); + } + + inline LLVMObjectFileRef wrap(const ObjectFile *OF) { + return reinterpret_cast(const_cast(OF)); + } + + inline ObjectFile::section_iterator *unwrap(LLVMSectionIteratorRef SI) { + return reinterpret_cast(SI); + } + + inline LLVMSectionIteratorRef + wrap(const ObjectFile::section_iterator *SI) { + return reinterpret_cast + (const_cast(SI)); + } + } +} + +#endif /* defined(__cplusplus) */ + +#endif + Modified: llvm/trunk/lib/VMCore/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/CMakeLists.txt?rev=128798&r1=128797&r2=128798&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/CMakeLists.txt (original) +++ llvm/trunk/lib/VMCore/CMakeLists.txt Sun Apr 3 17:34:07 2011 @@ -24,6 +24,7 @@ LeakDetector.cpp Metadata.cpp Module.cpp + Object.cpp Pass.cpp PassManager.cpp PassRegistry.cpp Added: llvm/trunk/lib/VMCore/Object.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Object.cpp?rev=128798&view=auto ============================================================================== --- llvm/trunk/lib/VMCore/Object.cpp (added) +++ llvm/trunk/lib/VMCore/Object.cpp Sun Apr 3 17:34:07 2011 @@ -0,0 +1,59 @@ +//===- Object.cpp - C bindings to the object file library--------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the C bindings to the file-format-independent object +// library. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/ObjectFile.h" +#include "llvm-c/Object.h" + +using namespace llvm; +using namespace object; + +LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) { + return wrap(ObjectFile::createObjectFile(unwrap(MemBuf))); +} + +void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { + delete unwrap(ObjectFile); +} + +LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile) { + ObjectFile::section_iterator SI = unwrap(ObjectFile)->begin_sections(); + return wrap(new ObjectFile::section_iterator(SI)); +} + +void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) { + delete unwrap(SI); +} + +LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile, + LLVMSectionIteratorRef SI) { + return (*unwrap(SI) == unwrap(ObjectFile)->end_sections()) ? 1 : 0; +} + +void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { + // We can't use unwrap() here because the argument to ++ must be an lvalue. + ++*reinterpret_cast(SI); +} + +const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) { + return (*unwrap(SI))->getName().data(); +} + +uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) { + return (*unwrap(SI))->getSize(); +} + +const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) { + return (*unwrap(SI))->getContents().data(); +} + From echristo at apple.com Sun Apr 3 17:53:19 2011 From: echristo at apple.com (Eric Christopher) Date: Sun, 03 Apr 2011 22:53:19 -0000 Subject: [llvm-commits] [llvm] r128799 - in /llvm/trunk/lib: Object/COFFObjectFile.cpp Object/ELFObjectFile.cpp Support/Path.cpp Message-ID: <20110403225319.8C3B22A6C12C@llvm.org> Author: echristo Date: Sun Apr 3 17:53:19 2011 New Revision: 128799 URL: http://llvm.org/viewvc/llvm-project?rev=128799&view=rev Log: Assorted bugfixes in object file handling: - Adds support for sniffing PE/COFF files on win32 (.exe and .dll) which are COFF files that have an MS-DOS compatibility stub on the front of them. - Fixes a bug in the COFFObjectFile's support for the Microsoft COFF extension for long symbol names, wherein it was attempting to parse the leading '/' in an extended symbol name reference as part of the integer offset. - Fixes bugs in COFFObjectFile and ELFObjectFile wherein section and symbol iterators were being returned with uninitialized bytes; the type DataRefImpl is a union between 2 32-bit words (d.a and d.b) and a single intptr_t word (p). Only p was being initialized, so in 32-bit builds the result would be iterators with random upper 32-bit words in their DataRefImpls. This caused random failures when seeking around in object files. Patch by Graydon Hoare! Modified: llvm/trunk/lib/Object/COFFObjectFile.cpp llvm/trunk/lib/Object/ELFObjectFile.cpp llvm/trunk/lib/Support/Path.cpp Modified: llvm/trunk/lib/Object/COFFObjectFile.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/COFFObjectFile.cpp?rev=128799&r1=128798&r2=128799&view=diff ============================================================================== --- llvm/trunk/lib/Object/COFFObjectFile.cpp (original) +++ llvm/trunk/lib/Object/COFFObjectFile.cpp Sun Apr 3 17:53:19 2011 @@ -91,6 +91,7 @@ namespace { class COFFObjectFile : public ObjectFile { private: + uint64_t HeaderOff; const coff_file_header *Header; const coff_section *SectionTable; const coff_symbol *SymbolTable; @@ -256,7 +257,7 @@ // Check for string table entry. First byte is '/'. if (name[0] == '/') { uint32_t Offset; - name.getAsInteger(10, Offset); + name.substr(1).getAsInteger(10, Offset); return StringRef(getString(Offset)); } @@ -287,9 +288,20 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object) : ObjectFile(Object) { - Header = reinterpret_cast(base); + + HeaderOff = 0; + + if (base[0] == 0x4d && base[1] == 0x5a) { + // PE/COFF, seek through MS-DOS compatibility stub and 4-byte + // PE signature to find 'normal' COFF header. + HeaderOff += *reinterpret_cast(base + 0x3c); + HeaderOff += 4; + } + + Header = reinterpret_cast(base + HeaderOff); SectionTable = reinterpret_cast( base + + HeaderOff + sizeof(coff_file_header) + Header->SizeOfOptionalHeader); SymbolTable = @@ -303,6 +315,7 @@ ObjectFile::symbol_iterator COFFObjectFile::begin_symbols() const { DataRefImpl ret; + memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast(SymbolTable); return symbol_iterator(SymbolRef(ret, this)); } @@ -310,18 +323,21 @@ ObjectFile::symbol_iterator COFFObjectFile::end_symbols() const { // The symbol table ends where the string table begins. DataRefImpl ret; + memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast(StringTable); return symbol_iterator(SymbolRef(ret, this)); } ObjectFile::section_iterator COFFObjectFile::begin_sections() const { DataRefImpl ret; + memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast(SectionTable); return section_iterator(SectionRef(ret, this)); } ObjectFile::section_iterator COFFObjectFile::end_sections() const { DataRefImpl ret; + memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast(SectionTable + Header->NumberOfSections); return section_iterator(SectionRef(ret, this)); } Modified: llvm/trunk/lib/Object/ELFObjectFile.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/ELFObjectFile.cpp?rev=128799&r1=128798&r2=128799&view=diff ============================================================================== --- llvm/trunk/lib/Object/ELFObjectFile.cpp (original) +++ llvm/trunk/lib/Object/ELFObjectFile.cpp Sun Apr 3 17:53:19 2011 @@ -547,6 +547,7 @@ ObjectFile::section_iterator ELFObjectFile ::begin_sections() const { DataRefImpl ret; + memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast(base + Header->e_shoff); return section_iterator(SectionRef(ret, this)); } @@ -555,6 +556,7 @@ ObjectFile::section_iterator ELFObjectFile ::end_sections() const { DataRefImpl ret; + memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast(base + Header->e_shoff + (Header->e_shentsize * Header->e_shnum)); Modified: llvm/trunk/lib/Support/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Path.cpp?rev=128799&r1=128798&r2=128799&view=diff ============================================================================== --- llvm/trunk/lib/Support/Path.cpp (original) +++ llvm/trunk/lib/Support/Path.cpp Sun Apr 3 17:53:19 2011 @@ -15,11 +15,15 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Config/config.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Endian.h" #include #include #include using namespace llvm; using namespace sys; +namespace { +using support::ulittle32_t; +} //===----------------------------------------------------------------------===// //=== WARNING: Implementation here must contain only TRULY operating system @@ -129,6 +133,16 @@ if (magic[1] == 0x02) return COFF_FileType; break; + + case 0x4d: // Possible MS-DOS stub on Windows PE file + if (magic[1] == 0x5a) { + uint32_t off = *reinterpret_cast(magic + 0x3c); + // PE/COFF file, either EXE or DLL. + if (off < length && memcmp(magic + off, "PE\0\0",4) == 0) + return COFF_FileType; + } + break; + case 0x64: // x86-64 Windows. if (magic[1] == char(0x86)) return COFF_FileType; From echristo at apple.com Sun Apr 3 18:07:51 2011 From: echristo at apple.com (Eric Christopher) Date: Sun, 03 Apr 2011 23:07:51 -0000 Subject: [llvm-commits] [llvm] r128800 - in /llvm/trunk/lib: Object/CMakeLists.txt Object/Object.cpp VMCore/CMakeLists.txt VMCore/Object.cpp Message-ID: <20110403230751.523BE2A6C12C@llvm.org> Author: echristo Date: Sun Apr 3 18:07:51 2011 New Revision: 128800 URL: http://llvm.org/viewvc/llvm-project?rev=128800&view=rev Log: Move Object.cpp out of VMCore and into Object. Added: llvm/trunk/lib/Object/Object.cpp - copied unchanged from r128798, llvm/trunk/lib/VMCore/Object.cpp Removed: llvm/trunk/lib/VMCore/Object.cpp Modified: llvm/trunk/lib/Object/CMakeLists.txt llvm/trunk/lib/VMCore/CMakeLists.txt Modified: llvm/trunk/lib/Object/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/CMakeLists.txt?rev=128800&r1=128799&r2=128800&view=diff ============================================================================== --- llvm/trunk/lib/Object/CMakeLists.txt (original) +++ llvm/trunk/lib/Object/CMakeLists.txt Sun Apr 3 18:07:51 2011 @@ -1,5 +1,6 @@ add_llvm_library(LLVMObject MachOObject.cpp + Object.cpp ObjectFile.cpp COFFObjectFile.cpp ELFObjectFile.cpp Modified: llvm/trunk/lib/VMCore/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/CMakeLists.txt?rev=128800&r1=128799&r2=128800&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/CMakeLists.txt (original) +++ llvm/trunk/lib/VMCore/CMakeLists.txt Sun Apr 3 18:07:51 2011 @@ -24,7 +24,6 @@ LeakDetector.cpp Metadata.cpp Module.cpp - Object.cpp Pass.cpp PassManager.cpp PassRegistry.cpp Removed: llvm/trunk/lib/VMCore/Object.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Object.cpp?rev=128799&view=auto ============================================================================== --- llvm/trunk/lib/VMCore/Object.cpp (original) +++ llvm/trunk/lib/VMCore/Object.cpp (removed) @@ -1,59 +0,0 @@ -//===- Object.cpp - C bindings to the object file library--------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the C bindings to the file-format-independent object -// library. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Object/ObjectFile.h" -#include "llvm-c/Object.h" - -using namespace llvm; -using namespace object; - -LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) { - return wrap(ObjectFile::createObjectFile(unwrap(MemBuf))); -} - -void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { - delete unwrap(ObjectFile); -} - -LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile) { - ObjectFile::section_iterator SI = unwrap(ObjectFile)->begin_sections(); - return wrap(new ObjectFile::section_iterator(SI)); -} - -void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) { - delete unwrap(SI); -} - -LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile, - LLVMSectionIteratorRef SI) { - return (*unwrap(SI) == unwrap(ObjectFile)->end_sections()) ? 1 : 0; -} - -void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { - // We can't use unwrap() here because the argument to ++ must be an lvalue. - ++*reinterpret_cast(SI); -} - -const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) { - return (*unwrap(SI))->getName().data(); -} - -uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) { - return (*unwrap(SI))->getSize(); -} - -const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) { - return (*unwrap(SI))->getContents().data(); -} - From pichet2000 at gmail.com Sun Apr 3 18:41:25 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Sun, 3 Apr 2011 19:41:25 -0400 Subject: [llvm-commits] [llvm] r128782 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/Utils/Local.cpp test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll In-Reply-To: <20110402224517.C24E52A6C12C@llvm.org> References: <20110402224517.C24E52A6C12C@llvm.org> Message-ID: On Sat, Apr 2, 2011 at 6:45 PM, Eli Friedman wrote: > Author: efriedma > Date: Sat Apr ?2 17:45:17 2011 > New Revision: 128782 > > URL: http://llvm.org/viewvc/llvm-project?rev=128782&view=rev > Log: > PR9446: RecursivelyDeleteTriviallyDeadInstructions can delete the instruction > after the given instruction; make sure to handle that case correctly. > (It's difficult to trigger; the included testcase involves a dead > block, but I don't think that's a requirement.) > > While I'm here, get rid of the unnecessary warning about > SimplifyInstructionsInBlock, since it should work correctly as far as I know. > > > Added: > ? ?llvm/trunk/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll > Modified: > ? ?llvm/trunk/include/llvm/Transforms/Utils/Local.h > ? ?llvm/trunk/lib/Transforms/Utils/Local.cpp > > Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=128782&r1=128781&r2=128782&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) > +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Sat Apr ?2 17:45:17 2011 > @@ -74,10 +74,6 @@ > ?/// > ?/// This returns true if it changed the code, note that it can delete > ?/// instructions in other blocks as well in this block. > -/// > -/// WARNING: Do not use this function on unreachable blocks, as recursive > -/// simplification is not able to handle corner-case scenarios that can > -/// arise in them. > ?bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0); > > ?//===----------------------------------------------------------------------===// > > Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=128782&r1=128781&r2=128782&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) > +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Sat Apr ?2 17:45:17 2011 > @@ -332,8 +332,11 @@ > ? ? ? ? BI = BB->begin(); > ? ? ? continue; > ? ? } > - > + > + ? ?WeakVH BIHandle(BI); Here BI can be equal to BB->end() Hence an end iterator is dereferenced causing the crash in WeakVH constructor on MSVC From echristo at apple.com Sun Apr 3 18:51:48 2011 From: echristo at apple.com (Eric Christopher) Date: Sun, 03 Apr 2011 23:51:48 -0000 Subject: [llvm-commits] [llvm] r128801 - in /llvm/trunk: include/llvm/Object/MachOObject.h lib/Object/MachOObject.cpp tools/macho-dump/macho-dump.cpp Message-ID: <20110403235148.145CA2A6C12C@llvm.org> Author: echristo Date: Sun Apr 3 18:51:47 2011 New Revision: 128801 URL: http://llvm.org/viewvc/llvm-project?rev=128801&view=rev Log: Start migrating mach-o dumping facilities to the object file out of a separate executable. Modified: llvm/trunk/include/llvm/Object/MachOObject.h llvm/trunk/lib/Object/MachOObject.cpp llvm/trunk/tools/macho-dump/macho-dump.cpp Modified: llvm/trunk/include/llvm/Object/MachOObject.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachOObject.h?rev=128801&r1=128800&r2=128801&view=diff ============================================================================== --- llvm/trunk/include/llvm/Object/MachOObject.h (original) +++ llvm/trunk/include/llvm/Object/MachOObject.h Sun Apr 3 18:51:47 2011 @@ -19,6 +19,7 @@ namespace llvm { class MemoryBuffer; +class raw_ostream; namespace object { @@ -172,7 +173,26 @@ InMemoryStruct &Res) const; /// @} + + /// @name Object Dump Facilities + /// @{ + /// dump - Support for debugging, callable in GDB: V->dump() + // + void dump() const; + void dumpHeader() const; + + /// print - Implement operator<< on Value. + /// + void print(raw_ostream &O) const; + void printHeader(raw_ostream &O) const; + + /// @} }; + +inline raw_ostream &operator<<(raw_ostream &OS, const MachOObject &V) { + V.print(OS); + return OS; +} } // end namespace object } // end namespace llvm Modified: llvm/trunk/lib/Object/MachOObject.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObject.cpp?rev=128801&r1=128800&r2=128801&view=diff ============================================================================== --- llvm/trunk/lib/Object/MachOObject.cpp (original) +++ llvm/trunk/lib/Object/MachOObject.cpp Sun Apr 3 18:51:47 2011 @@ -12,6 +12,8 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Host.h" #include "llvm/Support/SwapByteOrder.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Debug.h" using namespace llvm; using namespace llvm::object; @@ -340,3 +342,29 @@ Index * sizeof(macho::Symbol64TableEntry)); ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); } + +/* ** */ +// Object Dumping Facilities +void MachOObject::dump() const { print(dbgs()); dbgs() << '\n'; } +void MachOObject::dumpHeader() const { printHeader(dbgs()); dbgs() << '\n'; } + +void MachOObject::printHeader(raw_ostream &O) const { + O << "('cputype', " << Header.CPUType << ")\n"; + O << "('cpusubtype', " << Header.CPUSubtype << ")\n"; + O << "('filetype', " << Header.FileType << ")\n"; + O << "('num_load_commands', " << Header.NumLoadCommands << ")\n"; + O << "('load_commands_size', " << Header.SizeOfLoadCommands << ")\n"; + O << "('flag', " << Header.Flags << ")\n"; + + // Print extended header if 64-bit. + if (is64Bit()) + O << "('reserved', " << Header64Ext.Reserved << ")\n"; +} + +void MachOObject::print(raw_ostream &O) const { + O << "Header:\n"; + printHeader(O); + O << "Load Commands:\n"; + + O << "Buffer:\n"; +} Modified: llvm/trunk/tools/macho-dump/macho-dump.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/macho-dump/macho-dump.cpp?rev=128801&r1=128800&r2=128801&view=diff ============================================================================== --- llvm/trunk/tools/macho-dump/macho-dump.cpp (original) +++ llvm/trunk/tools/macho-dump/macho-dump.cpp Sun Apr 3 18:51:47 2011 @@ -376,8 +376,8 @@ if (!InputObject) return Error("unable to load object: '" + ErrorStr + "'"); - if (int Res = DumpHeader(*InputObject)) - return Res; + // Print the header + InputObject->printHeader(outs()); // Print the load commands. int Res = 0; From eli.friedman at gmail.com Sun Apr 3 19:37:38 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 04 Apr 2011 00:37:38 -0000 Subject: [llvm-commits] [llvm] r128802 - /llvm/trunk/lib/Transforms/Utils/Local.cpp Message-ID: <20110404003738.41B6B2A6C12C@llvm.org> Author: efriedma Date: Sun Apr 3 19:37:38 2011 New Revision: 128802 URL: http://llvm.org/viewvc/llvm-project?rev=128802&view=rev Log: Attempt to fix breakage from r128782 reported by Francois Pichet on llvm-commits. (Not sure why it only breaks on Windows; maybe it has something to do with the iterator representation...) Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=128802&r1=128801&r2=128802&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Sun Apr 3 19:37:38 2011 @@ -333,6 +333,9 @@ continue; } + if (Inst->isTerminator()) + break; + WeakVH BIHandle(BI); MadeChange |= RecursivelyDeleteTriviallyDeadInstructions(Inst); if (BIHandle != BI) From eli.friedman at gmail.com Sun Apr 3 19:43:10 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Sun, 3 Apr 2011 17:43:10 -0700 Subject: [llvm-commits] [llvm] r128782 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/Utils/Local.cpp test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll In-Reply-To: References: <20110402224517.C24E52A6C12C@llvm.org> Message-ID: On Sun, Apr 3, 2011 at 4:41 PM, Francois Pichet wrote: > On Sat, Apr 2, 2011 at 6:45 PM, Eli Friedman wrote: >> Author: efriedma >> Date: Sat Apr ?2 17:45:17 2011 >> New Revision: 128782 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=128782&view=rev >> Log: >> PR9446: RecursivelyDeleteTriviallyDeadInstructions can delete the instruction >> after the given instruction; make sure to handle that case correctly. >> (It's difficult to trigger; the included testcase involves a dead >> block, but I don't think that's a requirement.) >> >> While I'm here, get rid of the unnecessary warning about >> SimplifyInstructionsInBlock, since it should work correctly as far as I know. >> >> >> Added: >> ? ?llvm/trunk/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll >> Modified: >> ? ?llvm/trunk/include/llvm/Transforms/Utils/Local.h >> ? ?llvm/trunk/lib/Transforms/Utils/Local.cpp >> >> Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=128782&r1=128781&r2=128782&view=diff >> ============================================================================== >> --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) >> +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Sat Apr ?2 17:45:17 2011 >> @@ -74,10 +74,6 @@ >> ?/// >> ?/// This returns true if it changed the code, note that it can delete >> ?/// instructions in other blocks as well in this block. >> -/// >> -/// WARNING: Do not use this function on unreachable blocks, as recursive >> -/// simplification is not able to handle corner-case scenarios that can >> -/// arise in them. >> ?bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0); >> >> ?//===----------------------------------------------------------------------===// >> >> Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=128782&r1=128781&r2=128782&view=diff >> ============================================================================== >> --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) >> +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Sat Apr ?2 17:45:17 2011 >> @@ -332,8 +332,11 @@ >> ? ? ? ? BI = BB->begin(); >> ? ? ? continue; >> ? ? } >> - >> + >> + ? ?WeakVH BIHandle(BI); > > Here BI can be equal to BB->end() > Hence an end iterator is dereferenced causing the crash in WeakVH > constructor on MSVC Ah, of course; try r128802? -Eli From aggarwa4 at illinois.edu Sun Apr 3 19:46:18 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 04 Apr 2011 00:46:18 -0000 Subject: [llvm-commits] [poolalloc] r128803 - in /poolalloc/trunk/test/dsa/types: mrv.ll mrv1.ll Message-ID: <20110404004618.AEA872A6C12C@llvm.org> Author: aggarwa4 Date: Sun Apr 3 19:46:18 2011 New Revision: 128803 URL: http://llvm.org/viewvc/llvm-project?rev=128803&view=rev Log: Examples for MRV cases. Modified: poolalloc/trunk/test/dsa/types/mrv.ll poolalloc/trunk/test/dsa/types/mrv1.ll Modified: poolalloc/trunk/test/dsa/types/mrv.ll URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/types/mrv.ll?rev=128803&r1=128802&r2=128803&view=diff ============================================================================== --- poolalloc/trunk/test/dsa/types/mrv.ll (original) +++ poolalloc/trunk/test/dsa/types/mrv.ll Sun Apr 3 19:46:18 2011 @@ -2,7 +2,7 @@ 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-n8:16:32:64" target triple = "x86_64-unknown-linux-gnu" -;RUN: dsaopt %s -dsa-local -analyze -check-type=main:s:0,0:float|double::4:float::8:float +;RUN: dsaopt %s -dsa-local -analyze -check-type=main:s,0:float|double::4:float::8:float ; Function foo, actually accepts an object of struct S. But as ; per calling conventions, the value is passed in registers, after Modified: poolalloc/trunk/test/dsa/types/mrv1.ll URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/types/mrv1.ll?rev=128803&r1=128802&r2=128803&view=diff ============================================================================== --- poolalloc/trunk/test/dsa/types/mrv1.ll (original) +++ poolalloc/trunk/test/dsa/types/mrv1.ll Sun Apr 3 19:46:18 2011 @@ -4,8 +4,8 @@ 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-n8:16:32:64" target triple = "x86_64-unknown-linux-gnu" -;RUN: dsaopt %s -dsa-local -analyze -check-type=main:s:0,0:float|double::4:float::8:float -;RUN: dsaopt %s -dsa-local -analyze -check-type=main:s1:0,0:float::4:float::8:float +;RUN: dsaopt %s -dsa-local -analyze -check-type=main:s,0:float|double::4:float::8:float +;RUN: dsaopt %s -dsa-local -analyze -check-type=main:s1,0:float::4:float::8:float %0 = type { double, float } %struct.S = type { float, float, float } From pichet2000 at gmail.com Sun Apr 3 20:00:28 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Sun, 3 Apr 2011 21:00:28 -0400 Subject: [llvm-commits] [llvm] r128782 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/Utils/Local.cpp test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll In-Reply-To: References: <20110402224517.C24E52A6C12C@llvm.org> Message-ID: On Sun, Apr 3, 2011 at 8:43 PM, Eli Friedman wrote: > On Sun, Apr 3, 2011 at 4:41 PM, Francois Pichet wrote: >> On Sat, Apr 2, 2011 at 6:45 PM, Eli Friedman wrote: >>> Author: efriedma >>> Date: Sat Apr ?2 17:45:17 2011 >>> New Revision: 128782 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=128782&view=rev >>> Log: >>> PR9446: RecursivelyDeleteTriviallyDeadInstructions can delete the instruction >>> after the given instruction; make sure to handle that case correctly. >>> (It's difficult to trigger; the included testcase involves a dead >>> block, but I don't think that's a requirement.) >>> >>> While I'm here, get rid of the unnecessary warning about >>> SimplifyInstructionsInBlock, since it should work correctly as far as I know. >>> >>> >>> Added: >>> ? ?llvm/trunk/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll >>> Modified: >>> ? ?llvm/trunk/include/llvm/Transforms/Utils/Local.h >>> ? ?llvm/trunk/lib/Transforms/Utils/Local.cpp >>> >>> Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=128782&r1=128781&r2=128782&view=diff >>> ============================================================================== >>> --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) >>> +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Sat Apr ?2 17:45:17 2011 >>> @@ -74,10 +74,6 @@ >>> ?/// >>> ?/// This returns true if it changed the code, note that it can delete >>> ?/// instructions in other blocks as well in this block. >>> -/// >>> -/// WARNING: Do not use this function on unreachable blocks, as recursive >>> -/// simplification is not able to handle corner-case scenarios that can >>> -/// arise in them. >>> ?bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0); >>> >>> ?//===----------------------------------------------------------------------===// >>> >>> Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=128782&r1=128781&r2=128782&view=diff >>> ============================================================================== >>> --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) >>> +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Sat Apr ?2 17:45:17 2011 >>> @@ -332,8 +332,11 @@ >>> ? ? ? ? BI = BB->begin(); >>> ? ? ? continue; >>> ? ? } >>> - >>> + >>> + ? ?WeakVH BIHandle(BI); >> >> Here BI can be equal to BB->end() >> Hence an end iterator is dereferenced causing the crash in WeakVH >> constructor on MSVC > > Ah, of course; try r128802? > > -Eli Problem fixed. From peter at pcc.me.uk Sun Apr 3 19:57:03 2011 From: peter at pcc.me.uk (Peter Collingbourne) Date: Mon, 04 Apr 2011 00:57:03 -0000 Subject: [llvm-commits] [llvm] r128804 - /llvm/trunk/include/llvm/ADT/IntrusiveRefCntPtr.h Message-ID: <20110404005703.3C59B2A6C12C@llvm.org> Author: pcc Date: Sun Apr 3 19:57:03 2011 New Revision: 128804 URL: http://llvm.org/viewvc/llvm-project?rev=128804&view=rev Log: IntrusiveRefCntPtr: in RefCountedBase and RefCountedBaseVPTR, make ref_cnt mutable and Retain/Release const to enable reference counted pointers to const objects Modified: llvm/trunk/include/llvm/ADT/IntrusiveRefCntPtr.h Modified: llvm/trunk/include/llvm/ADT/IntrusiveRefCntPtr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/IntrusiveRefCntPtr.h?rev=128804&r1=128803&r2=128804&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/IntrusiveRefCntPtr.h (original) +++ llvm/trunk/include/llvm/ADT/IntrusiveRefCntPtr.h Sun Apr 3 19:57:03 2011 @@ -42,15 +42,15 @@ //===----------------------------------------------------------------------===// template class RefCountedBase { - unsigned ref_cnt; + mutable unsigned ref_cnt; public: RefCountedBase() : ref_cnt(0) {} - void Retain() { ++ref_cnt; } - void Release() { + void Retain() const { ++ref_cnt; } + void Release() const { assert (ref_cnt > 0 && "Reference count is already zero."); - if (--ref_cnt == 0) delete static_cast(this); + if (--ref_cnt == 0) delete static_cast(this); } }; @@ -63,14 +63,14 @@ /// attempting to do this will produce a compile error. //===----------------------------------------------------------------------===// class RefCountedBaseVPTR { - unsigned ref_cnt; + mutable unsigned ref_cnt; protected: RefCountedBaseVPTR() : ref_cnt(0) {} virtual ~RefCountedBaseVPTR() {} - void Retain() { ++ref_cnt; } - void Release() { + void Retain() const { ++ref_cnt; } + void Release() const { assert (ref_cnt > 0 && "Reference count is already zero."); if (--ref_cnt == 0) delete this; } From aggarwa4 at illinois.edu Sun Apr 3 20:03:06 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 04 Apr 2011 01:03:06 -0000 Subject: [llvm-commits] [poolalloc] r128805 - /poolalloc/trunk/test/dsa/local/memcpy.ll Message-ID: <20110404010306.4027B2A6C12C@llvm.org> Author: aggarwa4 Date: Sun Apr 3 20:03:06 2011 New Revision: 128805 URL: http://llvm.org/viewvc/llvm-project?rev=128805&view=rev Log: Test for the memcpy intrinsic. Added: poolalloc/trunk/test/dsa/local/memcpy.ll Added: poolalloc/trunk/test/dsa/local/memcpy.ll URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/local/memcpy.ll?rev=128805&view=auto ============================================================================== --- poolalloc/trunk/test/dsa/local/memcpy.ll (added) +++ poolalloc/trunk/test/dsa/local/memcpy.ll Sun Apr 3 20:03:06 2011 @@ -0,0 +1,24 @@ +; RUN: dsaopt %s -dsa-local -analyze -check-same-node=test:P,test:Q +; RUN: llvm-as %s -o /dev/null +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-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +define void @test(i32* %P, i32* %Q) { +entry: + %tmp.1 = bitcast i32* %P to i8* ; [#uses=3] + %tmp.3 = bitcast i32* %Q to i8* ; [#uses=4] + tail call void @llvm.memcpy.i32( i8* %tmp.1, i8* %tmp.3, i32 100000, i32 1 ) + tail call void @llvm.memcpy.i64( i8* %tmp.1, i8* %tmp.3, i64 100000, i32 1 ) + tail call void @llvm.memset.i32( i8* %tmp.3, i8 14, i32 10000, i32 0 ) + tail call void @llvm.memmove.i32( i8* %tmp.1, i8* %tmp.3, i32 123124, i32 1 ) + ret void +} + +declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) + +declare void @llvm.memcpy.i64(i8*, i8*, i64, i32) + +declare void @llvm.memset.i32(i8*, i8, i32, i32) + +declare void @llvm.memmove.i32(i8*, i8*, i32, i32) + From etherzhhb at gmail.com Sun Apr 3 22:27:07 2011 From: etherzhhb at gmail.com (ether zhhb) Date: Mon, 4 Apr 2011 11:27:07 +0800 Subject: [llvm-commits] [PATCH 1/2] Region: Check the exit region before use it when expanding a region. Message-ID: >From 0c43ee6358a05b19b6b9924e5de3074216b7bcd5 Mon Sep 17 00:00:00 2001 From: ether Date: Mon, 4 Apr 2011 11:24:37 +0800 Subject: [PATCH 1/2] Region: Check the exit region before use it when expanding a region. --- lib/Analysis/RegionInfo.cpp | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/lib/Analysis/RegionInfo.cpp b/lib/Analysis/RegionInfo.cpp index e2f6a8b..a5250cf 100644 --- a/lib/Analysis/RegionInfo.cpp +++ b/lib/Analysis/RegionInfo.cpp @@ -394,6 +394,9 @@ Region *Region::getExpandedRegion() const { Region *R = RI->getRegionFor(exit); + if (!R) + llvm_unreachable(("Can not find exit for region: " + getNameStr()).c_str()); + if (R->getEntry() != exit) { if (exit->getTerminator()->getNumSuccessors() == 1) return new Region(getEntry(), *succ_begin(exit), RI, DT); -- 1.7.3.3 From etherzhhb at gmail.com Sun Apr 3 22:31:48 2011 From: etherzhhb at gmail.com (ether zhhb) Date: Mon, 4 Apr 2011 11:31:48 +0800 Subject: [llvm-commits] Subject: [PATCH 2/2] Region: Allow user control the printing style of the print function. Message-ID: hi, This patch allow user to control the printing style of the Region's print method by calling it with a PrintStyle parameter like: R->print(dbgs(), true, 0, Region::PrintRN/*Print the region with hireachy style*/); best regards ether --- include/llvm/Analysis/RegionInfo.h | 6 +++++- lib/Analysis/RegionInfo.cpp | 32 ++++++++++++++++---------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h index a36ca11..9b4b637 100644 --- a/include/llvm/Analysis/RegionInfo.h +++ b/include/llvm/Analysis/RegionInfo.h @@ -335,12 +335,16 @@ public: return RI; } + /// PrintStyle - Print region in difference ways. + enum PrintStyle { PrintNone, PrintBB, PrintRN }; + /// @brief Print the region. /// /// @param OS The output stream the Region is printed to. /// @param printTree Print also the tree of subregions. /// @param level The indentation level used for printing. - void print(raw_ostream& OS, bool printTree = true, unsigned level = 0) const; + void print(raw_ostream& OS, bool printTree = true, unsigned level = 0, + enum PrintStyle Style = PrintNone) const; /// @brief Print the region to stderr. void dump() const; diff --git a/lib/Analysis/RegionInfo.cpp b/lib/Analysis/RegionInfo.cpp index a5250cf..e6df424 100644 --- a/lib/Analysis/RegionInfo.cpp +++ b/lib/Analysis/RegionInfo.cpp @@ -41,16 +41,15 @@ VerifyRegionInfoX("verify-region-info", cl::location(VerifyRegionInfo), STATISTIC(numRegions, "The # of regions"); STATISTIC(numSimpleRegions, "The # of simple regions"); -//===----------------------------------------------------------------------===// -/// PrintStyle - Print region in difference ways. -enum PrintStyle { PrintNone, PrintBB, PrintRN }; - -static cl::opt printStyle("print-region-style", cl::Hidden, +static cl::opt printStyle("print-region-style", + cl::Hidden, cl::desc("style of printing regions"), cl::values( - clEnumValN(PrintNone, "none", "print no details"), - clEnumValN(PrintBB, "bb", "print regions in detail with block_iterator"), - clEnumValN(PrintRN, "rn", "print regions in detail with element_iterator"), + clEnumValN(Region::PrintNone, "none", "print no details"), + clEnumValN(Region::PrintBB, "bb", + "print regions in detail with block_iterator"), + clEnumValN(Region::PrintRN, "rn", + "print regions in detail with element_iterator"), clEnumValEnd)); //===----------------------------------------------------------------------===// /// Region Implementation @@ -416,7 +415,8 @@ Region *Region::getExpandedRegion() const { return new Region(getEntry(), R->getExit(), RI, DT); } -void Region::print(raw_ostream &OS, bool print_tree, unsigned level) const { +void Region::print(raw_ostream &OS, bool print_tree, unsigned level, + enum PrintStyle Style) const { if (print_tree) OS.indent(level*2) << "[" << level << "] " << getNameStr(); else @@ -425,14 +425,14 @@ void Region::print(raw_ostream &OS, bool print_tree, unsigned level) const { OS << "\n"; - if (printStyle != PrintNone) { + if (Style != PrintNone) { OS.indent(level*2) << "{\n"; OS.indent(level*2 + 2); - if (printStyle == PrintBB) { + if (Style == PrintBB) { for (const_block_iterator I = block_begin(), E = block_end(); I!=E; ++I) OS << **I << ", "; // TODO: remove the last "," - } else if (printStyle == PrintRN) { + } else if (Style == PrintRN) { for (const_element_iterator I = element_begin(), E = element_end(); I!=E; ++I) OS << **I << ", "; // TODO: remove the last ", } @@ -442,14 +442,14 @@ void Region::print(raw_ostream &OS, bool print_tree, unsigned level) const { if (print_tree) for (const_iterator RI = begin(), RE = end(); RI != RE; ++RI) - (*RI)->print(OS, print_tree, level+1); + (*RI)->print(OS, print_tree, level+1, Style); - if (printStyle != PrintNone) + if (Style != PrintNone) OS.indent(level*2) << "} \n"; } void Region::dump() const { - print(dbgs(), true, getDepth()); + print(dbgs(), true, getDepth(), printStyle.getValue()); } void Region::clearNodeCache() { @@ -717,7 +717,7 @@ void RegionInfo::getAnalysisUsage(AnalysisUsage &AU) const { void RegionInfo::print(raw_ostream &OS, const Module *) const { OS << "Region tree:\n"; - TopLevelRegion->print(OS, true, 0); + TopLevelRegion->print(OS, true, 0, printStyle.getValue()); OS << "End region tree\n"; } -- 1.7.3.3 -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-Region-Allow-user-control-the-printing-style-of-the-.patch Type: application/octet-stream Size: 4633 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110404/76646e43/attachment-0001.obj From matthieu.monrocq at gmail.com Sat Apr 2 04:45:47 2011 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Sat, 2 Apr 2011 11:45:47 +0200 Subject: [llvm-commits] LLVM Transform Passes web page fixes Message-ID: Hello, Here is a small patch fixing the broken links on the 3 sections of the LLVM's Analysis and Transform Passes page. Matthieu. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110402/95635967/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm_passes_html.patch Type: application/octet-stream Size: 1217 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110402/95635967/attachment.obj From wingedtachikoma at gmail.com Sat Apr 2 23:56:26 2011 From: wingedtachikoma at gmail.com (Sean Bartell) Date: Sun, 3 Apr 2011 00:56:26 -0400 Subject: [llvm-commits] [PATCH] Use predicates more often when optimizing for size Message-ID: <20110403045626.GA27536@flcl.lan> When optimizing for size, we want to use predicates instead of branches to save a few instructions. Predicates are used when the resulting code is at least 1/2 as fast as with branching; this includes almost all cases where predicates can be used. There are, of course, other heuristics--I think GCC just uses a limit of 8 instructions. Tested with make check in LLVM. I'd appreciate any feedback, since if I'm accepted into GSoC I'll be doing this much more often :). Thanks, Sean Bartell -------------- next part -------------- >From 58b8afd57058f6acc2662a879290a56351bd19d2 Mon Sep 17 00:00:00 2001 From: Sean Bartell Date: Sat, 2 Apr 2011 23:32:56 -0400 Subject: [PATCH] Use predicates more often when optimizing for size. When optimizing for size, we want to use predicates instead of branches to save a few instructions. Predicates are used when the resulting code is at least 1/2 as fast as with branching; this includes almost all cases where predicates can be used. --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 8 +++++ test/CodeGen/ARM/ifcvt12.ll | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 0 deletions(-) create mode 100644 test/CodeGen/ARM/ifcvt12.ll diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 1acad9d..95a3067 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1282,6 +1282,10 @@ bool ARMBaseInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB, UnpredCost += 1.0; // The branch itself UnpredCost += (1.0 - Confidence) * Subtarget.getMispredictionPenalty(); + // If optimizing for size, use predication if it's up to twice as slow. + if (MBB.getParent()->getFunction()->hasFnAttr(Attribute::OptimizeForSize)) + UnpredCost *= 2; + return (float)(NumCyles + ExtraPredCycles) < UnpredCost; } @@ -1299,6 +1303,10 @@ isProfitableToIfCvt(MachineBasicBlock &TMBB, UnpredCost += 1.0; // The branch itself UnpredCost += (1.0 - Confidence) * Subtarget.getMispredictionPenalty(); + // If optimizing for size, use predication if it's up to twice as slow. + if (TMBB.getParent()->getFunction()->hasFnAttr(Attribute::OptimizeForSize)) + UnpredCost *= 2; + return (float)(TCycles + FCycles + TExtra + FExtra) < UnpredCost; } diff --git a/test/CodeGen/ARM/ifcvt12.ll b/test/CodeGen/ARM/ifcvt12.ll new file mode 100644 index 0000000..83b52a1 --- /dev/null +++ b/test/CodeGen/ARM/ifcvt12.ll @@ -0,0 +1,49 @@ +; RUN: llc < %s -march=arm | FileCheck %s +; Use predicates more often when optimizing for size. + +define i32 @t1(i32 %x) nounwind optsize { +; CHECK: t1: +; CHECK-NOT: blt +; CHECK-NOT: bge +entry: + %0 = icmp sgt i32 %x, 17 + br i1 %0, label %bb1, label %bb2 + +; CHECK: subge +bb1: + %1 = sub i32 %x, 61 + %2 = mul i32 %1, 3 + br label %end + +bb2: + %3 = mul i32 %x, 5 + %4 = add i32 %3, 25 + br label %end + +end: + %5 = phi i32 [ %2, %bb1 ], [ %4, %bb2] + ret i32 %5 +} + +define i32 @t2(i32 %x) nounwind optsize { +; CHECK: t2: +; CHECK-NOT: bxlt +; CHECK-NOT: blt +entry: + %0 = icmp sgt i32 %x, 17 + br i1 %0, label %bb1, label %end + +; CHECK: subge +; CHECK: andge +bb1: + %1 = sub i32 %x, 61 + %2 = mul i32 %1, 3 + %3 = and i32 %2, 25 + %4 = mul i32 %3, 5 + br label %end + +end: + %5 = phi i32 [ %4, %bb1 ], [ %x, %entry ] + %6 = xor i32 %5, 17 + ret i32 %6 +} -- 1.7.4.2

    The members of enumeration types (tag = DW_TAG_enumeration_type) are enumerator descriptors, each representing - the definition of enumeration value for the set.