From pichet2000 at gmail.com Mon Jun 20 00:19:38 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Mon, 20 Jun 2011 05:19:38 -0000 Subject: [llvm-commits] [llvm] r133416 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp Message-ID: <20110620051938.26D432A6C12C@llvm.org> Author: fpichet Date: Mon Jun 20 00:19:37 2011 New Revision: 133416 URL: http://llvm.org/viewvc/llvm-project?rev=133416&view=rev Log: Fix MSVC build. next() function already exists in the MSVC headers. This create a overload conflict. Make sure we pick up the llvm one. Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=133416&r1=133415&r2=133416&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Mon Jun 20 00:19:37 2011 @@ -635,7 +635,7 @@ << "From simple Succ: " << *TailBB); MachineBasicBlock *NewTarget = *TailBB->succ_begin(); - MachineBasicBlock *NextBB = next(MachineFunction::iterator(PredBB)); + MachineBasicBlock *NextBB = llvm::next(MachineFunction::iterator(PredBB)); DenseMap LocalVRMap; SmallVector, 4> CopyInfos; From pichet2000 at gmail.com Mon Jun 20 00:30:21 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Mon, 20 Jun 2011 01:30:21 -0400 Subject: [llvm-commits] [llvm] r133415 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp In-Reply-To: <20110620041635.302E52A6C12C@llvm.org> References: <20110620041635.302E52A6C12C@llvm.org> Message-ID: On Mon, Jun 20, 2011 at 12:16 AM, Rafael Espindola wrote: > Author: rafael > Date: Sun Jun 19 23:16:35 2011 > New Revision: 133415 > > URL: http://llvm.org/viewvc/llvm-project?rev=133415&view=rev > Log: > Teach early dup how to duplicate basic blocks with one successor and only phi instructions > into more complex blocks. > > Modified: > ? ?llvm/trunk/lib/CodeGen/TailDuplication.cpp > > Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=133415&r1=133414&r2=133415&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) > +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Sun Jun 19 23:16:35 2011 > @@ -96,6 +96,12 @@ > ? ? bool TailDuplicateBlocks(MachineFunction &MF); > ? ? bool shouldTailDuplicate(const MachineFunction &MF, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?MachineBasicBlock &TailBB); > + ? ?bool isSimpleBB(MachineBasicBlock *TailBB); > + ? ?bool canCompletelyDuplicateSimpleBB(MachineBasicBlock &BB); > + ? ?bool duplicateSimpleBB(MachineBasicBlock *TailBB, > + ? ? ? ? ? ? ? ? ? ? ? ? ? SmallVector &TDBBs, > + ? ? ? ? ? ? ? ? ? ? ? ? ? const DenseSet &RegsUsedByPhi, > + ? ? ? ? ? ? ? ? ? ? ? ? ? SmallVector &Copies); > ? ? bool TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF, > ? ? ? ? ? ? ? ? ? ? ? ?SmallVector &TDBBs, > ? ? ? ? ? ? ? ? ? ? ? ?SmallVector &Copies); > @@ -557,6 +563,136 @@ > ? return true; > ?} > > +/// isSimpleBB - True if this BB has only one unconditional jump. > +bool > +TailDuplicatePass::isSimpleBB(MachineBasicBlock *TailBB) { > + ?if (TailBB->succ_size() != 1) > + ? ?return false; > + ?MachineBasicBlock::iterator I = TailBB->getFirstNonPHI(); > + ?MachineBasicBlock::iterator E = TailBB->end(); > + ?while (I->isDebugValue() && I != E) > + ? ?++I; > + ?if (I == E) > + ? ?return true; > + ?return I->getDesc().isUnconditionalBranch(); > +} > + > +static bool > +bothUsedInPHI(const MachineBasicBlock &A, > + ? ? ? ? ? ? ?SmallPtrSet SuccsB) { > + ?for (MachineBasicBlock::const_succ_iterator SI = A.succ_begin(), > + ? ? ? ? SE = A.succ_end(); SI != SE; ++SI) { > + ? ?MachineBasicBlock *BB = *SI; > + ? ?if (SuccsB.count(BB) && !BB->empty() && BB->begin()->isPHI()) > + ? ? ?return true; > + ?} > + > + ?return false; > +} > + > +bool > +TailDuplicatePass::canCompletelyDuplicateSimpleBB(MachineBasicBlock &BB) { > + ?SmallPtrSet Succs(BB.succ_begin(), BB.succ_end()); > + > + ?for (MachineBasicBlock::pred_iterator PI = BB.pred_begin(), > + ? ? ? PE = BB.pred_end(); PI != PE; ++PI) { > + ? ?MachineBasicBlock *PredBB = *PI; > + ? ?if (PredBB->getLandingPadSuccessor()) > + ? ? ?return false; > + ? ?if (bothUsedInPHI(*PredBB, Succs)) > + ? ? ?return false; > + ? ?MachineBasicBlock *PredTBB = NULL, *PredFBB = NULL; > + ? ?SmallVector PredCond; > + ? ?if (TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond, true)) > + ? ? ?return false; > + ?} > + ?return true; > +} > + > +bool > +TailDuplicatePass::duplicateSimpleBB(MachineBasicBlock *TailBB, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SmallVector &TDBBs, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const DenseSet &UsedByPhi, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SmallVector &Copies) { > + ?if (!canCompletelyDuplicateSimpleBB(*TailBB)) > + ? ?return false; > + > + ?bool Changed = false; > + ?SmallVector Preds(TailBB->pred_begin(), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TailBB->pred_end()); > + ?for (SmallSetVector::iterator PI = Preds.begin(), > + ? ? ? PE = Preds.end(); PI != PE; ++PI) { > + ? ?MachineBasicBlock *PredBB = *PI; > + > + ? ?MachineBasicBlock *PredTBB = NULL, *PredFBB = NULL; > + ? ?SmallVector PredCond; > + ? ?bool NotAnalyzable = > + ? ? ?TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond, true); > + ? ?(void)NotAnalyzable; > + ? ?assert(!NotAnalyzable && "Cannot duplicate this!"); > + > + ? ?DEBUG(dbgs() << "\nTail-duplicating into PredBB: " << *PredBB > + ? ? ? ? ? ? ? ? << "From simple Succ: " << *TailBB); > + > + ? ?MachineBasicBlock *NewTarget = *TailBB->succ_begin(); > + ? ?MachineBasicBlock *NextBB = next(MachineFunction::iterator(PredBB)); Hi, I made a small change here for MSVC compatibility, See r133416 From nadav.rotem at intel.com Mon Jun 20 02:15:58 2011 From: nadav.rotem at intel.com (Nadav Rotem) Date: Mon, 20 Jun 2011 07:15:58 -0000 Subject: [llvm-commits] [llvm] r133424 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp test/CodeGen/X86/promote-trunc.ll Message-ID: <20110620071558.D31AE2A6C12C@llvm.org> Author: nadav Date: Mon Jun 20 02:15:58 2011 New Revision: 133424 URL: http://llvm.org/viewvc/llvm-project?rev=133424&view=rev Log: Fix PromoteIntRes_TRUNCATE: Add support for cases where the source vector type is to be split while the target vector is to be promoted. (eg: <4 x i64> -> <4 x i8> ) Added: llvm/trunk/test/CodeGen/X86/promote-trunc.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=133424&r1=133423&r2=133424&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Mon Jun 20 02:15:58 2011 @@ -520,20 +520,44 @@ SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) { EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); SDValue Res; + SDValue InOp = N->getOperand(0); + DebugLoc dl = N->getDebugLoc(); - switch (getTypeAction(N->getOperand(0).getValueType())) { + switch (getTypeAction(InOp.getValueType())) { default: llvm_unreachable("Unknown type action!"); case TargetLowering::TypeLegal: case TargetLowering::TypeExpandInteger: - Res = N->getOperand(0); + Res = InOp; break; case TargetLowering::TypePromoteInteger: - Res = GetPromotedInteger(N->getOperand(0)); + Res = GetPromotedInteger(InOp); break; + case TargetLowering::TypeSplitVector: + EVT InVT = InOp.getValueType(); + assert(InVT.isVector() && "Cannot split scalar types"); + unsigned NumElts = InVT.getVectorNumElements(); + assert(NumElts == NVT.getVectorNumElements() && + "Dst and Src must have the same number of elements"); + EVT EltVT = InVT.getScalarType(); + assert(isPowerOf2_32(NumElts) && + "Promoted vector type must be a power of two"); + + EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts/2); + EVT HalfNVT = EVT::getVectorVT(*DAG.getContext(), NVT.getScalarType(), + NumElts/2); + + SDValue EOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HalfVT, InOp, + DAG.getIntPtrConstant(0)); + SDValue EOp2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HalfVT, InOp, + DAG.getIntPtrConstant(NumElts/2)); + EOp1 = DAG.getNode(ISD::TRUNCATE, dl, HalfNVT, EOp1); + EOp2 = DAG.getNode(ISD::TRUNCATE, dl, HalfNVT, EOp2); + + return DAG.getNode(ISD::CONCAT_VECTORS, dl, NVT, EOp1, EOp2); } // Truncate to NVT instead of VT - return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), NVT, Res); + return DAG.getNode(ISD::TRUNCATE, dl, NVT, Res); } SDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) { Added: llvm/trunk/test/CodeGen/X86/promote-trunc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/promote-trunc.ll?rev=133424&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/promote-trunc.ll (added) +++ llvm/trunk/test/CodeGen/X86/promote-trunc.ll Mon Jun 20 02:15:58 2011 @@ -0,0 +1,11 @@ +; RUN: llc -promote-elements < %s -march=x86-64 + +define<4 x i8> @func_8_64() { + %F = load <4 x i64>* undef + %G = trunc <4 x i64> %F to <4 x i8> + %H = load <4 x i64>* undef + %Y = trunc <4 x i64> %H to <4 x i8> + %T = add <4 x i8> %Y, %G + ret <4 x i8> %T +} + From baldrick at free.fr Mon Jun 20 02:29:30 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Jun 2011 09:29:30 +0200 Subject: [llvm-commits] [llvm] r133285 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp In-Reply-To: <54E09593-01A1-4936-AFF8-7AF19D2C6919@apple.com> References: <20110617202152.D6B812A6C12C@llvm.org> <4DFDF276.5030703@free.fr> <54E09593-01A1-4936-AFF8-7AF19D2C6919@apple.com> Message-ID: <4DFEF6DA.4030503@free.fr> Hi John, > On Jun 19, 2011, at 5:58 AM, Duncan Sands wrote: >>> + // Insist that the amount-to-allocate not overflow. >>> + OverflowingBinaryOperator *OBI = dyn_cast(Val); >>> + if (OBI&& !OBI->hasNoUnsignedWrap()) return 0; >> >> I noticed you dropped the test for NSW. I thought this was a problem because >> front-ends generally don't ever produce NUW, though they may produce NSW... > > Stuart asked me to look at this, and I gave him a quick answer > that it's generally correct for nuw arithmetic, but that I wasn't as > certain for nsw arithmetic. Now I think it's probably fine for either > as long as it's homogenous throughout. > > The main restriction on the alloca size argument can be expressed as: > (N * sizeof(T)) udiv sizeof(T) == N > However, there's a second restriction, which is that it's undefined > behavior to allocate something too large for the stack. Technically > this is target-specific, but if we just assume by fiat that 2^31 is too large, > then as long as the arithmetic is being done in some reasonable size > then we know that N * sizeof(T) isn't permitted to signed overflow, either. if you are willing to assume that then you don't need to check for nuw either... I think I saw some GCC testcases fly by in which people were allocating stack objects larger than 2^32, so I'm not sure that "N * sizeof(T) < 2^31" is a reasonable assumption... About nsw: if you assume than N and sizeof(T) are both less than 2^31, then they are non-negative as signed numbers. If you have the nsw flag then you know that (N * sizeof(T)) is non-negative as a signed number. This implies that there was no unsigned wrap either, so all is OK. I'm willing to assume that sizeof(T) is less than 2^31, but I'm not sure about N. Ciao, Duncan. From baldrick at free.fr Mon Jun 20 02:43:10 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Jun 2011 07:43:10 -0000 Subject: [llvm-commits] [dragonegg] r133427 - in /dragonegg/trunk: Makefile README extras/do_self_strap gcc-patches/ www/index.html Message-ID: <20110620074311.1AA7B2A6C12D@llvm.org> Author: baldrick Date: Mon Jun 20 02:43:10 2011 New Revision: 133427 URL: http://llvm.org/viewvc/llvm-project?rev=133427&view=rev Log: Dragonegg no longer requires a patched version of gcc. Update the docs to reflect that. Also, change the Makefile so that it defaults to building for "gcc" rather than "gcc-4.5". Use the GCC variable to override as explained in the README. Removed: dragonegg/trunk/gcc-patches/ Modified: dragonegg/trunk/Makefile dragonegg/trunk/README dragonegg/trunk/extras/do_self_strap dragonegg/trunk/www/index.html Modified: dragonegg/trunk/Makefile URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Makefile?rev=133427&r1=133426&r2=133427&view=diff ============================================================================== --- dragonegg/trunk/Makefile (original) +++ dragonegg/trunk/Makefile Mon Jun 20 02:43:10 2011 @@ -1,5 +1,5 @@ # Specify the gcc executable you will use the dragonegg plugin with here. -GCC?=gcc-4.5 +GCC?=gcc # Specify the copy of LLVM you will build the plugin against by giving its # llvm-config here. To use an installed copy of LLVM, specify the installed Modified: dragonegg/trunk/README URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/README?rev=133427&r1=133426&r2=133427&view=diff ============================================================================== --- dragonegg/trunk/README (original) +++ dragonegg/trunk/README Mon Jun 20 02:43:10 2011 @@ -2,95 +2,60 @@ - BUILD INSTRUCTIONS - ---------------------- -Step 0: Build and install llvm ------------------------------- +Prerequisites +------------- -I'm assuming anyone reading this knows how to build and install llvm. -You need the latest llvm from the subversion repository. +The dragonegg plugin works with gcc 4.5 or gcc 4.6, so you will need to have one +of these installed. Many linux distributions ship one or both of them, perhaps +as an addon package; binaries can be downloaded for most platforms. Otherwise +you can always build one of these gcc versions yourself. Both plugin support +(--enable-plugin) and support for link time optimization (--enable-lto) need +to be enabled in gcc, but since they are enabled by default on most platforms +this should be the case. -Step 1: Build gcc ------------------ +Step 0: Build and install llvm +------------------------------ -Obtain a copy of the source code for the gcc-4.5 release. You can get it from -one of the gcc mirrors, see http://gcc.gnu.org/mirrors.html. Alternatively, you -can use the gcc-4.5 branch of the gcc subversion repository: - svn checkout svn://gcc.gnu.org/svn/gcc/branches/gcc-4_5-branch SomeLocalDir -If you are feeling brave then you can try gcc mainline: - svn checkout svn://gcc.gnu.org/svn/gcc/trunk SomeLocalDir -Changes on gcc mainline occasionally break the plugin, so your mileage may vary. -You can find a subversion revision number that is known to work well in the file -gcc_revision_tested_with (in the same directory as this README). - -Apply the patches in the gcc-patches subdirectory, if any. The following should -do the trick ("SomeLocalDir" is where you checked/unpacked the gcc source): - cat gcc-patches/*.diff | patch -d SomeLocalDir -p1 - -Configure gcc with your favorite options and also with --enable-plugin and ---enable-lto. Build gcc and install it somewhere. If you don't have libelf -installed then the configure step may fail because the configure script thinks -that LTO requires libelf, though in fact it does not when using dragonegg. See - http://gcc.gnu.org/wiki/LinkTimeOptimization#Building_the_branch -In theory the gcc you build can be a cross-compiler, and the plugin should work -and build code for the targeted platform. I don't think anyone has ever tried -this though. - -Darwin special: the gcc configure script thinks darwin doesn't support dynamic -libraries and concludes that plugins won't work. You can find patches to fix -this here: -http://gcc.gnu.org/ml/gcc-patches/2010-04/msg00610.html -NOTE: This may be fixed in gcc mainline (gcc 4.6). - -Darwin special 2: the gcc configure script thinks darwin doesn't support LTO -because it is not an ELF platform. Dragonegg repurposes the LTO infrastructure, -and thus needs LTO support enabled, but it makes no use of the parts of LTO that -require ELF. You just need to turn off the ELF check in the configure script. -If anyone has a patch to do this, I will be happy to add it here! -NOTE: This is fixed in gcc mainline (gcc 4.6). +I'm assuming anyone reading this knows how to build and install llvm. The +version of llvm must match the version of the plugin, so if you are building +dragonegg-3.0 then you should use llvm-3.0, while if you are building the +development version of dragonegg then use the development version of llvm. -Step 2: Build the plugin +Step 1: Build the plugin ------------------------ Build the plugin like this: - GCC=PATH_TO_JUST_INSTALLED_GCC make -This should be done in the directory containing this README. + GCC=PATH_TO_INSTALLED_GCC make +This command should be executed in the directory containing this README. The plugin needs to know about the version of gcc it will be loaded into, which -is why you need to specify the gcc installed in step 1 via the GCC variable like -this. If you have arranged for the new gcc to occur in your path with the name -gcc-4.5 (using a symbolic link for example) then you can build the plugin using: +is why you need to specify your version of gcc 4.5/4.6 via the GCC variable like +this. If you don't set the GCC variable then by default "gcc" is used, so you +can just do make +to build if your system gcc is gcc version 4.5 or 4.6. + The plugin is compiled using the system compiler, and not with the gcc specified -in the GCC variable (which wouldn't work if you built a cross compiler). If you -want to also compile the plugin with the new gcc, you can do: - CC=PATH_TO_JUST_INSTALLED_GCC CXX=PATH_TO_JUST_INSTALLED_GCC GCC=PATH_TO_JUST_INSTALLED_GCC make +in the GCC variable (which wouldn't work if it is a cross compiler). If you +want to also compile the plugin with your copy gcc 4.5/4.6, you can do: + CC=PATH_TO_INSTALLED_GCC CXX=PATH_TO_INSTALLED_GCC GCC=PATH_TO_INSTALLED_GCC make The build system runs the "llvm-config" program (which should be in your path if -you installed LLVM properly in step 0) to find out about the copy of LLVM you +you installed llvm properly in step 0) to find out about the copy of LLVM you installed, so there is no need to tell the build system explicitly about LLVM. If llvm-config is not in your path then you can specify where to find it using the LLVM_CONFIG variable. The end result of the build is a shared library, dragonegg.so. -------------------------- -- COMMON BUILD PROBLEMS - -------------------------- - -To build gcc-4.5 you need the GMP, MPC and MPFR libraries. If you installed the -libraries locally, so their header files are not in the standard system include -path, then the dragonegg build will probably fail due to failing to find header -files like mpc.h. To solve this, use CPPFLAGS to add additional include paths, -for example: - CPPFLAGS="-I/path/to/header/files" make - ---------------------- - USAGE INSTRUCTIONS - ---------------------- Run gcc as usual, but pass -fplugin=./dragonegg.so as an extra command line -argument. Make sure you use the gcc you installed above, not the system gcc! +argument. Make sure you use the gcc you built dragonegg against (see step 1)! ------------------ Modified: dragonegg/trunk/extras/do_self_strap URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/extras/do_self_strap?rev=133427&r1=133426&r2=133427&view=diff ============================================================================== --- dragonegg/trunk/extras/do_self_strap (original) +++ dragonegg/trunk/extras/do_self_strap Mon Jun 20 02:43:10 2011 @@ -100,19 +100,11 @@ svn co -r $GCC_REVISION svn://gcc.gnu.org/svn/gcc/branches/gcc-4_5-branch $GCC_SOURCE elif [ ! -L $GCC_SOURCE ] ; then # Do not update symbolic links. This is # for the benefit of the buildbots. - echo "Reverting any applied patches" - svn revert -R $GCC_SOURCE/gcc echo "Updating GCC" svn update -r $GCC_REVISION $GCC_SOURCE fi -# Apply any needed patches to GCC -for PATCH in $DRAGONEGG_SOURCE/gcc-patches/*.diff ; do - echo "Applying patch $PATCH" - patch -d $GCC_SOURCE -p1 < $PATCH -done - PLUGIN_OPTION= # No plugin yet PREV_DRAGONEGG_BUILD= # No previous dragonegg for STAGE in $STAGES ; do Modified: dragonegg/trunk/www/index.html URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/www/index.html?rev=133427&r1=133426&r2=133427&view=diff ============================================================================== --- dragonegg/trunk/www/index.html (original) +++ dragonegg/trunk/www/index.html Mon Jun 20 02:43:10 2011 @@ -37,19 +37,22 @@
    -
  • C works well, for example you can build a working gcc using it
  • +
  • C works well, for example you can build a working gcc using it.
  • C++ works fairly well, for example you can build LLVM, clang and boost with it (the resulting LLVM and clang work correctly; boost mostly works but - there are some mysterious failures)
  • + there are some mysterious failures).
  • Fortran works fairly well, for example SPEC CPU mostly compiles and works, - but there are some failures
  • + but there are some failures. These have all been fixed in the development + version.
  • 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 can compile simple Java programs
  • -
  • Limited debug info
  • -
  • Requires patching gcc
  • -
  • Only supports x86-32 and x86-64
  • + work. +
  • It can compile a small amount of Obj-C and Obj-C++.
  • +
  • It can compile simple Java programs, but they don't execute properly + (this is a consequence of the java front-end not supporting GCC's LTO).
  • +
  • Limited debug info.
  • +
  • Versions 2.9 and earlier require patching gcc (the development version + does not).
  • +
  • Only supports x86-32 and x86-64.
  • Only supports linux, darwin and freebsd (additional gcc patches may be needed on darwin, see the README file).
@@ -278,12 +281,7 @@
	svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm

Build LLVM in the usual way.

-

Get the gcc-4.5 source code:

-
	svn co http://gcc.gnu.org/svn/gcc/branches/gcc-4_5-branch gcc-4.5
-

Apply all of the patches in dragonegg/gcc-patches/, if any, to the - gcc-4.5 source. You need to pass the -p1 option to patch. - Build and install gcc-4.5 in the - usual way.

+

Install gcc-4.5 or gcc-4.6 (you do not need to build your own copy).

Doing

	GCC=path_to_just_installed_gcc make

in the dragonegg directory should then build dragonegg.so. From baldrick at free.fr Mon Jun 20 04:26:23 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Jun 2011 09:26:23 -0000 Subject: [llvm-commits] [llvm] r133430 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp Message-ID: <20110620092623.C8B2C2A6C12C@llvm.org> Author: baldrick Date: Mon Jun 20 04:26:23 2011 New Revision: 133430 URL: http://llvm.org/viewvc/llvm-project?rev=133430&view=rev Log: Disable the logic added by rafael in commit 133415 to see if it brings the dragonegg buildbots back to life. Original commit message: Teach early dup how to duplicate basic blocks with one successor and only phi instructions into more complex blocks. Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=133430&r1=133429&r2=133430&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Mon Jun 20 04:26:23 2011 @@ -707,7 +707,7 @@ DenseSet UsedByPhi; getRegsUsedByPHIs(*TailBB, &UsedByPhi); - if (isSimpleBB(TailBB)) + if (0 && isSimpleBB(TailBB)) // Disabled to see if doing so fixes buildbots. return duplicateSimpleBB(TailBB, TDBBs, UsedByPhi, Copies); // Iterate through all the unique predecessors and tail-duplicate this From baldrick at free.fr Mon Jun 20 05:02:06 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Jun 2011 10:02:06 -0000 Subject: [llvm-commits] [dragonegg] r133431 - /dragonegg/trunk/src/Debug.cpp Message-ID: <20110620100206.4410F2A6C12C@llvm.org> Author: baldrick Date: Mon Jun 20 05:02:06 2011 New Revision: 133431 URL: http://llvm.org/viewvc/llvm-project?rev=133431&view=rev Log: TYPE_DEBUG_REPRESENTATION_TYPE was removed in gcc-4.6. Handle VECTOR_TYPE directly. Modified: dragonegg/trunk/src/Debug.cpp Modified: dragonegg/trunk/src/Debug.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Debug.cpp?rev=133431&r1=133430&r2=133431&view=diff ============================================================================== --- dragonegg/trunk/src/Debug.cpp (original) +++ dragonegg/trunk/src/Debug.cpp Mon Jun 20 05:02:06 2011 @@ -619,9 +619,6 @@ return DIType(); } - if (TREE_CODE(type) == VECTOR_TYPE) - type = TREE_TYPE (TYPE_FIELDS (TYPE_DEBUG_REPRESENTATION_TYPE (type))); - // Add the dimensions of the array. FIXME: This loses CV qualifiers from // interior arrays, do we care? Why aren't nested arrays represented the // obvious/recursive way? @@ -629,24 +626,29 @@ // There will be ARRAY_TYPE nodes for each rank. Followed by the derived // type. - tree atype = type; - tree EltTy = TREE_TYPE(atype); - for (; TREE_CODE(atype) == ARRAY_TYPE; - atype = TREE_TYPE(atype)) { - tree Domain = TYPE_DOMAIN(atype); - if (Domain) { - // FIXME - handle dynamic ranges - tree MinValue = TYPE_MIN_VALUE(Domain); - tree MaxValue = TYPE_MAX_VALUE(Domain); - uint64_t Low = 0; - uint64_t Hi = 0; - if (isInt64(MinValue, false)) - Low = getINTEGER_CSTVal(MinValue); - if (isInt64(MaxValue, false)) - Hi = getINTEGER_CSTVal(MaxValue); - Subscripts.push_back(DebugFactory.GetOrCreateSubrange(Low, Hi)); + tree EltTy = TREE_TYPE(type); + if (TREE_CODE(type) == ARRAY_TYPE) { + tree atype = type; + for (; TREE_CODE(atype) == ARRAY_TYPE; atype = TREE_TYPE(atype)) { + tree Domain = TYPE_DOMAIN(atype); + if (Domain) { + // FIXME - handle dynamic ranges + tree MinValue = TYPE_MIN_VALUE(Domain); + tree MaxValue = TYPE_MAX_VALUE(Domain); + uint64_t Low = 0; + uint64_t Hi = 0; + if (isInt64(MinValue, false)) + Low = getINTEGER_CSTVal(MinValue); + if (isInt64(MaxValue, false)) + Hi = getINTEGER_CSTVal(MaxValue); + Subscripts.push_back(DebugFactory.GetOrCreateSubrange(Low, Hi)); + } + EltTy = TREE_TYPE(atype); } - EltTy = TREE_TYPE(atype); + } else { + assert(TREE_CODE(type) == VECTOR_TYPE && "Not an array or vector type!"); + unsigned Length = TYPE_VECTOR_SUBPARTS(type); + Subscripts.push_back(DebugFactory.GetOrCreateSubrange(0, Length)); } llvm::DIArray SubscriptArray = From justin.holewinski at gmail.com Mon Jun 20 07:53:26 2011 From: justin.holewinski at gmail.com (Justin Holewinski) Date: Mon, 20 Jun 2011 08:53:26 -0400 Subject: [llvm-commits] [PATCH][Target/PTX] Add address_size directive to PTX backend In-Reply-To: <20110620015129.GA56262@cs.nctu.edu.tw> References: <20110617073109.GA93378@cs.nctu.edu.tw> <20110618065617.GA25444@cs.nctu.edu.tw> <20110619121258.GA50677@cs.nctu.edu.tw> <347A9771-6ADD-4454-86D6-2842AEA82D44@gmail.com> <20110620015129.GA56262@cs.nctu.edu.tw> Message-ID: On Jun 19, 2011, at 9:51 PM, ??? wrote: > Hi, Justin > >>> What you want is removing FeatureAddrSize32/64 from PTX.td to avoid >>> user intervention, right? PTXAddrSize is assigned accroding to the >>> 32/64-bit flag, >>> >>> // PTXSubtarget ctor in PTXSubtarget.cpp >>> PTXAddrSize = is64Bit? PTX_AddrSize_64 : PTX_AddrSize_32; >> >> Correct. > > Fixed. I hate to nit-pick, but do we really need the address size field and associated enumeration? It's always tied to the 64-bit flag, and we do not need to create any TableGen predicates from the value. I think this patch can be as simple as: if (ST.supportsPTX23()) { std::string addrSize = is64Bit() ? "64" : "32"; OutStreamer.EmitRawText(Twine("\t.address_size " + addrSize)); } ? with the appropriate test cases. > > Regards, > chenwj > > -- > Wei-Ren Chen (???) > Computer Systems Lab, Institute of Information Science, > Academia Sinica, Taiwan (R.O.C.) > Tel:886-2-2788-3799 #1667 > Thanks, Justin Holewinski -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110620/ed2b0928/attachment.html From rafael.espindola at gmail.com Mon Jun 20 09:11:42 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Mon, 20 Jun 2011 14:11:42 -0000 Subject: [llvm-commits] [llvm] r133432 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp Message-ID: <20110620141142.A6EDD2A6C12C@llvm.org> Author: rafael Date: Mon Jun 20 09:11:42 2011 New Revision: 133432 URL: http://llvm.org/viewvc/llvm-project?rev=133432&view=rev Log: Re enable 133415 with two fixes * Don't introduce a duplicated bb in the CFG * When making a branch unconditional, clear the PredCond array so that it is really unconditional. Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=133432&r1=133431&r2=133432&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Mon Jun 20 09:11:42 2011 @@ -669,8 +669,10 @@ PredTBB = NewTarget; // Make the branch unconditional if possible - if (PredTBB == PredFBB) + if (PredTBB == PredFBB) { + PredCond.clear(); PredFBB = NULL; + } // Avoid adding fall through branches. if (PredFBB == NextBB) @@ -684,7 +686,10 @@ TII->InsertBranch(*PredBB, PredTBB, PredFBB, PredCond, DebugLoc()); PredBB->removeSuccessor(TailBB); - PredBB->addSuccessor(NewTarget); + unsigned NumSuccessors = PredBB->succ_size(); + assert(NumSuccessors <= 1); + if (NumSuccessors == 0 || *PredBB->succ_begin() != NewTarget) + PredBB->addSuccessor(NewTarget); TDBBs.push_back(PredBB); @@ -707,7 +712,7 @@ DenseSet UsedByPhi; getRegsUsedByPHIs(*TailBB, &UsedByPhi); - if (0 && isSimpleBB(TailBB)) // Disabled to see if doing so fixes buildbots. + if (isSimpleBB(TailBB)) return duplicateSimpleBB(TailBB, TDBBs, UsedByPhi, Copies); // Iterate through all the unique predecessors and tail-duplicate this From jay.foad at gmail.com Mon Jun 20 09:12:33 2011 From: jay.foad at gmail.com (Jay Foad) Date: Mon, 20 Jun 2011 14:12:33 -0000 Subject: [llvm-commits] [llvm] r133433 - in /llvm/trunk: include/llvm/Use.h lib/VMCore/Use.cpp lib/VMCore/User.cpp Message-ID: <20110620141233.7A0872A6C12C@llvm.org> Author: foad Date: Mon Jun 20 09:12:33 2011 New Revision: 133433 URL: http://llvm.org/viewvc/llvm-project?rev=133433&view=rev Log: Remove the AugmentedUse struct. I don't think the AugmentedUse struct buys us much, either in correctness or in ease of use. Ditch it, and simplify Use::getUser() and User::allocHungoffUses(). Modified: llvm/trunk/include/llvm/Use.h llvm/trunk/lib/VMCore/Use.cpp llvm/trunk/lib/VMCore/User.cpp Modified: llvm/trunk/include/llvm/Use.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Use.h?rev=133433&r1=133432&r2=133433&view=diff ============================================================================== --- llvm/trunk/include/llvm/Use.h (original) +++ llvm/trunk/include/llvm/Use.h Mon Jun 20 09:12:33 2011 @@ -60,6 +60,10 @@ /// that also works with less standard-compliant compilers void swap(Use &RHS); + // A type for the word following an array of hung-off Uses in memory, which is + // a pointer back to their User with the bottom bit set. + typedef PointerIntPair UserRef; + private: /// Copy ctor - do not implement Use(const Use &U); @@ -208,15 +212,6 @@ unsigned getOperandNo() const; }; -//===----------------------------------------------------------------------===// -// AugmentedUse layout struct -//===----------------------------------------------------------------------===// - -struct AugmentedUse : public Use { - PointerIntPair ref; - AugmentedUse(); // not implemented -}; - } // End llvm namespace #endif Modified: llvm/trunk/lib/VMCore/Use.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Use.cpp?rev=133433&r1=133432&r2=133433&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Use.cpp (original) +++ llvm/trunk/lib/VMCore/Use.cpp Mon Jun 20 09:12:33 2011 @@ -135,11 +135,9 @@ User *Use::getUser() const { const Use *End = getImpliedUser(); - const PointerIntPair& - ref(static_cast(End - 1)->ref); - User *She = ref.getPointer(); - return ref.getInt() - ? She + const UserRef *ref = reinterpret_cast(End); + return ref->getInt() + ? ref->getPointer() : (User*)End; } Modified: llvm/trunk/lib/VMCore/User.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/User.cpp?rev=133433&r1=133432&r2=133433&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/User.cpp (original) +++ llvm/trunk/lib/VMCore/User.cpp Mon Jun 20 09:12:33 2011 @@ -41,13 +41,9 @@ Use *User::allocHungoffUses(unsigned N) const { Use *Begin = static_cast(::operator new(sizeof(Use) * N - + sizeof(AugmentedUse) - - sizeof(Use))); + + sizeof(Use::UserRef))); Use *End = Begin + N; - PointerIntPair& - ref(static_cast(End[-1]).ref); - ref.setPointer(const_cast(this)); - ref.setInt(1); + (void) new(End) Use::UserRef(const_cast(this), 1); return Use::initTags(Begin, End); } From jay.foad at gmail.com Mon Jun 20 09:18:48 2011 From: jay.foad at gmail.com (Jay Foad) Date: Mon, 20 Jun 2011 14:18:48 -0000 Subject: [llvm-commits] [llvm] r133434 - in /llvm/trunk/lib: Bitcode/Writer/BitcodeWriter.cpp Target/CppBackend/CPPBackend.cpp Transforms/Scalar/GVN.cpp Transforms/Scalar/LoopRotation.cpp VMCore/AsmWriter.cpp VMCore/BasicBlock.cpp VMCore/Verifier.cpp Message-ID: <20110620141848.567952A6C12C@llvm.org> Author: foad Date: Mon Jun 20 09:18:48 2011 New Revision: 133434 URL: http://llvm.org/viewvc/llvm-project?rev=133434&view=rev Log: Make better use of the PHINode API. Change various bits of code to make better use of the existing PHINode API, to insulate them from forthcoming changes in how PHINodes store their operands. Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp llvm/trunk/lib/VMCore/AsmWriter.cpp llvm/trunk/lib/VMCore/BasicBlock.cpp llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=133434&r1=133433&r2=133434&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Jun 20 09:18:48 2011 @@ -1079,12 +1079,16 @@ AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV; break; - case Instruction::PHI: + case Instruction::PHI: { + const PHINode &PN = cast(I); Code = bitc::FUNC_CODE_INST_PHI; - Vals.push_back(VE.getTypeID(I.getType())); - for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) - Vals.push_back(VE.getValueID(I.getOperand(i))); + Vals.push_back(VE.getTypeID(PN.getType())); + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { + Vals.push_back(VE.getValueID(PN.getIncomingValue(i))); + Vals.push_back(VE.getValueID(PN.getIncomingBlock(i))); + } break; + } case Instruction::Alloca: Code = bitc::FUNC_CODE_INST_ALLOCA; Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=133434&r1=133433&r2=133434&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Mon Jun 20 09:18:48 2011 @@ -1353,9 +1353,10 @@ printEscapedString(phi->getName()); Out << "\", " << bbname << ");"; nl(Out); - for (unsigned i = 0; i < phi->getNumOperands(); i+=2) { + for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) { Out << iName << "->addIncoming(" - << opNames[i] << ", " << opNames[i+1] << ");"; + << opNames[PHINode::getOperandNumForIncomingValue(i)] << ", " + << opNames[PHINode::getOperandNumForIncomingBlock(i)] << ");"; nl(Out); } break; Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=133434&r1=133433&r2=133434&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Mon Jun 20 09:18:48 2011 @@ -1190,8 +1190,10 @@ // escaping uses to any values that are operands to these PHIs. for (unsigned i = 0, e = NewPHIs.size(); i != e; ++i) { PHINode *P = NewPHIs[i]; - for (unsigned ii = 0, ee = P->getNumIncomingValues(); ii != ee; ++ii) - AA->addEscapingUse(P->getOperandUse(2*ii)); + for (unsigned ii = 0, ee = P->getNumIncomingValues(); ii != ee; ++ii) { + unsigned jj = PHINode::getOperandNumForIncomingValue(ii); + AA->addEscapingUse(P->getOperandUse(jj)); + } } } @@ -2149,8 +2151,11 @@ // Because we have added a PHI-use of the pointer value, it has now // "escaped" from alias analysis' perspective. We need to inform // AA of this. - for (unsigned ii = 0, ee = Phi->getNumIncomingValues(); ii != ee; ++ii) - VN.getAliasAnalysis()->addEscapingUse(Phi->getOperandUse(2*ii)); + for (unsigned ii = 0, ee = Phi->getNumIncomingValues(); ii != ee; + ++ii) { + unsigned jj = PHINode::getOperandNumForIncomingValue(ii); + VN.getAliasAnalysis()->addEscapingUse(Phi->getOperandUse(jj)); + } if (MD) MD->invalidateCachedPointerInfo(Phi); Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=133434&r1=133433&r2=133434&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Mon Jun 20 09:18:48 2011 @@ -220,7 +220,7 @@ // For PHI nodes, the value available in OldPreHeader is just the // incoming value from OldPreHeader. for (; PHINode *PN = dyn_cast(I); ++I) - ValueMap[PN] = PN->getIncomingValue(PN->getBasicBlockIndex(OrigPreheader)); + ValueMap[PN] = PN->getIncomingValueForBlock(OrigPreheader); // For the rest of the instructions, either hoist to the OrigPreheader if // possible or create a clone in the OldPreHeader if not. Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=133434&r1=133433&r2=133434&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Mon Jun 20 09:18:48 2011 @@ -1905,16 +1905,16 @@ writeOperand(I.getOperand(i), true); } Out << ']'; - } else if (isa(I)) { + } else if (const PHINode *PN = dyn_cast(&I)) { Out << ' '; TypePrinter.print(I.getType(), Out); Out << ' '; - for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) { + for (unsigned op = 0, Eop = PN->getNumIncomingValues(); op < Eop; ++op) { if (op) Out << ", "; Out << "[ "; - writeOperand(I.getOperand(op ), false); Out << ", "; - writeOperand(I.getOperand(op+1), false); Out << " ]"; + writeOperand(PN->getIncomingValue(op), false); Out << ", "; + writeOperand(PN->getIncomingBlock(op), false); Out << " ]"; } } else if (const ExtractValueInst *EVI = dyn_cast(&I)) { Out << ' '; Modified: llvm/trunk/lib/VMCore/BasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/BasicBlock.cpp?rev=133434&r1=133433&r2=133434&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/BasicBlock.cpp (original) +++ llvm/trunk/lib/VMCore/BasicBlock.cpp Mon Jun 20 09:18:48 2011 @@ -227,8 +227,8 @@ // If the PHI _HAD_ two uses, replace PHI node with its now *single* value if (max_idx == 2) { - if (PN->getOperand(0) != PN) - PN->replaceAllUsesWith(PN->getOperand(0)); + if (PN->getIncomingValue(0) != PN) + PN->replaceAllUsesWith(PN->getIncomingValue(0)); else // We are left with an infinite loop with no entries: kill the PHI. PN->replaceAllUsesWith(UndefValue::get(PN->getType())); Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=133434&r1=133433&r2=133434&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Mon Jun 20 09:18:48 2011 @@ -1482,8 +1482,10 @@ // PHI nodes differ from other nodes because they actually "use" the // value in the predecessor basic blocks they correspond to. BasicBlock *UseBlock = BB; - if (isa(I)) - UseBlock = dyn_cast(I.getOperand(i+1)); + if (PHINode *PN = dyn_cast(&I)) { + unsigned j = PHINode::getIncomingValueNumForOperand(i); + UseBlock = PN->getIncomingBlock(j); + } Assert2(UseBlock, "Invoke operand is PHI node with bad incoming-BB", Op, &I); @@ -1515,10 +1517,11 @@ return; } } - } else if (isa(I)) { + } else if (PHINode *PN = dyn_cast(&I)) { // PHI nodes are more difficult than other nodes because they actually // "use" the value in the predecessor basic blocks they correspond to. - BasicBlock *PredBB = dyn_cast(I.getOperand(i+1)); + unsigned j = PHINode::getIncomingValueNumForOperand(i); + BasicBlock *PredBB = PN->getIncomingBlock(j); Assert2(PredBB && (DT->dominates(OpBlock, PredBB) || !DT->isReachableFromEntry(PredBB)), "Instruction does not dominate all uses!", Op, &I); From jay.foad at gmail.com Mon Jun 20 09:38:01 2011 From: jay.foad at gmail.com (Jay Foad) Date: Mon, 20 Jun 2011 14:38:01 -0000 Subject: [llvm-commits] [llvm] r133435 - in /llvm/trunk: include/llvm/ include/llvm/Support/ lib/Target/CppBackend/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ Message-ID: <20110620143801.6C0D72A6C124@llvm.org> Author: foad Date: Mon Jun 20 09:38:01 2011 New Revision: 133435 URL: http://llvm.org/viewvc/llvm-project?rev=133435&view=rev Log: Change how PHINodes store their operands. Change PHINodes to store simple pointers to their incoming basic blocks, instead of full-blown Uses. Note that this loses an optimization in SplitCriticalEdge(), because we can no longer walk the use list of a BasicBlock to find phi nodes. See the comment I removed starting "However, the foreach loop is slow for blocks with lots of predecessors". Extend replaceAllUsesWith() on a BasicBlock to also update any phi nodes in the block's successors. This mimics what would have happened when PHINodes were proper Users of their incoming blocks. (Note that this only works if OldBB->replaceAllUsesWith(NewBB) is called when OldBB still has a terminator instruction, so it still has some successors.) Modified: llvm/trunk/include/llvm/BasicBlock.h llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/Support/CFG.h llvm/trunk/include/llvm/Use.h llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp llvm/trunk/lib/VMCore/BasicBlock.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/lib/VMCore/User.cpp llvm/trunk/lib/VMCore/Value.cpp llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/include/llvm/BasicBlock.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BasicBlock.h?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/include/llvm/BasicBlock.h (original) +++ llvm/trunk/include/llvm/BasicBlock.h Mon Jun 20 09:38:01 2011 @@ -110,7 +110,7 @@ Function *getParent() { return Parent; } /// use_back - Specialize the methods defined in Value, as we know that an - /// BasicBlock can only be used by Users (specifically PHI nodes, terminators, + /// BasicBlock can only be used by Users (specifically terminators /// and BlockAddress's). User *use_back() { return cast(*use_begin());} const User *use_back() const { return cast(*use_begin());} @@ -248,6 +248,10 @@ /// other than direct branches, switches, etc. to it. bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; } + /// replaceSuccessorsPhiUsesWith - Update all phi nodes in all our successors + /// to refer to basic block New instead of to us. + void replaceSuccessorsPhiUsesWith(BasicBlock *New); + private: /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress /// objects using it. This is almost always 0, sometimes one, possibly but Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Mon Jun 20 09:38:01 2011 @@ -1814,7 +1814,7 @@ explicit PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr = "", Instruction *InsertBefore = 0) : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), - ReservedSpace(NumReservedValues * 2) { + ReservedSpace(NumReservedValues) { setName(NameStr); OperandList = allocHungoffUses(ReservedSpace); } @@ -1822,11 +1822,16 @@ PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), - ReservedSpace(NumReservedValues * 2) { + ReservedSpace(NumReservedValues) { setName(NameStr); OperandList = allocHungoffUses(ReservedSpace); } protected: + // allocHungoffUses - this is more complicated than the generic + // User::allocHungoffUses, because we have to allocate Uses for the incoming + // values and pointers to the incoming blocks, all in one allocation. + Use *allocHungoffUses(unsigned) const; + virtual PHINode *clone_impl() const; public: /// Constructors - NumReservedValues is a hint for the number of incoming @@ -1845,32 +1850,55 @@ /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + // Block iterator interface. This provides access to the list of incoming + // basic blocks, which parallels the list of incoming values. + + typedef BasicBlock **block_iterator; + typedef BasicBlock * const *const_block_iterator; + + block_iterator block_begin() { + Use::UserRef *ref = + reinterpret_cast(op_begin() + ReservedSpace); + return reinterpret_cast(ref + 1); + } + + const_block_iterator block_begin() const { + const Use::UserRef *ref = + reinterpret_cast(op_begin() + ReservedSpace); + return reinterpret_cast(ref + 1); + } + + block_iterator block_end() { + return block_begin() + getNumOperands(); + } + + const_block_iterator block_end() const { + return block_begin() + getNumOperands(); + } + /// getNumIncomingValues - Return the number of incoming edges /// - unsigned getNumIncomingValues() const { return getNumOperands()/2; } + unsigned getNumIncomingValues() const { return getNumOperands(); } /// getIncomingValue - Return incoming value number x /// Value *getIncomingValue(unsigned i) const { - assert(i*2 < getNumOperands() && "Invalid value number!"); - return getOperand(i*2); + return getOperand(i); } void setIncomingValue(unsigned i, Value *V) { - assert(i*2 < getNumOperands() && "Invalid value number!"); - setOperand(i*2, V); + setOperand(i, V); } static unsigned getOperandNumForIncomingValue(unsigned i) { - return i*2; + return i; } static unsigned getIncomingValueNumForOperand(unsigned i) { - assert(i % 2 == 0 && "Invalid incoming-value operand index!"); - return i/2; + return i; } /// getIncomingBlock - Return incoming basic block number @p i. /// BasicBlock *getIncomingBlock(unsigned i) const { - return cast(getOperand(i*2+1)); + return block_begin()[i]; } /// getIncomingBlock - Return incoming basic block corresponding @@ -1878,7 +1906,7 @@ /// BasicBlock *getIncomingBlock(const Use &U) const { assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?"); - return cast((&U + 1)->get()); + return getIncomingBlock(&U - op_begin()); } /// getIncomingBlock - Return incoming basic block corresponding @@ -1889,16 +1917,8 @@ return getIncomingBlock(I.getUse()); } - void setIncomingBlock(unsigned i, BasicBlock *BB) { - setOperand(i*2+1, (Value*)BB); - } - static unsigned getOperandNumForIncomingBlock(unsigned i) { - return i*2+1; - } - static unsigned getIncomingBlockNumForOperand(unsigned i) { - assert(i % 2 == 1 && "Invalid incoming-block operand index!"); - return i/2; + block_begin()[i] = BB; } /// addIncoming - Add an incoming value to the end of the PHI list @@ -1908,13 +1928,12 @@ assert(BB && "PHI node got a null basic block!"); assert(getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"); - unsigned OpNo = NumOperands; - if (OpNo+2 > ReservedSpace) + if (NumOperands == ReservedSpace) growOperands(); // Get more space! // Initialize some new operands. - NumOperands = OpNo+2; - OperandList[OpNo] = V; - OperandList[OpNo+1] = (Value*)BB; + ++NumOperands; + setIncomingValue(NumOperands - 1, V); + setIncomingBlock(NumOperands - 1, BB); } /// removeIncomingValue - Remove an incoming value. This is useful if a @@ -1937,14 +1956,16 @@ /// block in the value list for this PHI. Returns -1 if no instance. /// int getBasicBlockIndex(const BasicBlock *BB) const { - Use *OL = OperandList; - for (unsigned i = 0, e = getNumOperands(); i != e; i += 2) - if (OL[i+1].get() == (const Value*)BB) return i/2; + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (block_begin()[i] == BB) + return i; return -1; } Value *getIncomingValueForBlock(const BasicBlock *BB) const { - return getIncomingValue(getBasicBlockIndex(BB)); + int Idx = getBasicBlockIndex(BB); + assert(Idx >= 0 && "Invalid basic block argument!"); + return getIncomingValue(Idx); } /// hasConstantValue - If the specified PHI node always merges together the Modified: llvm/trunk/include/llvm/Support/CFG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CFG.h?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CFG.h (original) +++ llvm/trunk/include/llvm/Support/CFG.h Mon Jun 20 09:38:01 2011 @@ -33,7 +33,7 @@ USE_iterator It; inline void advancePastNonTerminators() { - // Loop to ignore non terminator uses (for example PHI nodes). + // Loop to ignore non terminator uses (for example BlockAddresses). while (!It.atEnd() && !isa(*It)) ++It; } Modified: llvm/trunk/include/llvm/Use.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Use.h?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/include/llvm/Use.h (original) +++ llvm/trunk/include/llvm/Use.h Mon Jun 20 09:38:01 2011 @@ -112,13 +112,16 @@ Use *getNext() const { return Next; } + /// initTags - initialize the waymarking tags on an array of Uses, so that + /// getUser() can find the User from any of those Uses. + static Use *initTags(Use *Start, Use *Stop); + /// zap - This is used to destroy Use operands when the number of operands of /// a User changes. static void zap(Use *Start, const Use *Stop, bool del = false); private: const Use* getImpliedUser() const; - static Use *initTags(Use *Start, Use *Stop); Value *Val; Use *Next; @@ -140,7 +143,6 @@ } friend class Value; - friend class User; }; // simplify_type - Allow clients to treat uses just like values when using Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Mon Jun 20 09:38:01 2011 @@ -1356,7 +1356,7 @@ for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) { Out << iName << "->addIncoming(" << opNames[PHINode::getOperandNumForIncomingValue(i)] << ", " - << opNames[PHINode::getOperandNumForIncomingBlock(i)] << ");"; + << getOpName(phi->getIncomingBlock(i)) << ");"; nl(Out); } break; Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Mon Jun 20 09:38:01 2011 @@ -1021,6 +1021,10 @@ while (PHINode *PN = dyn_cast(Succ->begin())) ReplaceUsesOfWith(PN, PN->getIncomingValue(0), Worklist, L, LPM); + // If Succ has any successors with PHI nodes, update them to have + // entries coming from Pred instead of Succ. + Succ->replaceAllUsesWith(Pred); + // Move all of the successor contents from Succ to Pred. Pred->getInstList().splice(BI, Succ->getInstList(), Succ->begin(), Succ->end()); @@ -1028,10 +1032,6 @@ BI->eraseFromParent(); RemoveFromWorklist(BI, Worklist); - // If Succ has any successors with PHI nodes, update them to have - // entries coming from Pred instead of Succ. - Succ->replaceAllUsesWith(Pred); - // Remove Succ from the loop tree. LI->removeBlock(Succ); LPM->deleteSimpleAnalysisValue(Succ, L); Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Mon Jun 20 09:38:01 2011 @@ -153,13 +153,13 @@ // Delete the unconditional branch from the predecessor... PredBB->getInstList().pop_back(); - // Move all definitions in the successor to the predecessor... - PredBB->getInstList().splice(PredBB->end(), BB->getInstList()); - // Make all PHI nodes that referred to BB now refer to Pred as their // source... BB->replaceAllUsesWith(PredBB); + // Move all definitions in the successor to the predecessor... + PredBB->getInstList().splice(PredBB->end(), BB->getInstList()); + // Inherit predecessors name if it exists. if (!PredBB->hasName()) PredBB->takeName(BB); Modified: llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp Mon Jun 20 09:38:01 2011 @@ -193,44 +193,22 @@ // If there are any PHI nodes in DestBB, we need to update them so that they // merge incoming values from NewBB instead of from TIBB. - if (PHINode *APHI = dyn_cast(DestBB->begin())) { - // This conceptually does: - // foreach (PHINode *PN in DestBB) - // PN->setIncomingBlock(PN->getIncomingBlock(TIBB), NewBB); - // but is optimized for two cases. - - if (APHI->getNumIncomingValues() <= 8) { // Small # preds case. - unsigned BBIdx = 0; - for (BasicBlock::iterator I = DestBB->begin(); isa(I); ++I) { - // We no longer enter through TIBB, now we come in through NewBB. - // Revector exactly one entry in the PHI node that used to come from - // TIBB to come from NewBB. - PHINode *PN = cast(I); - - // Reuse the previous value of BBIdx if it lines up. In cases where we - // have multiple phi nodes with *lots* of predecessors, this is a speed - // win because we don't have to scan the PHI looking for TIBB. This - // happens because the BB list of PHI nodes are usually in the same - // order. - if (PN->getIncomingBlock(BBIdx) != TIBB) - BBIdx = PN->getBasicBlockIndex(TIBB); - PN->setIncomingBlock(BBIdx, NewBB); - } - } else { - // However, the foreach loop is slow for blocks with lots of predecessors - // because PHINode::getIncomingBlock is O(n) in # preds. Instead, walk - // the user list of TIBB to find the PHI nodes. - SmallPtrSet UpdatedPHIs; - - for (Value::use_iterator UI = TIBB->use_begin(), E = TIBB->use_end(); - UI != E; ) { - Value::use_iterator Use = UI++; - if (PHINode *PN = dyn_cast(*Use)) { - // Remove one entry from each PHI. - if (PN->getParent() == DestBB && UpdatedPHIs.insert(PN)) - PN->setOperand(Use.getOperandNo(), NewBB); - } - } + { + unsigned BBIdx = 0; + for (BasicBlock::iterator I = DestBB->begin(); isa(I); ++I) { + // We no longer enter through TIBB, now we come in through NewBB. + // Revector exactly one entry in the PHI node that used to come from + // TIBB to come from NewBB. + PHINode *PN = cast(I); + + // Reuse the previous value of BBIdx if it lines up. In cases where we + // have multiple phi nodes with *lots* of predecessors, this is a speed + // win because we don't have to scan the PHI looking for TIBB. This + // happens because the BB list of PHI nodes are usually in the same + // order. + if (PN->getIncomingBlock(BBIdx) != TIBB) + BBIdx = PN->getBasicBlockIndex(TIBB); + PN->setIncomingBlock(BBIdx, NewBB); } } Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Mon Jun 20 09:38:01 2011 @@ -572,12 +572,12 @@ // removed, so we just need to splice the blocks. BI->eraseFromParent(); - // Move all the instructions in the succ to the pred. - I->getInstList().splice(I->end(), Dest->getInstList()); - // Make all PHI nodes that referred to Dest now refer to I as their source. Dest->replaceAllUsesWith(I); + // Move all the instructions in the succ to the pred. + I->getInstList().splice(I->end(), Dest->getInstList()); + // Remove the dest block. Dest->eraseFromParent(); Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Mon Jun 20 09:38:01 2011 @@ -1097,15 +1097,15 @@ TheCall->replaceAllUsesWith(Returns[0]->getReturnValue()); } + // Update PHI nodes that use the ReturnBB to use the AfterCallBB. + BasicBlock *ReturnBB = Returns[0]->getParent(); + ReturnBB->replaceAllUsesWith(AfterCallBB); + // Splice the code from the return block into the block that it will return // to, which contains the code that was after the call. - BasicBlock *ReturnBB = Returns[0]->getParent(); AfterCallBB->getInstList().splice(AfterCallBB->begin(), ReturnBB->getInstList()); - // Update PHI nodes that use the ReturnBB to use the AfterCallBB. - ReturnBB->replaceAllUsesWith(AfterCallBB); - // Delete the return instruction now and empty ReturnBB now. Returns[0]->eraseFromParent(); ReturnBB->eraseFromParent(); @@ -1125,8 +1125,8 @@ // Splice the code entry block into calling block, right before the // unconditional branch. - OrigBB->getInstList().splice(Br, CalleeEntry->getInstList()); CalleeEntry->replaceAllUsesWith(OrigBB); // Update PHI nodes + OrigBB->getInstList().splice(Br, CalleeEntry->getInstList()); // Remove the unconditional branch. OrigBB->getInstList().erase(Br); Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Mon Jun 20 09:38:01 2011 @@ -427,10 +427,6 @@ BasicBlock *PredBB = DestBB->getSinglePredecessor(); assert(PredBB && "Block doesn't have a single predecessor!"); - // Splice all the instructions from PredBB to DestBB. - PredBB->getTerminator()->eraseFromParent(); - DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList()); - // Zap anything that took the address of DestBB. Not doing this will give the // address an invalid value. if (DestBB->hasAddressTaken()) { @@ -445,6 +441,10 @@ // Anything that branched to PredBB now branches to DestBB. PredBB->replaceAllUsesWith(DestBB); + // Splice all the instructions from PredBB to DestBB. + PredBB->getTerminator()->eraseFromParent(); + DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList()); + if (P) { DominatorTree *DT = P->getAnalysisIfAvailable(); if (DT) { @@ -660,12 +660,17 @@ // them, which helps expose duplicates, but we have to check all the // operands to be safe in case instcombine hasn't run. uintptr_t Hash = 0; + // This hash algorithm is quite weak as hash functions go, but it seems + // to do a good enough job for this particular purpose, and is very quick. for (User::op_iterator I = PN->op_begin(), E = PN->op_end(); I != E; ++I) { - // This hash algorithm is quite weak as hash functions go, but it seems - // to do a good enough job for this particular purpose, and is very quick. Hash ^= reinterpret_cast(static_cast(*I)); Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7)); } + for (PHINode::block_iterator I = PN->block_begin(), E = PN->block_end(); + I != E; ++I) { + Hash ^= reinterpret_cast(static_cast(*I)); + Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7)); + } // Avoid colliding with the DenseMap sentinels ~0 and ~0-1. Hash >>= 1; // If we've never seen this hash value before, it's a unique PHI. Modified: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Mon Jun 20 09:38:01 2011 @@ -47,6 +47,14 @@ if (It != VMap.end()) I->setOperand(op, It->second); } + + if (PHINode *PN = dyn_cast(I)) { + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + ValueToValueMapTy::iterator It = VMap.find(PN->getIncomingBlock(i)); + if (It != VMap.end()) + PN->setIncomingBlock(i, cast(It->second)); + } + } } /// FoldBlockIntoPredecessor - Folds a basic block into its predecessor if it @@ -75,13 +83,13 @@ // Delete the unconditional branch from the predecessor... OnlyPred->getInstList().pop_back(); - // Move all definitions in the successor to the predecessor... - OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList()); - // Make all PHI nodes that referred to BB now refer to Pred as their // source... BB->replaceAllUsesWith(OnlyPred); + // Move all definitions in the successor to the predecessor... + OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList()); + std::string OldName = BB->getName(); // Erase basic block from the function... @@ -247,16 +255,14 @@ // the successor of the latch block. The successor of the exit block will // be updated specially after unrolling all the way. if (*BB != LatchBlock) - for (Value::use_iterator UI = (*BB)->use_begin(), UE = (*BB)->use_end(); - UI != UE;) { - Instruction *UseInst = cast(*UI); - ++UI; - if (isa(UseInst) && !L->contains(UseInst)) { - PHINode *phi = cast(UseInst); - Value *Incoming = phi->getIncomingValueForBlock(*BB); - phi->addIncoming(Incoming, New); - } - } + for (succ_iterator SI = succ_begin(*BB), SE = succ_end(*BB); SI != SE; + ++SI) + if (!L->contains(*SI)) + for (BasicBlock::iterator BBI = (*SI)->begin(), BBE = (*SI)->end(); + PHINode *phi = dyn_cast(BBI); ++BBI) { + Value *Incoming = phi->getIncomingValueForBlock(*BB); + phi->addIncoming(Incoming, New); + } // Keep track of new headers and latches as we create them, so that // we can insert the proper branches later. @@ -288,24 +294,20 @@ // successor blocks, update them to use the appropriate values computed as the // last iteration of the loop. if (Count != 1) { - SmallPtrSet Users; - for (Value::use_iterator UI = LatchBlock->use_begin(), - UE = LatchBlock->use_end(); UI != UE; ++UI) - if (PHINode *phi = dyn_cast(*UI)) - Users.insert(phi); - BasicBlock *LastIterationBB = cast(LastValueMap[LatchBlock]); - for (SmallPtrSet::iterator SI = Users.begin(), SE = Users.end(); + for (succ_iterator SI = succ_begin(LatchBlock), SE = succ_end(LatchBlock); SI != SE; ++SI) { - PHINode *PN = *SI; - Value *InVal = PN->removeIncomingValue(LatchBlock, false); - // If this value was defined in the loop, take the value defined by the - // last iteration of the loop. - if (Instruction *InValI = dyn_cast(InVal)) { - if (L->contains(InValI)) - InVal = LastValueMap[InVal]; + for (BasicBlock::iterator BBI = (*SI)->begin(), BBE = (*SI)->end(); + PHINode *PN = dyn_cast(BBI); ++BBI) { + Value *InVal = PN->removeIncomingValue(LatchBlock, false); + // If this value was defined in the loop, take the value defined by the + // last iteration of the loop. + if (Instruction *InValI = dyn_cast(InVal)) { + if (L->contains(InValI)) + InVal = LastValueMap[InVal]; + } + PN->addIncoming(InVal, LastIterationBB); } - PN->addIncoming(InVal, LastIterationBB); } } @@ -352,11 +354,16 @@ // Replace the conditional branch with an unconditional one. BranchInst::Create(Dest, Term); Term->eraseFromParent(); - // Merge adjacent basic blocks, if possible. - if (BasicBlock *Fold = FoldBlockIntoPredecessor(Dest, LI)) { + } + } + + // Merge adjacent basic blocks, if possible. + for (unsigned i = 0, e = Latches.size(); i != e; ++i) { + BranchInst *Term = cast(Latches[i]->getTerminator()); + if (Term->isUnconditional()) { + BasicBlock *Dest = Term->getSuccessor(0); + if (BasicBlock *Fold = FoldBlockIntoPredecessor(Dest, LI)) std::replace(Latches.begin(), Latches.end(), Dest, Fold); - std::replace(Headers.begin(), Headers.end(), Dest, Fold); - } } } Modified: llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp Mon Jun 20 09:38:01 2011 @@ -16,6 +16,7 @@ #include "llvm/Type.h" #include "llvm/Constants.h" #include "llvm/Function.h" +#include "llvm/Instructions.h" #include "llvm/Metadata.h" #include "llvm/ADT/SmallVector.h" using namespace llvm; @@ -128,6 +129,19 @@ "Referenced value not in value map!"); } + // Remap phi nodes' incoming blocks. + if (PHINode *PN = dyn_cast(I)) { + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + Value *V = MapValue(PN->getIncomingBlock(i), VMap, Flags); + // If we aren't ignoring missing entries, assert that something happened. + if (V != 0) + PN->setIncomingBlock(i, cast(V)); + else + assert((Flags & RF_IgnoreMissingEntries) && + "Referenced block not in value map!"); + } + } + // Remap attached metadata. SmallVector, 4> MDs; I->getAllMetadata(MDs); Modified: llvm/trunk/lib/VMCore/BasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/BasicBlock.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/BasicBlock.cpp (original) +++ llvm/trunk/lib/VMCore/BasicBlock.cpp Mon Jun 20 09:38:01 2011 @@ -308,3 +308,19 @@ return New; } +void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) { + TerminatorInst *TI = getTerminator(); + if (!TI) + // Cope with being called on a BasicBlock that doesn't have a terminator + // yet. Clang's CodeGenFunction::EmitReturnBlock() likes to do this. + return; + for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) { + BasicBlock *Succ = TI->getSuccessor(i); + for (iterator II = Succ->begin(); PHINode *PN = dyn_cast(II); + ++II) { + int i; + while ((i = PN->getBasicBlockIndex(this)) >= 0) + PN->setIncomingBlock(i, New); + } + } +} Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Mon Jun 20 09:38:01 2011 @@ -87,11 +87,8 @@ : Instruction(PN.getType(), Instruction::PHI, allocHungoffUses(PN.getNumOperands()), PN.getNumOperands()), ReservedSpace(PN.getNumOperands()) { - Use *OL = OperandList; - for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) { - OL[i] = PN.getOperand(i); - OL[i+1] = PN.getOperand(i+1); - } + std::copy(PN.op_begin(), PN.op_end(), op_begin()); + std::copy(PN.block_begin(), PN.block_end(), block_begin()); SubclassOptionalData = PN.SubclassOptionalData; } @@ -99,31 +96,37 @@ dropHungoffUses(); } +Use *PHINode::allocHungoffUses(unsigned N) const { + // Allocate the array of Uses of the incoming values, followed by a pointer + // (with bottom bit set) to the User, followed by the array of pointers to + // the incoming basic blocks. + size_t size = N * sizeof(Use) + sizeof(Use::UserRef) + + N * sizeof(BasicBlock*); + Use *Begin = static_cast(::operator new(size)); + Use *End = Begin + N; + (void) new(End) Use::UserRef(const_cast(this), 1); + return Use::initTags(Begin, End); +} + // removeIncomingValue - Remove an incoming value. This is useful if a // predecessor basic block is deleted. Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) { - unsigned NumOps = getNumOperands(); - Use *OL = OperandList; - assert(Idx*2 < NumOps && "BB not in PHI node!"); - Value *Removed = OL[Idx*2]; + Value *Removed = getIncomingValue(Idx); // Move everything after this operand down. // // FIXME: we could just swap with the end of the list, then erase. However, - // client might not expect this to happen. The code as it is thrashes the + // clients might not expect this to happen. The code as it is thrashes the // use/def lists, which is kinda lame. - for (unsigned i = (Idx+1)*2; i != NumOps; i += 2) { - OL[i-2] = OL[i]; - OL[i-2+1] = OL[i+1]; - } + std::copy(op_begin() + Idx + 1, op_end(), op_begin() + Idx); + std::copy(block_begin() + Idx + 1, block_end(), block_begin() + Idx); // Nuke the last value. - OL[NumOps-2].set(0); - OL[NumOps-2+1].set(0); - NumOperands = NumOps-2; + Op<-1>().set(0); + --NumOperands; // If the PHI node is dead, because it has zero entries, nuke it now. - if (NumOps == 2 && DeletePHIIfEmpty) { + if (getNumOperands() == 0 && DeletePHIIfEmpty) { // If anyone is using this PHI, make them use a dummy value instead... replaceAllUsesWith(UndefValue::get(getType())); eraseFromParent(); @@ -137,15 +140,18 @@ /// void PHINode::growOperands() { unsigned e = getNumOperands(); - // Multiply by 1.5 and round down so the result is still even. - unsigned NumOps = e + e / 4 * 2; + unsigned NumOps = e + e / 2; if (NumOps < 4) NumOps = 4; // 4 op PHI nodes are VERY common. + Use *OldOps = op_begin(); + BasicBlock **OldBlocks = block_begin(); + ReservedSpace = NumOps; - Use *OldOps = OperandList; - Use *NewOps = allocHungoffUses(NumOps); - std::copy(OldOps, OldOps + e, NewOps); - OperandList = NewOps; + OperandList = allocHungoffUses(ReservedSpace); + + std::copy(OldOps, OldOps + e, op_begin()); + std::copy(OldBlocks, OldBlocks + e, block_begin()); + Use::zap(OldOps, OldOps + e, true); } Modified: llvm/trunk/lib/VMCore/User.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/User.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/User.cpp (original) +++ llvm/trunk/lib/VMCore/User.cpp Mon Jun 20 09:38:01 2011 @@ -40,8 +40,10 @@ //===----------------------------------------------------------------------===// Use *User::allocHungoffUses(unsigned N) const { - Use *Begin = static_cast(::operator new(sizeof(Use) * N - + sizeof(Use::UserRef))); + // Allocate the array of Uses, followed by a pointer (with bottom bit set) to + // the User. + size_t size = N * sizeof(Use) + sizeof(Use::UserRef); + Use *Begin = static_cast(::operator new(size)); Use *End = Begin + N; (void) new(End) Use::UserRef(const_cast(this), 1); return Use::initTags(Begin, End); Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Mon Jun 20 09:38:01 2011 @@ -305,6 +305,9 @@ U.set(New); } + + if (BasicBlock *BB = dyn_cast(this)) + BB->replaceSuccessorsPhiUsesWith(cast(New)); } void Value::replaceAllUsesWith(Value *New) { Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=133435&r1=133434&r2=133435&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Mon Jun 20 09:38:01 2011 @@ -1139,9 +1139,6 @@ for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { Assert1(PN.getType() == PN.getIncomingValue(i)->getType(), "PHI node operands are not the same type as the result!", &PN); - Assert1(isa(PN.getOperand( - PHINode::getOperandNumForIncomingBlock(i))), - "PHI node incoming block is not a BasicBlock!", &PN); } // All other PHI node constraints are checked in the visitBasicBlock method. From rafael.espindola at gmail.com Mon Jun 20 09:46:12 2011 From: rafael.espindola at gmail.com (=?ISO-8859-1?Q?Rafael_=C1vila_de_Esp=EDndola?=) Date: Mon, 20 Jun 2011 10:46:12 -0400 Subject: [llvm-commits] [dragonegg] r133427 - in /dragonegg/trunk: Makefile README extras/do_self_strap gcc-patches/ www/index.html In-Reply-To: <20110620074311.1AA7B2A6C12D@llvm.org> References: <20110620074311.1AA7B2A6C12D@llvm.org> Message-ID: <4DFF5D34.4000501@gmail.com> On 11-06-20 3:43 AM, Duncan Sands wrote: > Author: baldrick > Date: Mon Jun 20 02:43:10 2011 > New Revision: 133427 > > URL: http://llvm.org/viewvc/llvm-project?rev=133427&view=rev > Log: > Dragonegg no longer requires a patched version of gcc. Update the docs > to reflect that. Also, change the Makefile so that it defaults to > building for "gcc" rather than "gcc-4.5". Use the GCC variable to > override as explained in the README. That is a big milestone, congratulations! Cheers, Rafael From jay.foad at gmail.com Mon Jun 20 09:46:47 2011 From: jay.foad at gmail.com (Jay Foad) Date: Mon, 20 Jun 2011 14:46:47 -0000 Subject: [llvm-commits] [llvm] r133436 - /llvm/trunk/test/Transforms/GVN/2011-04-27-phioperands.ll Message-ID: <20110620144647.8ECCC2A6C12C@llvm.org> Author: foad Date: Mon Jun 20 09:46:47 2011 New Revision: 133436 URL: http://llvm.org/viewvc/llvm-project?rev=133436&view=rev Log: This is an automatically reduced test case that crashed in GVN, at some point during the development of the phi operand changes. Added: llvm/trunk/test/Transforms/GVN/2011-04-27-phioperands.ll Added: llvm/trunk/test/Transforms/GVN/2011-04-27-phioperands.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/2011-04-27-phioperands.ll?rev=133436&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVN/2011-04-27-phioperands.ll (added) +++ llvm/trunk/test/Transforms/GVN/2011-04-27-phioperands.ll Mon Jun 20 09:46:47 2011 @@ -0,0 +1,106 @@ +; RUN: opt %s -gvn -disable-output + +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-f128:128:128-n8:16:32:64" + + at nuls = external global [10 x i8] + +define fastcc void @p_ere() nounwind { +entry: + br label %"" + +".i": + br i1 undef, label %".i30.i", label %doemit.exit51.i + +".i30.i": + unreachable + +doemit.exit51.i: + br label %".i" + +".i": + br i1 undef, label %".i55.i", label %doemit.exit76.i + +".i55.i": + unreachable + +doemit.exit76.i: + br label %".i" + +".i": + store i8* getelementptr inbounds ([10 x i8]* @nuls, i64 0, i64 0), i8** undef, align 8 + br label %".i" + +".i": + br label %".i" + +".i": + br i1 undef, label %".i", label %".i" + +".i": + br label %".i" + +".i": + br label %".i" + +".i": + br label %".i" + +".i": + br label %".i" + +".i": + %wascaret_2.i = phi i32 [ 0, %".i" ], [ 0, %".i" ], [ 0, %".i" ], [ 0, %".i" ], [ 0, %".i" ], [ 0, %".i" ], [ 0, %doemit.exit76.i ], [ 1, %doemit.exit51.i ], [ 0, %".i" ] + %D.5496_84.i = load i8** undef, align 8 + br i1 undef, label %".i", label %"" + +".i": + br i1 undef, label %"", label %".i" + +".i": + br i1 undef, label %".i", label %".i" + +".i": + br label %".i" + +".i": + switch i32 undef, label %"" [ + i32 42, label %".i" + i32 43, label %".i" + i32 63, label %".i" + i32 123, label %".i258.i" + ] + +".i": + br i1 undef, label %".i105.i", label %doemit.exit127.i + +".i105.i": + unreachable + +doemit.exit127.i: + unreachable + +".i": + br i1 undef, label %".i157.i", label %"" + +".i157.i": + unreachable + +".i": + br label %"" + +".i258.i": + unreachable + +"": + switch i32 undef, label %".i" [ + i32 36, label %".i" + i32 94, label %".i" + i32 124, label %".i" + i32 42, label %".i" + i32 43, label %".i" + i32 46, label %".i" + i32 63, label %".i" + i32 91, label %".i" + i32 92, label %".i" + ] +} From baldrick at free.fr Mon Jun 20 10:02:48 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Jun 2011 17:02:48 +0200 Subject: [llvm-commits] [dragonegg] r133427 - in /dragonegg/trunk: Makefile README extras/do_self_strap gcc-patches/ www/index.html In-Reply-To: <4DFF5D34.4000501@gmail.com> References: <20110620074311.1AA7B2A6C12D@llvm.org> <4DFF5D34.4000501@gmail.com> Message-ID: <4DFF6118.4030908@free.fr> >> Dragonegg no longer requires a patched version of gcc. Update the docs >> to reflect that. Also, change the Makefile so that it defaults to >> building for "gcc" rather than "gcc-4.5". Use the GCC variable to >> override as explained in the README. > > That is a big milestone, congratulations! Thanks Rafael :) This should be a big improvement for users: no need to build gcc, just use your system gcc [*]. Ciao, Duncan. [*] That said I can't build yet against my system gcc yet, I think due to Debian's multiarch changes :( From rdivacky at freebsd.org Mon Jun 20 10:28:39 2011 From: rdivacky at freebsd.org (Roman Divacky) Date: Mon, 20 Jun 2011 15:28:39 -0000 Subject: [llvm-commits] [llvm] r133439 - in /llvm/trunk: lib/Target/PowerPC/PPCISelDAGToDAG.cpp test/CodeGen/PowerPC/ppc64-32bit-addic.ll Message-ID: <20110620152839.F1FAE2A6C12C@llvm.org> Author: rdivacky Date: Mon Jun 20 10:28:39 2011 New Revision: 133439 URL: http://llvm.org/viewvc/llvm-project?rev=133439&view=rev Log: Don't apply on PPC64 the 32bit ADDIC optimizations as there's no overflow with 32bit values. Added: llvm/trunk/test/CodeGen/PowerPC/ppc64-32bit-addic.ll Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=133439&r1=133438&r2=133439&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Mon Jun 20 10:28:39 2011 @@ -610,6 +610,9 @@ DebugLoc dl = N->getDebugLoc(); unsigned Imm; ISD::CondCode CC = cast(N->getOperand(2))->get(); + EVT PtrVT = CurDAG->getTargetLoweringInfo().getPointerTy(); + bool isPPC64 = (PtrVT == MVT::i64); + if (isInt32Immediate(N->getOperand(1), Imm)) { // We can codegen setcc op, imm very efficiently compared to a brcond. // Check for those cases here. @@ -624,6 +627,7 @@ return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops, 4); } case ISD::SETNE: { + if (isPPC64) break; SDValue AD = SDValue(CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue, Op, getI32Imm(~0U)), 0); @@ -647,6 +651,7 @@ switch (CC) { default: break; case ISD::SETEQ: + if (isPPC64) break; Op = SDValue(CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue, Op, getI32Imm(1)), 0); return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, @@ -655,6 +660,7 @@ getI32Imm(0)), 0), Op.getValue(1)); case ISD::SETNE: { + if (isPPC64) break; Op = SDValue(CurDAG->getMachineNode(PPC::NOR, dl, MVT::i32, Op, Op), 0); SDNode *AD = CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue, Op, getI32Imm(~0U)); @@ -996,22 +1002,25 @@ } case ISD::SELECT_CC: { ISD::CondCode CC = cast(N->getOperand(4))->get(); + EVT PtrVT = CurDAG->getTargetLoweringInfo().getPointerTy(); + bool isPPC64 = (PtrVT == MVT::i64); // Handle the setcc cases here. select_cc lhs, 0, 1, 0, cc - if (ConstantSDNode *N1C = dyn_cast(N->getOperand(1))) - if (ConstantSDNode *N2C = dyn_cast(N->getOperand(2))) - if (ConstantSDNode *N3C = dyn_cast(N->getOperand(3))) - if (N1C->isNullValue() && N3C->isNullValue() && - N2C->getZExtValue() == 1ULL && CC == ISD::SETNE && - // FIXME: Implement this optzn for PPC64. - N->getValueType(0) == MVT::i32) { - SDNode *Tmp = - CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue, - N->getOperand(0), getI32Imm(~0U)); - return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, - SDValue(Tmp, 0), N->getOperand(0), - SDValue(Tmp, 1)); - } + if (!isPPC64) + if (ConstantSDNode *N1C = dyn_cast(N->getOperand(1))) + if (ConstantSDNode *N2C = dyn_cast(N->getOperand(2))) + if (ConstantSDNode *N3C = dyn_cast(N->getOperand(3))) + if (N1C->isNullValue() && N3C->isNullValue() && + N2C->getZExtValue() == 1ULL && CC == ISD::SETNE && + // FIXME: Implement this optzn for PPC64. + N->getValueType(0) == MVT::i32) { + SDNode *Tmp = + CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue, + N->getOperand(0), getI32Imm(~0U)); + return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, + SDValue(Tmp, 0), N->getOperand(0), + SDValue(Tmp, 1)); + } SDValue CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC, dl); unsigned BROpc = getPredicateForSetCC(CC); Added: llvm/trunk/test/CodeGen/PowerPC/ppc64-32bit-addic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/ppc64-32bit-addic.ll?rev=133439&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/ppc64-32bit-addic.ll (added) +++ llvm/trunk/test/CodeGen/PowerPC/ppc64-32bit-addic.ll Mon Jun 20 10:28:39 2011 @@ -0,0 +1,29 @@ +; Check that the ADDIC optimizations are not applied on PPC64 +; RUN: llc < %s | FileCheck %s +; ModuleID = 'os_unix.c' +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-v128:128:128-n32:64" +target triple = "powerpc64-unknown-freebsd9.0" + +define i32 @notZero(i32 %call) nounwind { +entry: +; CHECK-NOT: addic + %not.tobool = icmp ne i32 %call, 0 + %. = zext i1 %not.tobool to i32 + ret i32 %. +} + +define i32 @isMinusOne(i32 %call) nounwind { +entry: +; CHECK-NOT: addic + %not.tobool = icmp eq i32 %call, -1 + %. = zext i1 %not.tobool to i32 + ret i32 %. +} + +define i32 @isNotMinusOne(i32 %call) nounwind { +entry: +; CHECK-NOT: addic + %not.tobool = icmp ne i32 %call, -1 + %. = zext i1 %not.tobool to i32 + ret i32 %. +} From jay.foad at gmail.com Mon Jun 20 10:43:15 2011 From: jay.foad at gmail.com (Jay Foad) Date: Mon, 20 Jun 2011 16:43:15 +0100 Subject: [llvm-commits] [llvm] r133412 - in /llvm/trunk: include/llvm/Constants.h lib/Analysis/ConstantFolding.cpp lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/CodeGen/ShadowStackGC.cpp lib/Transforms/IPO/GlobalOpt.cpp lib/Transform Message-ID: > It would be "really really nice" if the ConstantStruct::get and > ConstantVector::get methods didn't make temporary std::vectors. How about this then? Patch 1 extends ConstantUniqueMap with a new template parameter ValRefType, representing a const reference to ValType. Normally this would just be const ValType&, but when ValType is a std::vector, we want to use ArrayRef as the reference type. I had to add a conversion operator to ArrayRef to get this to work. Is this reasonable? (I've only been using C++ for 15 years so I haven't really got the hang of it yet.) This also makes the existing ArrayRef::vec() somewhat redundant, but I didn't remove it. Patches 2/3/4 tidy up the get() methods of ConstantVector/Array/Struct to use ArrayRef throughout. Tested with "make all check-all", LLVM and Clang. I don't think llvm-gcc-4.2 or dragonegg need any changes, based on a quick grep. OK to commit? Thanks, Jay. -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-constantuniquemap.patch Type: text/x-patch Size: 5139 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110620/796bbb6f/attachment.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-constantvector.patch Type: text/x-patch Size: 2725 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110620/796bbb6f/attachment-0001.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-constantarray.patch Type: text/x-patch Size: 8193 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110620/796bbb6f/attachment-0002.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0004-constantstruct.patch Type: text/x-patch Size: 706 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110620/796bbb6f/attachment-0003.bin From justin.holewinski at gmail.com Mon Jun 20 10:56:20 2011 From: justin.holewinski at gmail.com (Justin Holewinski) Date: Mon, 20 Jun 2011 15:56:20 -0000 Subject: [llvm-commits] [llvm] r133443 - in /llvm/trunk/lib/Target/PTX: PTXAsmPrinter.cpp PTXInstrInfo.cpp PTXInstrInfo.h PTXInstrInfo.td Message-ID: <20110620155620.D18072A6C12C@llvm.org> Author: jholewinski Date: Mon Jun 20 10:56:20 2011 New Revision: 133443 URL: http://llvm.org/viewvc/llvm-project?rev=133443&view=rev Log: PTX: Add basic register spilling code The current implementation generates stack loads/stores, which are really just mov instructions from/to "special" registers. This may not be the most efficient implementation, compared to an approach where the stack registers are directly folded into instructions, but this is easier to implement and I have yet to see a case where ptxas is unable to see through this kind of register usage and know what is really going on. Modified: llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp llvm/trunk/lib/Target/PTX/PTXInstrInfo.h llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Modified: llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp?rev=133443&r1=133442&r2=133443&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp Mon Jun 20 10:56:20 2011 @@ -23,6 +23,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/MC/MCStreamer.h" @@ -194,6 +195,18 @@ def += ';'; OutStreamer.EmitRawText(Twine(def)); } + + const MachineFrameInfo* FrameInfo = MF->getFrameInfo(); + DEBUG(dbgs() << "Have " << FrameInfo->getNumObjects() << " frame object(s)\n"); + for (unsigned i = 0, e = FrameInfo->getNumObjects(); i != e; ++i) { + DEBUG(dbgs() << "Size of object: " << FrameInfo->getObjectSize(i) << "\n"); + std::string def = "\t.reg .b"; + def += utostr(FrameInfo->getObjectSize(i)*8); // Convert to bits + def += " s"; + def += utostr(i); + def += ";"; + OutStreamer.EmitRawText(Twine(def)); + } } void PTXAsmPrinter::EmitInstruction(const MachineInstr *MI) { Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp?rev=133443&r1=133442&r2=133443&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp Mon Jun 20 10:56:20 2011 @@ -288,6 +288,81 @@ } } +// Memory operand folding for spills +void PTXInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MII, + unsigned SrcReg, bool isKill, int FrameIdx, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const { + MachineInstr& MI = *MII; + DebugLoc DL = MI.getDebugLoc(); + + DEBUG(dbgs() << "storeRegToStackSlot: " << MI); + + int OpCode; + + // Select the appropriate opcode based on the register class + if (RC == PTX::RegI16RegisterClass) { + OpCode = PTX::STACKSTOREI16; + } + else if (RC == PTX::RegI32RegisterClass) { + OpCode = PTX::STACKSTOREI32; + } + else if (RC == PTX::RegI64RegisterClass) { + OpCode = PTX::STACKSTOREI32; + } + else if (RC == PTX::RegF32RegisterClass) { + OpCode = PTX::STACKSTOREF32; + } + else if (RC == PTX::RegF64RegisterClass) { + OpCode = PTX::STACKSTOREF64; + } + + // Build the store instruction (really a mov) + MachineInstrBuilder MIB = BuildMI(MBB, MII, DL, get(OpCode)); + MIB.addImm(FrameIdx); + MIB.addReg(SrcReg); + + AddDefaultPredicate(MIB); +} + +void PTXInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MII, + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const { + MachineInstr& MI = *MII; + DebugLoc DL = MI.getDebugLoc(); + + DEBUG(dbgs() << "loadRegToStackSlot: " << MI); + + int OpCode; + + // Select the appropriate opcode based on the register class + if (RC == PTX::RegI16RegisterClass) { + OpCode = PTX::STACKLOADI16; + } + else if (RC == PTX::RegI32RegisterClass) { + OpCode = PTX::STACKLOADI32; + } + else if (RC == PTX::RegI64RegisterClass) { + OpCode = PTX::STACKLOADI32; + } + else if (RC == PTX::RegF32RegisterClass) { + OpCode = PTX::STACKLOADF32; + } + else if (RC == PTX::RegF64RegisterClass) { + OpCode = PTX::STACKLOADF64; + } + + // Build the load instruction (really a mov) + MachineInstrBuilder MIB = BuildMI(MBB, MII, DL, get(OpCode)); + MIB.addReg(DestReg); + MIB.addImm(FrameIdx); + + AddDefaultPredicate(MIB); +} + // static helper routines MachineSDNode *PTXInstrInfo:: Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.h?rev=133443&r1=133442&r2=133443&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.h (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.h Mon Jun 20 10:56:20 2011 @@ -84,6 +84,29 @@ const SmallVectorImpl &Cond, DebugLoc DL) const; + // Memory operand folding for spills + // TODO: Implement this eventually and get rid of storeRegToStackSlot and + // loadRegFromStackSlot. Doing so will get rid of the "stack" registers + // we currently use to spill, though I doubt the overall effect on ptxas + // output will be large. I have yet to see a case where ptxas is unable + // to see through the "stack" register usage and hence generates + // efficient code anyway. + // virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + // MachineInstr* MI, + // const SmallVectorImpl &Ops, + // int FrameIndex) const; + + virtual void storeRegToStackSlot(MachineBasicBlock& MBB, + MachineBasicBlock::iterator MII, + unsigned SrcReg, bool isKill, int FrameIndex, + const TargetRegisterClass* RC, + const TargetRegisterInfo* TRI) const; + virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MII, + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const; + // static helper routines static MachineSDNode *GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode, Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.td?rev=133443&r1=133442&r2=133443&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Mon Jun 20 10:56:20 2011 @@ -977,6 +977,30 @@ def RET : InstPTX<(outs), (ins), "ret", [(PTXret)]>; } +///===- Spill Instructions ------------------------------------------------===// +// Special instructions used for stack spilling +def STACKSTOREI16 : InstPTX<(outs), (ins i32imm:$d, RegI16:$a), + "mov.u16\ts$d, $a", []>; +def STACKSTOREI32 : InstPTX<(outs), (ins i32imm:$d, RegI32:$a), + "mov.u32\ts$d, $a", []>; +def STACKSTOREI64 : InstPTX<(outs), (ins i32imm:$d, RegI64:$a), + "mov.u64\ts$d, $a", []>; +def STACKSTOREF32 : InstPTX<(outs), (ins i32imm:$d, RegF32:$a), + "mov.f32\ts$d, $a", []>; +def STACKSTOREF64 : InstPTX<(outs), (ins i32imm:$d, RegF64:$a), + "mov.f64\ts$d, $a", []>; + +def STACKLOADI16 : InstPTX<(outs), (ins RegI16:$d, i32imm:$a), + "mov.u16\t$d, s$a", []>; +def STACKLOADI32 : InstPTX<(outs), (ins RegI32:$d, i32imm:$a), + "mov.u32\t$d, s$a", []>; +def STACKLOADI64 : InstPTX<(outs), (ins RegI64:$d, i32imm:$a), + "mov.u64\t$d, s$a", []>; +def STACKLOADF32 : InstPTX<(outs), (ins RegF32:$d, i32imm:$a), + "mov.f32\t$d, s$a", []>; +def STACKLOADF64 : InstPTX<(outs), (ins RegF64:$d, i32imm:$a), + "mov.f64\t$d, s$a", []>; + ///===- Intrinsic Instructions --------------------------------------------===// include "PTXIntrinsicInstrInfo.td" From fvbommel at gmail.com Mon Jun 20 11:03:14 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Mon, 20 Jun 2011 18:03:14 +0200 Subject: [llvm-commits] [llvm] r133435 - in /llvm/trunk: include/llvm/ include/llvm/Support/ lib/Target/CppBackend/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ In-Reply-To: <20110620143801.6C0D72A6C124@llvm.org> References: <20110620143801.6C0D72A6C124@llvm.org> Message-ID: > ?void PHINode::growOperands() { > ? unsigned e = getNumOperands(); > - ?// Multiply by 1.5 and round down so the result is still even. > - ?unsigned NumOps = e + e / 4 * 2; > + ?unsigned NumOps = e + e / 2; > ? if (NumOps < 4) NumOps = 4; ? ? ?// 4 op PHI nodes are VERY common. Wouldn't it now be 2-op PHI nodes that are "VERY common"? (since 2 of the ops used to be basic blocks) From stoklund at 2pi.dk Mon Jun 20 11:59:03 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 20 Jun 2011 09:59:03 -0700 Subject: [llvm-commits] [llvm] r133443 - in /llvm/trunk/lib/Target/PTX: PTXAsmPrinter.cpp PTXInstrInfo.cpp PTXInstrInfo.h PTXInstrInfo.td In-Reply-To: <20110620155620.D18072A6C12C@llvm.org> References: <20110620155620.D18072A6C12C@llvm.org> Message-ID: <2C3AFB7B-D930-4B85-BFA7-5589ADCEF78E@2pi.dk> On Jun 20, 2011, at 8:56 AM, Justin Holewinski wrote: > + int OpCode; > + > + // Select the appropriate opcode based on the register class > + if (RC == PTX::RegI16RegisterClass) { > + OpCode = PTX::STACKSTOREI16; > + } > + else if (RC == PTX::RegI32RegisterClass) { > + OpCode = PTX::STACKSTOREI32; > + } > + else if (RC == PTX::RegI64RegisterClass) { > + OpCode = PTX::STACKSTOREI32; > + } > + else if (RC == PTX::RegF32RegisterClass) { > + OpCode = PTX::STACKSTOREF32; > + } > + else if (RC == PTX::RegF64RegisterClass) { > + OpCode = PTX::STACKSTOREF64; > + } Please add an assertion for the unknown register class case. Also, format your else-ifs like so: } else if (..) { /jakob From aggarwa4 at illinois.edu Mon Jun 20 11:55:27 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 20 Jun 2011 16:55:27 -0000 Subject: [llvm-commits] [poolalloc] r133444 - /poolalloc/trunk/lib/AssistDS/SimplifyLoad.cpp Message-ID: <20110620165527.E6FC42A6C12C@llvm.org> Author: aggarwa4 Date: Mon Jun 20 11:55:27 2011 New Revision: 133444 URL: http://llvm.org/viewvc/llvm-project?rev=133444&view=rev Log: Remove extraneous printing. Modified: poolalloc/trunk/lib/AssistDS/SimplifyLoad.cpp Modified: poolalloc/trunk/lib/AssistDS/SimplifyLoad.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/SimplifyLoad.cpp?rev=133444&r1=133443&r2=133444&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/SimplifyLoad.cpp (original) +++ poolalloc/trunk/lib/AssistDS/SimplifyLoad.cpp Mon Jun 20 11:55:27 2011 @@ -63,10 +63,6 @@ if(const PointerType *PTy = dyn_cast(CE->getOperand(0)->getType())) if(PTy->getElementType() == CI->getType()) { LoadInst *LINew = new LoadInst(CE->getOperand(0), "", LI); - LINew->dump(); - LI->dump(); - CI->dump(); - CE->dump(); CI->replaceAllUsesWith(LINew); } } From aggarwa4 at illinois.edu Mon Jun 20 11:56:57 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 20 Jun 2011 16:56:57 -0000 Subject: [llvm-commits] [poolalloc] r133445 - in /poolalloc/trunk: include/assistDS/TypeChecks.h lib/AssistDS/TypeChecks.cpp Message-ID: <20110620165657.986972A6C12C@llvm.org> Author: aggarwa4 Date: Mon Jun 20 11:56:57 2011 New Revision: 133445 URL: http://llvm.org/viewvc/llvm-project?rev=133445&view=rev Log: Handle calls to va_copy, and add a new counter for the values in the copied va_list. Modified: poolalloc/trunk/include/assistDS/TypeChecks.h poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Modified: poolalloc/trunk/include/assistDS/TypeChecks.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/TypeChecks.h?rev=133445&r1=133444&r2=133445&view=diff ============================================================================== --- poolalloc/trunk/include/assistDS/TypeChecks.h (original) +++ poolalloc/trunk/include/assistDS/TypeChecks.h Mon Jun 20 11:56:57 2011 @@ -42,6 +42,8 @@ std::list ByValFunctions; std::list AddressTakenFunctions; std::set IndCalls; + // Map of VAList to current count + std::map CounterMap; // Analysis from other passes. TargetData *TD; Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=133445&r1=133444&r2=133445&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Mon Jun 20 11:56:57 2011 @@ -260,6 +260,7 @@ ByValFunctions.pop_back(); modified |= visitByValFunction(M, *F); } + // NOTE:must visit before VAArgFunctions, to populate the map with the // correct cloned functions. @@ -468,10 +469,24 @@ Function *CalledF = dyn_cast(CI->getCalledFunction()); if(VAListFunctionsMap.find(CalledF) == VAListFunctionsMap.end()) continue; + const Type *ListType = F->getParent()->getTypeByName("struct.__va_list_tag"); + const Type *ListPtrType = ListType->getPointerTo(); + unsigned VAListArgNum = 0; + for (Function::arg_iterator I = CalledF->arg_begin(); + I != CalledF->arg_end(); ++I) { + VAListArgNum ++; + if(I->getType() == ListPtrType) { + break; + } + } + Function::arg_iterator NII = F->arg_begin(); std::vectorArgs; Args.push_back(NII++); // total count - Args.push_back(NII++); // current count + Value *CounterSrc = CounterMap[CI->getOperand(VAListArgNum)->stripPointerCasts()]; + LoadInst *CountValue = new LoadInst(CounterSrc, "count", CI); + Args.push_back(CountValue); // current count + NII++; Args.push_back(NII); // MD for(unsigned i = 1 ;i < CI->getNumOperands(); i++) { // Add the original argument @@ -559,6 +574,7 @@ VAListFunctionsMap[&F_orig] = F; inst_iterator InsPt = inst_begin(F); + // Store the information Function::arg_iterator NII = F->arg_begin(); AllocaInst *VASizeLoc = new AllocaInst(Int64Ty, "", &*InsPt); @@ -566,9 +582,33 @@ NII++; AllocaInst *Counter = new AllocaInst(Int64Ty, "",&*InsPt); new StoreInst(NII, Counter, &*InsPt); + CounterMap[NII] = Counter; NII++; AllocaInst *VAMDLoc = new AllocaInst(VoidPtrTy, "", &*InsPt); new StoreInst(NII, VAMDLoc, &*InsPt); + + // Find all va_copy calls + for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { + for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;I++) { + CallInst *CI = dyn_cast(I); + if(!CI) + continue; + Function *CalledF = dyn_cast(CI->getCalledFunction()); + if(!CalledF) + continue; + if(!CalledF->isIntrinsic()) + continue; + if(CalledF->getIntrinsicID() != Intrinsic::vacopy) + continue; + // Reinitialize the counter + AllocaInst *CounterDest = new AllocaInst(Int64Ty, "",&*InsPt); + Value *CounterSource = CounterMap[CI->getOperand(2)->stripPointerCasts()]; + LoadInst *CurrentValue = new LoadInst(CounterSource, "count", CI); + new StoreInst(CurrentValue, CounterDest, CI); + CounterMap[CI->getOperand(1)->stripPointerCasts()] = CounterDest; + } + } + // instrument va_arg to increment the counter for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { @@ -577,13 +617,14 @@ if(!VI) continue; Constant *One = ConstantInt::get(Int64Ty, 1); - LoadInst *OldValue = new LoadInst(Counter, "count", VI); + Value *CounterSrc = CounterMap[VI->getOperand(0)->stripPointerCasts()]; + LoadInst *OldValue = new LoadInst(CounterSrc, "count", VI); Instruction *NewValue = BinaryOperator::Create(BinaryOperator::Add, OldValue, One, "count", VI); - new StoreInst(NewValue, Counter, VI); + new StoreInst(NewValue, CounterSrc, VI); std::vector Args; Instruction *VASize = new LoadInst(VASizeLoc, "", VI); Instruction *VAMetaData = new LoadInst(VAMDLoc, "", VI); @@ -804,6 +845,49 @@ AllocaInst *Counter = new AllocaInst(Int64Ty, "",&*InsPt); new StoreInst(ConstantInt::get(Int64Ty, 0), Counter, &*InsPt); + + // visit all VAStarts and initialize the counter + for (Function::iterator B = NewF->begin(), FE = NewF->end(); B != FE; ++B) { + for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;I++) { + CallInst *CI = dyn_cast(I); + if(!CI) + continue; + Function *CalledF = dyn_cast(CI->getCalledFunction()); + if(!CalledF) + continue; + if(!CalledF->isIntrinsic()) + continue; + if(CalledF->getIntrinsicID() != Intrinsic::vastart) + continue; + // Reinitialize the counter + StoreInst *SI3 = new StoreInst(ConstantInt::get(Int64Ty, 0), Counter); + SI3->insertAfter(CI); + CounterMap[CI->getOperand(1)->stripPointerCasts()] = Counter; + } + } + + // Find all va_copy calls + for (Function::iterator B = NewF->begin(), FE = NewF->end(); B != FE; ++B) { + for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;I++) { + CallInst *CI = dyn_cast(I); + if(!CI) + continue; + Function *CalledF = dyn_cast(CI->getCalledFunction()); + if(!CalledF) + continue; + if(!CalledF->isIntrinsic()) + continue; + if(CalledF->getIntrinsicID() != Intrinsic::vacopy) + continue; + // Reinitialize the counter + AllocaInst *CounterDest = new AllocaInst(Int64Ty, "",&*InsPt); + Value *CounterSource = CounterMap[CI->getOperand(2)->stripPointerCasts()]; + LoadInst *CurrentValue = new LoadInst(CounterSource, "count", CI); + new StoreInst(CurrentValue, CounterDest, CI); + CounterMap[CI->getOperand(1)->stripPointerCasts()] = CounterDest; + } + } + // Modify function to add checks on every var_arg call to ensure that we // are not accessing more arguments than we passed in. @@ -814,13 +898,14 @@ if(!VI) continue; Constant *One = ConstantInt::get(Int64Ty, 1); - LoadInst *OldValue = new LoadInst(Counter, "count", VI); + Value *CounterSrc = CounterMap[VI->getOperand(0)->stripPointerCasts()]; + LoadInst *OldValue = new LoadInst(CounterSrc, "count", VI); Instruction *NewValue = BinaryOperator::Create(BinaryOperator::Add, OldValue, One, "count", VI); - new StoreInst(NewValue, Counter, VI); + new StoreInst(NewValue, CounterSrc, VI); std::vector Args; Instruction *VASize = new LoadInst(VASizeLoc, "", VI); Instruction *VAMetaData = new LoadInst(VAMDLoc, "", VI); @@ -836,26 +921,6 @@ } } - // visit all VAStarts and initialize the counter - CallInst *VAStart = NULL; - for (Function::iterator B = NewF->begin(), FE = NewF->end(); B != FE; ++B) { - for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { - CallInst *CI = dyn_cast(I++); - if(!CI) - continue; - Function *CalledF = dyn_cast(CI->getCalledFunction()); - if(!CalledF) - continue; - if(!CalledF->isIntrinsic()) - continue; - if(CalledF->getIntrinsicID() != Intrinsic::vastart) - continue; - VAStart = CI; - // Reinitialize the counter - StoreInst *SI3 = new StoreInst(ConstantInt::get(Int64Ty, 0), Counter); - SI3->insertAfter(CI); - } - } // modify calls to va list functions to pass the metadata for (Function::iterator B = NewF->begin(), FE = NewF->end(); B != FE; ++B) { @@ -864,11 +929,24 @@ if(!CI) continue; Function *CalledF = dyn_cast(CI->getCalledFunction()); + if(VAListFunctionsMap.find(CalledF) == VAListFunctionsMap.end()) continue; + const Type *ListType = M.getTypeByName("struct.__va_list_tag"); + const Type *ListPtrType = ListType->getPointerTo(); + unsigned VAListArgNum = 0; + for (Function::arg_iterator I = CalledF->arg_begin(); + I != CalledF->arg_end(); ++I) { + VAListArgNum ++; + if(I->getType() == ListPtrType) { + break; + } + } std::vectorArgs; + + Value *CounterSrc = CounterMap[CI->getOperand(VAListArgNum)->stripPointerCasts()]; Instruction *VASize = new LoadInst(VASizeLoc, "", CI); - Instruction *VACounter = new LoadInst(Counter, "", CI); + Instruction *VACounter = new LoadInst(CounterSrc, "", CI); Instruction *VAMetaData = new LoadInst(VAMDLoc, "", CI); Args.push_back(VASize); // toatl count Args.push_back(VACounter); // current count From rafael.espindola at gmail.com Mon Jun 20 12:04:09 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Mon, 20 Jun 2011 17:04:09 -0000 Subject: [llvm-commits] [llvm] r133446 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp Message-ID: <20110620170409.20E472A6C12C@llvm.org> Author: rafael Date: Mon Jun 20 12:04:08 2011 New Revision: 133446 URL: http://llvm.org/viewvc/llvm-project?rev=133446&view=rev Log: Disable again. Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=133446&r1=133445&r2=133446&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Mon Jun 20 12:04:08 2011 @@ -712,7 +712,7 @@ DenseSet UsedByPhi; getRegsUsedByPHIs(*TailBB, &UsedByPhi); - if (isSimpleBB(TailBB)) + if (0 && isSimpleBB(TailBB)) return duplicateSimpleBB(TailBB, TDBBs, UsedByPhi, Copies); // Iterate through all the unique predecessors and tail-duplicate this From justin.holewinski at gmail.com Mon Jun 20 12:08:56 2011 From: justin.holewinski at gmail.com (Justin Holewinski) Date: Mon, 20 Jun 2011 17:08:56 -0000 Subject: [llvm-commits] [llvm] r133447 - /llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp Message-ID: <20110620170856.D077F2A6C12C@llvm.org> Author: jholewinski Date: Mon Jun 20 12:08:56 2011 New Revision: 133447 URL: http://llvm.org/viewvc/llvm-project?rev=133447&view=rev Log: PTX: Fix if-then-else formatting and add missing asserts Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp?rev=133447&r1=133446&r2=133447&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp Mon Jun 20 12:08:56 2011 @@ -304,18 +304,16 @@ // Select the appropriate opcode based on the register class if (RC == PTX::RegI16RegisterClass) { OpCode = PTX::STACKSTOREI16; - } - else if (RC == PTX::RegI32RegisterClass) { + } else if (RC == PTX::RegI32RegisterClass) { OpCode = PTX::STACKSTOREI32; - } - else if (RC == PTX::RegI64RegisterClass) { + } else if (RC == PTX::RegI64RegisterClass) { OpCode = PTX::STACKSTOREI32; - } - else if (RC == PTX::RegF32RegisterClass) { + } else if (RC == PTX::RegF32RegisterClass) { OpCode = PTX::STACKSTOREF32; - } - else if (RC == PTX::RegF64RegisterClass) { + } else if (RC == PTX::RegF64RegisterClass) { OpCode = PTX::STACKSTOREF64; + } else { + llvm_unreachable("Unknown PTX register class!"); } // Build the store instruction (really a mov) @@ -341,18 +339,16 @@ // Select the appropriate opcode based on the register class if (RC == PTX::RegI16RegisterClass) { OpCode = PTX::STACKLOADI16; - } - else if (RC == PTX::RegI32RegisterClass) { + } else if (RC == PTX::RegI32RegisterClass) { OpCode = PTX::STACKLOADI32; - } - else if (RC == PTX::RegI64RegisterClass) { + } else if (RC == PTX::RegI64RegisterClass) { OpCode = PTX::STACKLOADI32; - } - else if (RC == PTX::RegF32RegisterClass) { + } else if (RC == PTX::RegF32RegisterClass) { OpCode = PTX::STACKLOADF32; - } - else if (RC == PTX::RegF64RegisterClass) { + } else if (RC == PTX::RegF64RegisterClass) { OpCode = PTX::STACKLOADF64; + } else { + llvm_unreachable("Unknown PTX register class!"); } // Build the load instruction (really a mov) From justin.holewinski at gmail.com Mon Jun 20 12:15:48 2011 From: justin.holewinski at gmail.com (Justin Holewinski) Date: Mon, 20 Jun 2011 13:15:48 -0400 Subject: [llvm-commits] [llvm] r133443 - in /llvm/trunk/lib/Target/PTX: PTXAsmPrinter.cpp PTXInstrInfo.cpp PTXInstrInfo.h PTXInstrInfo.td In-Reply-To: <2C3AFB7B-D930-4B85-BFA7-5589ADCEF78E@2pi.dk> References: <20110620155620.D18072A6C12C@llvm.org> <2C3AFB7B-D930-4B85-BFA7-5589ADCEF78E@2pi.dk> Message-ID: On Jun 20, 2011, at 12:59 PM, Jakob Stoklund Olesen wrote: > > On Jun 20, 2011, at 8:56 AM, Justin Holewinski wrote: > >> + int OpCode; >> + >> + // Select the appropriate opcode based on the register class >> + if (RC == PTX::RegI16RegisterClass) { >> + OpCode = PTX::STACKSTOREI16; >> + } >> + else if (RC == PTX::RegI32RegisterClass) { >> + OpCode = PTX::STACKSTOREI32; >> + } >> + else if (RC == PTX::RegI64RegisterClass) { >> + OpCode = PTX::STACKSTOREI32; >> + } >> + else if (RC == PTX::RegF32RegisterClass) { >> + OpCode = PTX::STACKSTOREF32; >> + } >> + else if (RC == PTX::RegF64RegisterClass) { >> + OpCode = PTX::STACKSTOREF64; >> + } > > Please add an assertion for the unknown register class case. > > Also, format your else-ifs like so: > > } else if (..) { Fixed in r133447. > > /jakob > Thanks, Justin Holewinski -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110620/f4e15541/attachment.html From rjmccall at apple.com Mon Jun 20 12:17:55 2011 From: rjmccall at apple.com (John McCall) Date: Mon, 20 Jun 2011 10:17:55 -0700 Subject: [llvm-commits] [llvm] r133285 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp In-Reply-To: <4DFEF6DA.4030503@free.fr> References: <20110617202152.D6B812A6C12C@llvm.org> <4DFDF276.5030703@free.fr> <54E09593-01A1-4936-AFF8-7AF19D2C6919@apple.com> <4DFEF6DA.4030503@free.fr> Message-ID: On Jun 20, 2011, at 12:29 AM, Duncan Sands wrote: > Hi John, > >> On Jun 19, 2011, at 5:58 AM, Duncan Sands wrote: >>>> + // Insist that the amount-to-allocate not overflow. >>>> + OverflowingBinaryOperator *OBI = dyn_cast(Val); >>>> + if (OBI&& !OBI->hasNoUnsignedWrap()) return 0; >>> >>> I noticed you dropped the test for NSW. I thought this was a problem because >>> front-ends generally don't ever produce NUW, though they may produce NSW... >> >> Stuart asked me to look at this, and I gave him a quick answer >> that it's generally correct for nuw arithmetic, but that I wasn't as >> certain for nsw arithmetic. Now I think it's probably fine for either >> as long as it's homogenous throughout. >> >> The main restriction on the alloca size argument can be expressed as: >> (N * sizeof(T)) udiv sizeof(T) == N >> However, there's a second restriction, which is that it's undefined >> behavior to allocate something too large for the stack. Technically >> this is target-specific, but if we just assume by fiat that 2^31 is too large, >> then as long as the arithmetic is being done in some reasonable size >> then we know that N * sizeof(T) isn't permitted to signed overflow, either. > > if you are willing to assume that then you don't need to check for nuw either... We can't *assume* it doesn't overflow. That's the whole point of this discussion. There's an implicit multiply in sizeof(sp) as part of the alloca instruction, and it's undefined behavior if either - that multiply causes unsigned overflow or - either the input or output to that multiply is negative. This ends up being equivalent to saying that it's nuw nsw and cannot have a negative result. Since transforms are not permitted to introduce undefined behavior, that means that that this transform has to be forbidden unless we can prove that the multiply we're factoring out will not cause a signed or unsigned overflow, under the assumption that the end result doesn't end up being negative. Going back to Stuart's original test case, we can't apply the transform to this: %a = mul i32 16, %n %b = alloca i8, i32 %b %c = bitcast i8* %x to [16 x i8]* as that might introduce undefined behavior, because the multiply in %a is allowed to overflow, and the multiply in this: %c = alloca [16 x i8], i32 %n is not. > I think I saw some GCC testcases fly by in which people were allocating stack > objects larger than 2^32, so I'm not sure that "N * sizeof(T) < 2^31" is a > reasonable assumption... Okay, so the semantics should be in terms of sizeof(sp). I'm fine with that. John. From rjmccall at apple.com Mon Jun 20 12:20:49 2011 From: rjmccall at apple.com (John McCall) Date: Mon, 20 Jun 2011 10:20:49 -0700 Subject: [llvm-commits] [llvm] r133285 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp In-Reply-To: <4DFEF6DA.4030503@free.fr> References: <20110617202152.D6B812A6C12C@llvm.org> <4DFDF276.5030703@free.fr> <54E09593-01A1-4936-AFF8-7AF19D2C6919@apple.com> <4DFEF6DA.4030503@free.fr> Message-ID: <7CDAC10E-FAB7-4992-A41B-BF352B705921@apple.com> On Jun 20, 2011, at 12:29 AM, Duncan Sands wrote: > Hi John, > >> On Jun 19, 2011, at 5:58 AM, Duncan Sands wrote: >>>> + // Insist that the amount-to-allocate not overflow. >>>> + OverflowingBinaryOperator *OBI = dyn_cast(Val); >>>> + if (OBI&& !OBI->hasNoUnsignedWrap()) return 0; >>> >>> I noticed you dropped the test for NSW. I thought this was a problem because >>> front-ends generally don't ever produce NUW, though they may produce NSW... >> >> Stuart asked me to look at this, and I gave him a quick answer >> that it's generally correct for nuw arithmetic, but that I wasn't as >> certain for nsw arithmetic. Now I think it's probably fine for either >> as long as it's homogenous throughout. >> >> The main restriction on the alloca size argument can be expressed as: >> (N * sizeof(T)) udiv sizeof(T) == N >> However, there's a second restriction, which is that it's undefined >> behavior to allocate something too large for the stack. Technically >> this is target-specific, but if we just assume by fiat that 2^31 is too large, >> then as long as the arithmetic is being done in some reasonable size >> then we know that N * sizeof(T) isn't permitted to signed overflow, either. > > if you are willing to assume that then you don't need to check for nuw either... We can't *assume* it doesn't overflow. That's the whole point of this discussion. There's an implicit multiply in sizeof(sp) as part of the alloca instruction, and it's undefined behavior if either - that multiply causes unsigned overflow or - either the input or output to that multiply is negative. This ends up being equivalent to saying that it's nuw nsw and cannot have a negative result. Since transforms are not permitted to introduce undefined behavior, that means that that this transform has to be forbidden unless we can prove that the multiply we're factoring out will not cause a signed or unsigned overflow, under the assumption that the end result doesn't end up being negative. Going back to Stuart's original test case, we can't apply the transform to this: %a = mul i32 16, %n %b = alloca i8, i32 %b %c = bitcast i8* %x to [16 x i8]* as that might introduce undefined behavior, because the multiply in %a is allowed to overflow, and the multiply in this: %c = alloca [16 x i8], i32 %n is not. > I think I saw some GCC testcases fly by in which people were allocating stack > objects larger than 2^32, so I'm not sure that "N * sizeof(T) < 2^31" is a > reasonable assumption... Okay, so the semantics should be in terms of sizeof(sp). I'm fine with that. John. From jay.foad at gmail.com Mon Jun 20 12:46:19 2011 From: jay.foad at gmail.com (Jay Foad) Date: Mon, 20 Jun 2011 17:46:19 -0000 Subject: [llvm-commits] [llvm] r133449 - /llvm/trunk/lib/VMCore/Instructions.cpp Message-ID: <20110620174619.A9AE72A6C12C@llvm.org> Author: foad Date: Mon Jun 20 12:46:19 2011 New Revision: 133449 URL: http://llvm.org/viewvc/llvm-project?rev=133449&view=rev Log: Fix a check for PHINodes with two incoming values. Modified: llvm/trunk/lib/VMCore/Instructions.cpp Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=133449&r1=133448&r2=133449&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Mon Jun 20 12:46:19 2011 @@ -141,7 +141,7 @@ void PHINode::growOperands() { unsigned e = getNumOperands(); unsigned NumOps = e + e / 2; - if (NumOps < 4) NumOps = 4; // 4 op PHI nodes are VERY common. + if (NumOps < 2) NumOps = 2; // 2 op PHI nodes are VERY common. Use *OldOps = op_begin(); BasicBlock **OldBlocks = block_begin(); From jay.foad at gmail.com Mon Jun 20 12:52:53 2011 From: jay.foad at gmail.com (Jay Foad) Date: Mon, 20 Jun 2011 18:52:53 +0100 Subject: [llvm-commits] [llvm] r133435 - in /llvm/trunk: include/llvm/ include/llvm/Support/ lib/Target/CppBackend/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ In-Reply-To: References: <20110620143801.6C0D72A6C124@llvm.org> Message-ID: On 20 June 2011 17:03, Frits van Bommel wrote: >> ?void PHINode::growOperands() { >> ? unsigned e = getNumOperands(); >> - ?// Multiply by 1.5 and round down so the result is still even. >> - ?unsigned NumOps = e + e / 4 * 2; >> + ?unsigned NumOps = e + e / 2; >> ? if (NumOps < 4) NumOps = 4; ? ? ?// 4 op PHI nodes are VERY common. > > Wouldn't it now be 2-op PHI nodes that are "VERY common"? > (since 2 of the ops used to be basic blocks) Well spotted! I've fixed it now. Jay. From evan.cheng at apple.com Mon Jun 20 13:22:26 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 20 Jun 2011 11:22:26 -0700 Subject: [llvm-commits] patch: use movd for 32-bits and movq for 64-bits consistently In-Reply-To: References: Message-ID: <74360F14-FD32-455F-99C8-0D0C6039DBB1@apple.com> LGTM. Evan On Jun 16, 2011, at 4:15 PM, Nick Lewycky wrote: > On 16 June 2011 15:37, Eli Friedman wrote: > On Thu, Jun 16, 2011 at 3:35 PM, Nick Lewycky wrote: > > On 16 June 2011 15:29, Eli Friedman wrote: > >> > >> On Thu, Jun 16, 2011 at 2:33 PM, Anton Korobeynikov > >> wrote: > >> >> IIRC, we do things the way we do (outside of parsing asm) because the > >> >> old Darwin assembler wouldn't accept "movq %rax, %xmm0", and required > >> >> "movd %rax, %xmm0" instead. I don't recall all the details of that, > >> >> though. > >> > Yeah. Probably it's safe nowadays to get rid of this workaround? > >> > >> Note that even if we do decide to get rid of that workaround, we still > >> need to do the right thing with "movd %rax, %xmm0". > > > > Reject it? Or accept it and assemble as "movq %rax, %xmm0" like GNU as > > does? We've been pretty aggressive about rejecting bad assembly, regardless > > of what as does. > > Accept it; it would be weird to reject a construct that LLVM itself > has been generating for a very long time. > > Sound reasonable. Patch attached! > > Nick > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110620/d6a7b839/attachment.html From ganna at apple.com Mon Jun 20 13:32:35 2011 From: ganna at apple.com (Anna Zaks) Date: Mon, 20 Jun 2011 11:32:35 -0700 Subject: [llvm-commits] Adding add.with.overflow intrinsic support to CBackend. In-Reply-To: References: <20110620143801.6C0D72A6C124@llvm.org> Message-ID: <528BA51E-6300-4AB0-9EC9-345DC43CDD28@apple.com> Hi, Attached is a CBackend patch for review. It adds support for sadd.with.overflow and uadd.with.overflow intrinsics. Essentially, we emit implementation for each add.with.overflow intrinsic that occurs in the module. Issues are lack of support for arbitrary size integers and assumption about the two's compliment representation for integers (casts from signed to unsigned and backwards). However, it seems that these are the limitations of the current CBackend implementation as well. We know that the CBackend is no longer supported and might get completely rewritten, but this patch removes the known blockers for us and might be useful for someone else as well. Thanks, Anna. -------------- next part -------------- A non-text attachment was scrubbed... Name: CBackend-AddWithOverflow.diff Type: application/octet-stream Size: 9037 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110620/757449d9/attachment.obj From nicholas at mxc.ca Mon Jun 20 13:33:27 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 20 Jun 2011 18:33:27 -0000 Subject: [llvm-commits] [llvm] r133452 - in /llvm/trunk: lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/bitcast2.ll test/CodeGen/X86/vec_set-8.ll test/CodeGen/X86/vec_set-9.ll test/CodeGen/X86/vec_set-C.ll test/CodeGen/X86/vec_shuffle-14.ll test/CodeGen/X86/vec_shuffle-17.ll test/MC/X86/x86-64.s test/MC/X86/x86_64-avx-encoding.s Message-ID: <20110620183327.3F55D2A6C12C@llvm.org> Author: nicholas Date: Mon Jun 20 13:33:26 2011 New Revision: 133452 URL: http://llvm.org/viewvc/llvm-project?rev=133452&view=rev Log: Emit movq for 64-bit register to XMM register moves, but continue to accept movd when assembling. Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/test/CodeGen/X86/bitcast2.ll llvm/trunk/test/CodeGen/X86/vec_set-8.ll llvm/trunk/test/CodeGen/X86/vec_set-9.ll llvm/trunk/test/CodeGen/X86/vec_set-C.ll llvm/trunk/test/CodeGen/X86/vec_shuffle-14.ll llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll llvm/trunk/test/MC/X86/x86-64.s llvm/trunk/test/MC/X86/x86_64-avx-encoding.s Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=133452&r1=133451&r2=133452&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Mon Jun 20 13:33:26 2011 @@ -2850,11 +2850,11 @@ [(set VR128:$dst, (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>; def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src), - "mov{d|q}\t{$src, $dst|$dst, $src}", + "movq\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (v2i64 (scalar_to_vector GR64:$src)))]>; def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src), - "mov{d|q}\t{$src, $dst|$dst, $src}", + "movq\t{$src, $dst|$dst, $src}", [(set FR64:$dst, (bitconvert GR64:$src))]>; @@ -2895,7 +2895,7 @@ (iPTR 0))), addr:$dst)]>; def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src), - "mov{d|q}\t{$src, $dst|$dst, $src}", + "movq\t{$src, $dst|$dst, $src}", [(set GR64:$dst, (vector_extract (v2i64 VR128:$src), (iPTR 0)))]>; def MOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src), @@ -2903,7 +2903,7 @@ [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>; def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src), - "mov{d|q}\t{$src, $dst|$dst, $src}", + "movq\t{$src, $dst|$dst, $src}", [(set GR64:$dst, (bitconvert FR64:$src))]>; def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src), "movq\t{$src, $dst|$dst, $src}", @@ -2931,7 +2931,7 @@ (v4i32 (scalar_to_vector GR32:$src)))))]>, VEX; def VMOVZQI2PQIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src), - "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only + "movq\t{$src, $dst|$dst, $src}", // X86-64 only [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))))]>, VEX, VEX_W; @@ -2942,7 +2942,7 @@ [(set VR128:$dst, (v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))))]>; def MOVZQI2PQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src), - "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only + "movq\t{$src, $dst|$dst, $src}", // X86-64 only [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))))]>; } @@ -2968,6 +2968,21 @@ (MOVZDI2PDIrm addr:$src)>; } +// We used to emit this syntax to work around a bug in the Darwin assembler, +// so we'll continue to assemble it. +def : InstAlias<"movd\t{$src, $dst|$dst, $src}", + (MOV64toPQIrr VR128:$dst, GR64:$src), 0>; +def : InstAlias<"movd\t{$src, $dst|$dst, $src}", + (MOV64toSDrr FR64:$dst, GR64:$src), 0>; +def : InstAlias<"movd\t{$src, $dst|$dst, $src}", + (MOVPQIto64rr GR64:$dst, VR128:$src), 0>; +def : InstAlias<"movd\t{$src, $dst|$dst, $src}", + (MOVSDto64rr GR64:$dst, FR64:$src), 0>; +def : InstAlias<"movd\t{$src, $dst|$dst, $src}", + (VMOVZQI2PQIrr VR128:$dst, GR64:$src), 0>; +def : InstAlias<"movd\t{$src, $dst|$dst, $src}", + (MOVZQI2PQIrr VR128:$dst, GR64:$src), 0>; + //===---------------------------------------------------------------------===// // SSE2 - Move Quadword //===---------------------------------------------------------------------===// Modified: llvm/trunk/test/CodeGen/X86/bitcast2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bitcast2.ll?rev=133452&r1=133451&r2=133452&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/bitcast2.ll (original) +++ llvm/trunk/test/CodeGen/X86/bitcast2.ll Mon Jun 20 13:33:26 2011 @@ -1,13 +1,31 @@ -; RUN: llc < %s -march=x86-64 | grep movd | count 2 +; RUN: llc < %s -march=x86-64 | FileCheck %s ; RUN: llc < %s -march=x86-64 | not grep rsp define i64 @test1(double %A) { +; CHECK: test1 +; CHECK: movq %B = bitcast double %A to i64 ret i64 %B } define double @test2(i64 %A) { +; CHECK: test2 +; CHECK: movq %B = bitcast i64 %A to double ret double %B } +define i32 @test3(float %A) { +; CHECK: test3 +; CHECK: movd + %B = bitcast float %A to i32 + ret i32 %B +} + +define float @test4(i32 %A) { +; CHECK: test4 +; CHECK: movd + %B = bitcast i32 %A to float + ret float %B +} + Modified: llvm/trunk/test/CodeGen/X86/vec_set-8.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_set-8.ll?rev=133452&r1=133451&r2=133452&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_set-8.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_set-8.ll Mon Jun 20 13:33:26 2011 @@ -1,7 +1,7 @@ ; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s ; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s ; CHECK-NOT: movsd -; CHECK: movd {{%rdi|%rcx}}, %xmm0 +; CHECK: movq {{%rdi|%rcx}}, %xmm0 ; CHECK-NOT: movsd define <2 x i64> @test(i64 %i) nounwind { Modified: llvm/trunk/test/CodeGen/X86/vec_set-9.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_set-9.ll?rev=133452&r1=133451&r2=133452&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_set-9.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_set-9.ll Mon Jun 20 13:33:26 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 | grep movd | count 1 +; RUN: llc < %s -march=x86-64 | grep movq | count 1 ; RUN: llc < %s -march=x86-64 | grep {movlhps.*%xmm0, %xmm0} define <2 x i64> @test3(i64 %A) nounwind { Modified: llvm/trunk/test/CodeGen/X86/vec_set-C.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_set-C.ll?rev=133452&r1=133451&r2=133452&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_set-C.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_set-C.ll Mon Jun 20 13:33:26 2011 @@ -1,6 +1,6 @@ ; RUN: llc < %s -march=x86 -mattr=+sse2 | grep movq ; RUN: llc < %s -march=x86 -mattr=+sse2 | grep mov | count 1 -; RUN: llc < %s -march=x86-64 -mattr=+sse2 | grep movd +; RUN: llc < %s -march=x86-64 -mattr=+sse2 | grep movq define <2 x i64> @t1(i64 %x) nounwind { %tmp8 = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0 Modified: llvm/trunk/test/CodeGen/X86/vec_shuffle-14.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_shuffle-14.ll?rev=133452&r1=133451&r2=133452&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_shuffle-14.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_shuffle-14.ll Mon Jun 20 13:33:26 2011 @@ -1,7 +1,7 @@ ; RUN: llc < %s -march=x86 -mattr=+sse2 ; RUN: llc < %s -march=x86 -mattr=+sse2 | grep movd | count 1 -; RUN: llc < %s -march=x86-64 -mattr=+sse2 | grep movd | count 2 -; RUN: llc < %s -march=x86-64 -mattr=+sse2 | grep movq | count 3 +; RUN: llc < %s -march=x86-64 -mattr=+sse2 | grep movd | count 1 +; RUN: llc < %s -march=x86-64 -mattr=+sse2 | grep movq | count 4 ; RUN: llc < %s -march=x86 -mattr=+sse2 | not grep xor define <4 x i32> @t1(i32 %a) nounwind { Modified: llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll?rev=133452&r1=133451&r2=133452&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll Mon Jun 20 13:33:26 2011 @@ -1,7 +1,7 @@ ; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s ; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s ; CHECK-NOT: xor -; CHECK: movd {{%rdi|%rcx}}, %xmm0 +; CHECK: movq {{%rdi|%rcx}}, %xmm0 ; CHECK-NOT: xor ; PR2108 Modified: llvm/trunk/test/MC/X86/x86-64.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-64.s?rev=133452&r1=133451&r2=133452&view=diff ============================================================================== --- llvm/trunk/test/MC/X86/x86-64.s (original) +++ llvm/trunk/test/MC/X86/x86-64.s Mon Jun 20 13:33:26 2011 @@ -1128,3 +1128,11 @@ // CHECK: strq // CHECK: encoding: [0x48,0x0f,0x00,0xc8] str %rax + +// CHECK: movq %rdi, %xmm0 +// CHECK: encoding: [0x66,0x48,0x0f,0x6e,0xc7] + movq %rdi,%xmm0 + +// CHECK: movq %rdi, %xmm0 +// CHECK: encoding: [0x66,0x48,0x0f,0x6e,0xc7] + movd %rdi,%xmm0 Modified: llvm/trunk/test/MC/X86/x86_64-avx-encoding.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86_64-avx-encoding.s?rev=133452&r1=133451&r2=133452&view=diff ============================================================================== --- llvm/trunk/test/MC/X86/x86_64-avx-encoding.s (original) +++ llvm/trunk/test/MC/X86/x86_64-avx-encoding.s Mon Jun 20 13:33:26 2011 @@ -1444,9 +1444,9 @@ // CHECK: encoding: [0xc5,0x79,0x7e,0x30] vmovd %xmm14, (%rax) -// CHECK: vmovd %rax, %xmm14 -// CHECK: encoding: [0xc4,0x61,0xf9,0x6e,0xf0] - vmovd %rax, %xmm14 +// CHECK: vmovd %eax, %xmm14 +// CHECK: encoding: [0xc5,0x79,0x6e,0xf0] + vmovd %eax, %xmm14 // CHECK: vmovq %xmm14, (%rax) // CHECK: encoding: [0xc5,0x79,0xd6,0x30] From justin.holewinski at gmail.com Mon Jun 20 13:42:48 2011 From: justin.holewinski at gmail.com (Justin Holewinski) Date: Mon, 20 Jun 2011 18:42:48 -0000 Subject: [llvm-commits] [llvm] r133454 - in /llvm/trunk: lib/Target/PTX/PTXInstrInfo.td test/CodeGen/PTX/cvt.ll test/CodeGen/PTX/setp.ll Message-ID: <20110620184248.C19182A6C12C@llvm.org> Author: jholewinski Date: Mon Jun 20 13:42:48 2011 New Revision: 133454 URL: http://llvm.org/viewvc/llvm-project?rev=133454&view=rev Log: PTX: Fix conversion between predicates and value types Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td llvm/trunk/test/CodeGen/PTX/cvt.ll llvm/trunk/test/CodeGen/PTX/setp.ll Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.td?rev=133454&r1=133453&r2=133454&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Mon Jun 20 13:42:48 2011 @@ -826,31 +826,35 @@ // TODO: Do something with st.param if/when it is needed. // Conversion to pred - +// PTX does not directly support converting to a predicate type, so we fake it +// by performing a greater-than test between the value and zero. This follows +// the C convention that any non-zero value is equivalent to 'true'. def CVT_pred_u16 - : InstPTX<(outs RegPred:$d), (ins RegI16:$a), "cvt.pred.u16\t$d, $a", + : InstPTX<(outs RegPred:$d), (ins RegI16:$a), "setp.gt.b16\t$d, $a, 0", [(set RegPred:$d, (trunc RegI16:$a))]>; def CVT_pred_u32 - : InstPTX<(outs RegPred:$d), (ins RegI32:$a), "cvt.pred.u32\t$d, $a", + : InstPTX<(outs RegPred:$d), (ins RegI32:$a), "setp.gt.b32\t$d, $a, 0", [(set RegPred:$d, (trunc RegI32:$a))]>; def CVT_pred_u64 - : InstPTX<(outs RegPred:$d), (ins RegI64:$a), "cvt.pred.u64\t$d, $a", + : InstPTX<(outs RegPred:$d), (ins RegI64:$a), "setp.gt.b64\t$d, $a, 0", [(set RegPred:$d, (trunc RegI64:$a))]>; def CVT_pred_f32 - : InstPTX<(outs RegPred:$d), (ins RegF32:$a), "cvt.rzi.pred.f32\t$d, $a", + : InstPTX<(outs RegPred:$d), (ins RegF32:$a), "setp.gt.b32\t$d, $a, 0", [(set RegPred:$d, (fp_to_uint RegF32:$a))]>; def CVT_pred_f64 - : InstPTX<(outs RegPred:$d), (ins RegF64:$a), "cvt.rzi.pred.f64\t$d, $a", + : InstPTX<(outs RegPred:$d), (ins RegF64:$a), "setp.gt.b64\t$d, $a, 0", [(set RegPred:$d, (fp_to_uint RegF64:$a))]>; // Conversion to u16 - +// PTX does not directly support converting a predicate to a value, so we +// use a select instruction to select either 0 or 1 (integer or fp) based +// on the truth value of the predicate. def CVT_u16_pred - : InstPTX<(outs RegI16:$d), (ins RegPred:$a), "cvt.u16.pred\t$d, $a", + : InstPTX<(outs RegI16:$d), (ins RegPred:$a), "selp.u16\t$d, 1, 0, $a", [(set RegI16:$d, (zext RegPred:$a))]>; def CVT_u16_u32 @@ -872,7 +876,7 @@ // Conversion to u32 def CVT_u32_pred - : InstPTX<(outs RegI32:$d), (ins RegPred:$a), "cvt.u32.pred\t$d, $a", + : InstPTX<(outs RegI32:$d), (ins RegPred:$a), "selp.u32\t$d, 1, 0, $a", [(set RegI32:$d, (zext RegPred:$a))]>; def CVT_u32_u16 @@ -894,7 +898,7 @@ // Conversion to u64 def CVT_u64_pred - : InstPTX<(outs RegI64:$d), (ins RegPred:$a), "cvt.u64.pred\t$d, $a", + : InstPTX<(outs RegI64:$d), (ins RegPred:$a), "selp.u64\t$d, 1, 0, $a", [(set RegI64:$d, (zext RegPred:$a))]>; def CVT_u64_u16 @@ -916,7 +920,8 @@ // Conversion to f32 def CVT_f32_pred - : InstPTX<(outs RegF32:$d), (ins RegPred:$a), "cvt.rn.f32.pred\t$d, $a", + : InstPTX<(outs RegF32:$d), (ins RegPred:$a), + "selp.f32\t$d, 0F3F800000, 0F00000000, $a", // 1.0 [(set RegF32:$d, (uint_to_fp RegPred:$a))]>; def CVT_f32_u16 @@ -938,7 +943,8 @@ // Conversion to f64 def CVT_f64_pred - : InstPTX<(outs RegF64:$d), (ins RegPred:$a), "cvt.rn.f64.pred\t$d, $a", + : InstPTX<(outs RegF64:$d), (ins RegPred:$a), + "selp.f64\t$d, 0D3F80000000000000, 0D0000000000000000, $a", // 1.0 [(set RegF64:$d, (uint_to_fp RegPred:$a))]>; def CVT_f64_u16 Modified: llvm/trunk/test/CodeGen/PTX/cvt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/cvt.ll?rev=133454&r1=133453&r2=133454&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PTX/cvt.ll (original) +++ llvm/trunk/test/CodeGen/PTX/cvt.ll Mon Jun 20 13:42:48 2011 @@ -4,8 +4,10 @@ ; (note: we convert back to i32 to return) define ptx_device i32 @cvt_pred_i16(i16 %x, i1 %y) { -; CHECK: cvt.pred.u16 p0, rh1; -; CHECK: ret; +; CHECK: setp.gt.b16 p0, rh1, 0 +; CHECK-NEXT: and.pred p0, p0, p1; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; %a = trunc i16 %x to i1 %b = and i1 %a, %y %c = zext i1 %b to i32 @@ -13,8 +15,10 @@ } define ptx_device i32 @cvt_pred_i32(i32 %x, i1 %y) { -; CHECK: cvt.pred.u32 p0, r1; -; CHECK: ret; +; CHECK: setp.gt.b32 p0, r1, 0 +; CHECK-NEXT: and.pred p0, p0, p1; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; %a = trunc i32 %x to i1 %b = and i1 %a, %y %c = zext i1 %b to i32 @@ -22,8 +26,10 @@ } define ptx_device i32 @cvt_pred_i64(i64 %x, i1 %y) { -; CHECK: cvt.pred.u64 p0, rd1; -; CHECK: ret; +; CHECK: setp.gt.b64 p0, rd1, 0 +; CHECK-NEXT: and.pred p0, p0, p1; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; %a = trunc i64 %x to i1 %b = and i1 %a, %y %c = zext i1 %b to i32 @@ -31,8 +37,10 @@ } define ptx_device i32 @cvt_pred_f32(float %x, i1 %y) { -; CHECK: cvt.rzi.pred.f32 p0, r1; -; CHECK: ret; +; CHECK: setp.gt.b32 p0, r1, 0 +; CHECK-NEXT: and.pred p0, p0, p1; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; %a = fptoui float %x to i1 %b = and i1 %a, %y %c = zext i1 %b to i32 @@ -40,8 +48,10 @@ } define ptx_device i32 @cvt_pred_f64(double %x, i1 %y) { -; CHECK: cvt.rzi.pred.f64 p0, rd1; -; CHECK: ret; +; CHECK: setp.gt.b64 p0, rd1, 0 +; CHECK-NEXT: and.pred p0, p0, p1; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; %a = fptoui double %x to i1 %b = and i1 %a, %y %c = zext i1 %b to i32 @@ -51,36 +61,36 @@ ; i16 define ptx_device i16 @cvt_i16_preds(i1 %x) { -; CHECK: cvt.u16.pred rh0, p1; -; CHECK: ret; +; CHECK: selp.u16 rh0, 1, 0, p1; +; CHECK-NEXT: ret; %a = zext i1 %x to i16 ret i16 %a } define ptx_device i16 @cvt_i16_i32(i32 %x) { ; CHECK: cvt.u16.u32 rh0, r1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = trunc i32 %x to i16 ret i16 %a } define ptx_device i16 @cvt_i16_i64(i64 %x) { ; CHECK: cvt.u16.u64 rh0, rd1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = trunc i64 %x to i16 ret i16 %a } define ptx_device i16 @cvt_i16_f32(float %x) { ; CHECK: cvt.rzi.u16.f32 rh0, r1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = fptoui float %x to i16 ret i16 %a } define ptx_device i16 @cvt_i16_f64(double %x) { ; CHECK: cvt.rzi.u16.f64 rh0, rd1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = fptoui double %x to i16 ret i16 %a } @@ -88,36 +98,36 @@ ; i32 define ptx_device i32 @cvt_i32_preds(i1 %x) { -; CHECK: cvt.u32.pred r0, p1; -; CHECK: ret; +; CHECK: selp.u32 r0, 1, 0, p1; +; CHECK-NEXT: ret; %a = zext i1 %x to i32 ret i32 %a } define ptx_device i32 @cvt_i32_i16(i16 %x) { ; CHECK: cvt.u32.u16 r0, rh1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = zext i16 %x to i32 ret i32 %a } define ptx_device i32 @cvt_i32_i64(i64 %x) { ; CHECK: cvt.u32.u64 r0, rd1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = trunc i64 %x to i32 ret i32 %a } define ptx_device i32 @cvt_i32_f32(float %x) { ; CHECK: cvt.rzi.u32.f32 r0, r1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = fptoui float %x to i32 ret i32 %a } define ptx_device i32 @cvt_i32_f64(double %x) { ; CHECK: cvt.rzi.u32.f64 r0, rd1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = fptoui double %x to i32 ret i32 %a } @@ -125,29 +135,29 @@ ; i64 define ptx_device i64 @cvt_i64_preds(i1 %x) { -; CHECK: cvt.u64.pred rd0, p1; -; CHECK: ret; +; CHECK: selp.u64 rd0, 1, 0, p1; +; CHECK-NEXT: ret; %a = zext i1 %x to i64 ret i64 %a } define ptx_device i64 @cvt_i64_i16(i16 %x) { ; CHECK: cvt.u64.u16 rd0, rh1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = zext i16 %x to i64 ret i64 %a } define ptx_device i64 @cvt_i64_i32(i32 %x) { ; CHECK: cvt.u64.u32 rd0, r1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = zext i32 %x to i64 ret i64 %a } define ptx_device i64 @cvt_i64_f32(float %x) { ; CHECK: cvt.rzi.u64.f32 rd0, r1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = fptoui float %x to i64 ret i64 %a } @@ -162,36 +172,36 @@ ; f32 define ptx_device float @cvt_f32_preds(i1 %x) { -; CHECK: cvt.rn.f32.pred r0, p1; -; CHECK: ret; +; CHECK: selp.f32 r0, 0F3F800000, 0F00000000, p1; +; CHECK-NEXT: ret; %a = uitofp i1 %x to float ret float %a } define ptx_device float @cvt_f32_i16(i16 %x) { ; CHECK: cvt.rn.f32.u16 r0, rh1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = uitofp i16 %x to float ret float %a } define ptx_device float @cvt_f32_i32(i32 %x) { ; CHECK: cvt.rn.f32.u32 r0, r1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = uitofp i32 %x to float ret float %a } define ptx_device float @cvt_f32_i64(i64 %x) { ; CHECK: cvt.rn.f32.u64 r0, rd1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = uitofp i64 %x to float ret float %a } define ptx_device float @cvt_f32_f64(double %x) { ; CHECK: cvt.rn.f32.f64 r0, rd1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = fptrunc double %x to float ret float %a } @@ -199,36 +209,36 @@ ; f64 define ptx_device double @cvt_f64_preds(i1 %x) { -; CHECK: cvt.rn.f64.pred rd0, p1; -; CHECK: ret; +; CHECK: selp.f64 rd0, 0D3F80000000000000, 0D0000000000000000, p1; +; CHECK-NEXT: ret; %a = uitofp i1 %x to double ret double %a } define ptx_device double @cvt_f64_i16(i16 %x) { ; CHECK: cvt.rn.f64.u16 rd0, rh1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = uitofp i16 %x to double ret double %a } define ptx_device double @cvt_f64_i32(i32 %x) { ; CHECK: cvt.rn.f64.u32 rd0, r1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = uitofp i32 %x to double ret double %a } define ptx_device double @cvt_f64_i64(i64 %x) { ; CHECK: cvt.rn.f64.u64 rd0, rd1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = uitofp i64 %x to double ret double %a } define ptx_device double @cvt_f64_f32(float %x) { ; CHECK: cvt.f64.f32 rd0, r1; -; CHECK: ret; +; CHECK-NEXT: ret; %a = fpext float %x to double ret double %a } Modified: llvm/trunk/test/CodeGen/PTX/setp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/setp.ll?rev=133454&r1=133453&r2=133454&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PTX/setp.ll (original) +++ llvm/trunk/test/CodeGen/PTX/setp.ll Mon Jun 20 13:42:48 2011 @@ -2,7 +2,7 @@ define ptx_device i32 @test_setp_eq_u32_rr(i32 %x, i32 %y) { ; CHECK: setp.eq.u32 p0, r1, r2; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %p = icmp eq i32 %x, %y %z = zext i1 %p to i32 @@ -11,7 +11,7 @@ define ptx_device i32 @test_setp_ne_u32_rr(i32 %x, i32 %y) { ; CHECK: setp.ne.u32 p0, r1, r2; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %p = icmp ne i32 %x, %y %z = zext i1 %p to i32 @@ -20,7 +20,7 @@ define ptx_device i32 @test_setp_lt_u32_rr(i32 %x, i32 %y) { ; CHECK: setp.lt.u32 p0, r1, r2; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %p = icmp ult i32 %x, %y %z = zext i1 %p to i32 @@ -29,7 +29,7 @@ define ptx_device i32 @test_setp_le_u32_rr(i32 %x, i32 %y) { ; CHECK: setp.le.u32 p0, r1, r2; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %p = icmp ule i32 %x, %y %z = zext i1 %p to i32 @@ -38,7 +38,7 @@ define ptx_device i32 @test_setp_gt_u32_rr(i32 %x, i32 %y) { ; CHECK: setp.gt.u32 p0, r1, r2; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %p = icmp ugt i32 %x, %y %z = zext i1 %p to i32 @@ -47,7 +47,7 @@ define ptx_device i32 @test_setp_ge_u32_rr(i32 %x, i32 %y) { ; CHECK: setp.ge.u32 p0, r1, r2; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %p = icmp uge i32 %x, %y %z = zext i1 %p to i32 @@ -56,7 +56,7 @@ define ptx_device i32 @test_setp_eq_u32_ri(i32 %x) { ; CHECK: setp.eq.u32 p0, r1, 1; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %p = icmp eq i32 %x, 1 %z = zext i1 %p to i32 @@ -65,7 +65,7 @@ define ptx_device i32 @test_setp_ne_u32_ri(i32 %x) { ; CHECK: setp.ne.u32 p0, r1, 1; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %p = icmp ne i32 %x, 1 %z = zext i1 %p to i32 @@ -74,7 +74,7 @@ define ptx_device i32 @test_setp_lt_u32_ri(i32 %x) { ; CHECK: setp.eq.u32 p0, r1, 0; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %p = icmp ult i32 %x, 1 %z = zext i1 %p to i32 @@ -83,7 +83,7 @@ define ptx_device i32 @test_setp_le_u32_ri(i32 %x) { ; CHECK: setp.lt.u32 p0, r1, 2; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %p = icmp ule i32 %x, 1 %z = zext i1 %p to i32 @@ -92,7 +92,7 @@ define ptx_device i32 @test_setp_gt_u32_ri(i32 %x) { ; CHECK: setp.gt.u32 p0, r1, 1; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %p = icmp ugt i32 %x, 1 %z = zext i1 %p to i32 @@ -101,7 +101,7 @@ define ptx_device i32 @test_setp_ge_u32_ri(i32 %x) { ; CHECK: setp.ne.u32 p0, r1, 0; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %p = icmp uge i32 %x, 1 %z = zext i1 %p to i32 @@ -111,7 +111,7 @@ 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: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %c = icmp eq i32 %x, %y %d = icmp ugt i32 %u, %v @@ -121,9 +121,9 @@ } define ptx_device i32 @test_setp_4_op_format_2(i32 %x, i32 %y, i32 %w) { -; CHECK: cvt.pred.u32 p0, r3; +; CHECK: setp.gt.b32 p0, r3, 0; ; CHECK-NEXT: setp.eq.and.u32 p0, r1, r2, !p0; -; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; ; CHECK-NEXT: ret; %c = trunc i32 %w to i1 %d = icmp eq i32 %x, %y From baldrick at free.fr Mon Jun 20 15:06:18 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Jun 2011 20:06:18 -0000 Subject: [llvm-commits] [dragonegg] r133465 - /dragonegg/trunk/README Message-ID: <20110620200618.43AA82A6C12C@llvm.org> Author: baldrick Date: Mon Jun 20 15:06:18 2011 New Revision: 133465 URL: http://llvm.org/viewvc/llvm-project?rev=133465&view=rev Log: I worked out how to build dragonegg against debian's gcc 4.5. Modified: dragonegg/trunk/README Modified: dragonegg/trunk/README URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/README?rev=133465&r1=133464&r2=133465&view=diff ============================================================================== --- dragonegg/trunk/README (original) +++ dragonegg/trunk/README Mon Jun 20 15:06:18 2011 @@ -28,6 +28,12 @@ Build the plugin like this: GCC=PATH_TO_INSTALLED_GCC make This command should be executed in the directory containing this README. +The plugin makes use of various gcc headers that are usually shipped with gcc. +However some linux distributions, for example debian and ubuntu, have split the +headers out of gcc into a separate package. So if you get errors along the +lines of "config.h not found", check whether gcc headers like "config.h" and +"tree.h" are installed. On debian the package containing headers is called +gcc-4.5-plugin-dev or gcc-4.6-plugin-dev. The plugin needs to know about the version of gcc it will be loaded into, which is why you need to specify your version of gcc 4.5/4.6 via the GCC variable like From stoklund at 2pi.dk Mon Jun 20 15:56:05 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 20 Jun 2011 20:56:05 -0000 Subject: [llvm-commits] [llvm] r133470 - /llvm/trunk/utils/TableGen/CodeGenRegisters.cpp Message-ID: <20110620205605.C13162A6C12C@llvm.org> Author: stoklund Date: Mon Jun 20 15:56:05 2011 New Revision: 133470 URL: http://llvm.org/viewvc/llvm-project?rev=133470&view=rev Log: Skip fields that don't exist in the Register class. Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.cpp Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.cpp?rev=133470&r1=133469&r2=133470&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenRegisters.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenRegisters.cpp Mon Jun 20 15:56:05 2011 @@ -236,7 +236,8 @@ if (RV.getName() == "DwarfNumbers" || RV.getName() == "DwarfAlias" || RV.getName() == "Aliases") { - NewReg->addValue(*RegisterCl->getValue(RV.getName())); + if (const RecordVal *DefRV = RegisterCl->getValue(RV.getName())) + NewReg->addValue(*DefRV); continue; } From isanbard at gmail.com Mon Jun 20 17:12:25 2011 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 20 Jun 2011 22:12:25 -0000 Subject: [llvm-commits] [llvm] r133473 - /llvm/trunk/lib/MC/MCAsmStreamer.cpp Message-ID: <20110620221225.258DD2A6C12C@llvm.org> Author: void Date: Mon Jun 20 17:12:24 2011 New Revision: 133473 URL: http://llvm.org/viewvc/llvm-project?rev=133473&view=rev Log: Remove the subclassing. This will be moved to the ASM printer. Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=133473&r1=133472&r2=133473&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Mon Jun 20 17:12:24 2011 @@ -1244,391 +1244,12 @@ if (!UseCFI) EmitFrames(false); } - -//===----------------------------------------------------------------------===// -/// MCLSDADecoderAsmStreamer - This is identical to the MCAsmStreamer, but -/// outputs a description of the LSDA in a human readable format. -/// -namespace { - -class MCLSDADecoderAsmStreamer : public MCAsmStreamer { - const MCSymbol *PersonalitySymbol; - const MCSymbol *LSDASymbol; - bool InLSDA; - bool ReadingULEB128; - - uint64_t BytesRead; - uint64_t ActionTableBytes; - uint64_t LSDASize; - - SmallVector ULEB128Value; - std::vector LSDAEncoding; - std::vector Assignments; - - /// GetULEB128Value - A helper function to convert the value in the - /// ULEB128Value vector into a uint64_t. - uint64_t GetULEB128Value(SmallVectorImpl &ULEB128Value) { - uint64_t Val = 0; - for (unsigned i = 0, e = ULEB128Value.size(); i != e; ++i) - Val |= (ULEB128Value[i] & 0x7F) << (7 * i); - return Val; - } - - /// ResetState - Reset the state variables. - void ResetState() { - PersonalitySymbol = 0; - LSDASymbol = 0; - LSDASize = 0; - BytesRead = 0; - ActionTableBytes = 0; - InLSDA = false; - ReadingULEB128 = false; - ULEB128Value.clear(); - LSDAEncoding.clear(); - Assignments.clear(); - } - - void EmitEHTableDescription(); - - const char *DecodeDWARFEncoding(unsigned Encoding) { - switch (Encoding) { - case dwarf::DW_EH_PE_absptr: return "absptr"; - case dwarf::DW_EH_PE_omit: return "omit"; - case dwarf::DW_EH_PE_pcrel: return "pcrel"; - case dwarf::DW_EH_PE_udata4: return "udata4"; - case dwarf::DW_EH_PE_udata8: return "udata8"; - case dwarf::DW_EH_PE_sdata4: return "sdata4"; - case dwarf::DW_EH_PE_sdata8: return "sdata8"; - case dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata4: return "pcrel udata4"; - case dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata4: return "pcrel sdata4"; - case dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata8: return "pcrel udata8"; - case dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata8: return "pcrel sdata8"; - case dwarf::DW_EH_PE_indirect|dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata4: - return "indirect pcrel udata4"; - case dwarf::DW_EH_PE_indirect|dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata4: - return "indirect pcrel sdata4"; - case dwarf::DW_EH_PE_indirect|dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata8: - return "indirect pcrel udata8"; - case dwarf::DW_EH_PE_indirect|dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata8: - return "indirect pcrel sdata8"; - } - - return ""; - } -public: - MCLSDADecoderAsmStreamer(MCContext &Context, formatted_raw_ostream &os, - bool isVerboseAsm, bool useLoc, bool useCFI, - MCInstPrinter *printer, MCCodeEmitter *emitter, - TargetAsmBackend *asmbackend, - bool showInst) - : MCAsmStreamer(Context, os, isVerboseAsm, useLoc, useCFI, - printer, emitter, asmbackend, showInst) { - ResetState(); - } - ~MCLSDADecoderAsmStreamer() {} - - virtual void Finish() { - ResetState(); - MCAsmStreamer::Finish(); - } - - virtual void EmitLabel(MCSymbol *Symbol) { - if (Symbol == LSDASymbol) - InLSDA = true; - MCAsmStreamer::EmitLabel(Symbol); - } - virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { - if (InLSDA) - Assignments.push_back(Value); - MCAsmStreamer::EmitAssignment(Symbol, Value); - } - virtual void EmitBytes(StringRef Data, unsigned AddrSpace); - virtual void EmitIntValue(uint64_t Value, unsigned Size, - unsigned AddrSpace = 0); - virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - unsigned AddrSpace); - virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, - unsigned AddrSpace); - virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) { - PersonalitySymbol = Sym; - MCAsmStreamer::EmitCFIPersonality(Sym, Encoding); - } - virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { - LSDASymbol = Sym; - MCAsmStreamer::EmitCFILsda(Sym, Encoding); - } -}; - -} // end anonymous namespace - -void MCLSDADecoderAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { - if (InLSDA && Data.size() == 1) { - LSDAEncoding.push_back((unsigned)(unsigned char)Data[0]); - ++BytesRead; - - if (LSDAEncoding.size() == 4) - // The fourth value tells us where the bottom of the type table is. - LSDASize = BytesRead + LSDAEncoding[3]; - else if (LSDAEncoding.size() == 6) - // The sixth value tells us where the start of the action table is. - ActionTableBytes = BytesRead; - } - - MCAsmStreamer::EmitBytes(Data, AddrSpace); -} - -void MCLSDADecoderAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size, - unsigned AddrSpace) { - if (!InLSDA) - return MCAsmStreamer::EmitIntValue(Value, Size, AddrSpace); - - BytesRead += Size; - - // We place the LSDA into the LSDAEncoding vector for later analysis. If we - // have a ULEB128, we read that in separate iterations through here and then - // get its value. - if (!ReadingULEB128) { - LSDAEncoding.push_back(Value); - int EncodingSize = LSDAEncoding.size(); - - if (EncodingSize == 1 || EncodingSize == 3) { - // The LPStart and TType encodings. - if (Value != dwarf::DW_EH_PE_omit) { - // The encoding is next and is a ULEB128 value. - ReadingULEB128 = true; - ULEB128Value.clear(); - } else { - // The encoding was omitted. Put a 0 here as a placeholder. - LSDAEncoding.push_back(0); - } - } else if (EncodingSize == 5) { - // The next value is a ULEB128 value that tells us how long the call site - // table is -- where the start of the action tab - ReadingULEB128 = true; - ULEB128Value.clear(); - } - - InLSDA = (LSDASize == 0 || BytesRead < LSDASize); - } else { - // We're reading a ULEB128. Make it so! - ULEB128Value.push_back(Value); - - if ((Value & 0x80) == 0) { - uint64_t Val = GetULEB128Value(ULEB128Value); - LSDAEncoding.push_back(Val); - ULEB128Value.clear(); - ReadingULEB128 = false; - - if (LSDAEncoding.size() == 4) - // The fourth value tells us where the bottom of the type table is. - LSDASize = BytesRead + LSDAEncoding[3]; - else if (LSDAEncoding.size() == 6) - // The sixth value tells us where the start of the action table is. - ActionTableBytes = BytesRead; - } - } - - MCAsmStreamer::EmitValueImpl(MCConstantExpr::Create(Value, getContext()), - Size, AddrSpace); - - if (LSDASize != 0 && !InLSDA) - EmitEHTableDescription(); -} - -void MCLSDADecoderAsmStreamer::EmitValueImpl(const MCExpr *Value, - unsigned Size, - unsigned AddrSpace) { - if (InLSDA && LSDASize != 0) { - assert(BytesRead + Size <= LSDASize && "EH table too small!"); - - if (BytesRead > uint64_t(LSDAEncoding[5]) + ActionTableBytes) - // Insert the type values. - Assignments.push_back(Value); - - LSDAEncoding.push_back(Assignments.size()); - BytesRead += Size; - InLSDA = (LSDASize == 0 || BytesRead < LSDASize); - } - - MCAsmStreamer::EmitValueImpl(Value, Size, AddrSpace); - - if (LSDASize != 0 && !InLSDA) - EmitEHTableDescription(); -} - -void MCLSDADecoderAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, - unsigned AddrSpace) { - if (InLSDA && ReadingULEB128) { - for (uint64_t I = NumBytes; I != 0; --I) - ULEB128Value.push_back(FillValue); - - BytesRead += NumBytes; - - if ((FillValue & 0x80) == 0) { - uint64_t Val = GetULEB128Value(ULEB128Value); - LSDAEncoding.push_back(Val); - ULEB128Value.clear(); - ReadingULEB128 = false; - - if (LSDAEncoding.size() == 4) - // The fourth value tells us where the bottom of the type table is. - LSDASize = BytesRead + LSDAEncoding[3]; - else if (LSDAEncoding.size() == 6) - // The sixth value tells us where the start of the action table is. - ActionTableBytes = BytesRead; - } - } - - MCAsmStreamer::EmitFill(NumBytes, FillValue, AddrSpace); -} - -/// EmitEHTableDescription - Emit a human readable version of the LSDA. -void MCLSDADecoderAsmStreamer::EmitEHTableDescription() { - assert(LSDAEncoding.size() > 6 && "Invalid LSDA!"); - - // Emit header information. - StringRef C = MAI.getCommentString(); -#define CMT OS << C << ' ' - CMT << "Exception Handling Table: " << LSDASymbol->getName() << "\n"; - CMT << " @LPStart Encoding: " << DecodeDWARFEncoding(LSDAEncoding[0]) << "\n"; - if (LSDAEncoding[1]) - CMT << "@LPStart: 0x" << LSDAEncoding[1] << "\n"; - CMT << " @TType Encoding: " << DecodeDWARFEncoding(LSDAEncoding[2]) << "\n"; - CMT << " @TType Base: " << LSDAEncoding[3] << " bytes\n"; - CMT << "@CallSite Encoding: " << DecodeDWARFEncoding(LSDAEncoding[4]) << "\n"; - CMT << "@Action Table Size: " << LSDAEncoding[5] << " bytes\n\n"; - - bool isSjLjEH = (MAI.getExceptionHandlingType() == ExceptionHandling::SjLj); - - int64_t CallSiteTableSize = LSDAEncoding[5]; - unsigned CallSiteEntrySize; - if (!isSjLjEH) - CallSiteEntrySize = 4 + // Region start. - 4 + // Region end. - 4 + // Landing pad. - 1; // TType index. - else - CallSiteEntrySize = 1 + // Call index. - 1; // TType index. - - unsigned NumEntries = CallSiteTableSize / CallSiteEntrySize; - assert(CallSiteTableSize % CallSiteEntrySize == 0 && - "The action table size is not a multiple of what it should be!"); - unsigned TTypeIdx = 5 + // Action table size index. - (isSjLjEH ? 2 : 4) * NumEntries + // Action table entries. - 1; // Just because. - - // Emit the action table. - unsigned Action = 1; - for (unsigned I = 6; I < TTypeIdx; ) { - CMT << "Action " << Action++ << ":\n"; - - // The beginning of the throwing region. - uint64_t Idx = LSDAEncoding[I++]; - - if (!isSjLjEH) { - CMT << " A throw between " - << *cast(Assignments[Idx - 1])->getLHS() << " and "; - - // The end of the throwing region. - Idx = LSDAEncoding[I++]; - OS << *cast(Assignments[Idx - 1])->getLHS(); - - // The landing pad. - Idx = LSDAEncoding[I++]; - if (Idx) { - OS << " jumps to " - << *cast(Assignments[Idx - 1])->getLHS() - << " on an exception.\n"; - } else { - OS << " does not have a landing pad.\n"; - ++I; - continue; - } - } else { - CMT << " A throw from call " << Idx << "\n"; - } - - // The index into the action table. - Idx = LSDAEncoding[I++]; - if (!Idx) { - CMT << " :cleanup:\n"; - continue; - } - - // A semi-graphical representation of what the different indexes are in the - // loop below. - // - // Idx - Index into the action table. - // Action - Index into the type table from the type table base. - // Next - Offset from Idx to the next action type. - // - // Idx---. - // | - // v - // [call site table] _1 _2 _3 - // TTypeIdx--> ......................... - // [action 1] _1 _2 - // [action 2] _1 _2 - // ... - // [action n] _1 _2 - // [type m] ^ - // ... | - // [type 1] `---Next - // - - int Action = LSDAEncoding[TTypeIdx + Idx - 1]; - if ((Action & 0x40) != 0) - // Ignore exception specifications. - continue; - - // Emit the types that are caught by this exception. - CMT << " For type(s): "; - for (;;) { - if ((Action & 0x40) != 0) - // Ignore exception specifications. - break; - - if (uint64_t Ty = LSDAEncoding[LSDAEncoding.size() - Action]) { - OS << " " << *Assignments[Ty - 1]; - - // Types can be chained together. Typically, it's a negative offset from - // the current type to a different one in the type table. - int Next = LSDAEncoding[TTypeIdx + Idx]; - if (Next == 0) - break; - if ((Next & 0x40) != 0) - Next = (int)(signed char)(Next | 0x80); - Idx += Next + 1; - Action = LSDAEncoding[TTypeIdx + Idx - 1]; - continue; - } else { - OS << " :catchall:"; - } - break; - } - - OS << "\n"; - } - - OS << "\n"; - ResetState(); -} - MCStreamer *llvm::createAsmStreamer(MCContext &Context, formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, bool useCFI, MCInstPrinter *IP, MCCodeEmitter *CE, TargetAsmBackend *TAB, bool ShowInst) { - ExceptionHandling::ExceptionsType ET = - Context.getAsmInfo().getExceptionHandlingType(); - - if (useCFI && isVerboseAsm && - (ET == ExceptionHandling::SjLj || ET == ExceptionHandling::DwarfCFI)) - return new MCLSDADecoderAsmStreamer(Context, OS, isVerboseAsm, useLoc, - useCFI, IP, CE, TAB, ShowInst); - return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI, IP, CE, TAB, ShowInst); } From aggarwa4 at illinois.edu Mon Jun 20 17:22:32 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 20 Jun 2011 22:22:32 -0000 Subject: [llvm-commits] [poolalloc] r133474 - /poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c Message-ID: <20110620222232.CCBE32A6C12C@llvm.org> Author: aggarwa4 Date: Mon Jun 20 17:22:32 2011 New Revision: 133474 URL: http://llvm.org/viewvc/llvm-project?rev=133474&view=rev Log: Break track Load into 2 parts, one that reads the metadata and one that checks it. This is work to break up the check on load to getting data at the load and checking at the uses. Modified: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c Modified: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c?rev=133474&r1=133473&r2=133474&view=diff ============================================================================== --- poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c (original) +++ poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c Mon Jun 20 17:22:32 2011 @@ -150,29 +150,26 @@ compareTypes(TypeAccessed, ((uint8_t*)MD)[ArgAccessed], tag); } -/** - * Check the loaded type against the type recorded in the shadow memory. - */ -void trackLoadInst(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) { - uint8_t i = 1; +void getTypeTag(void *ptr, uint64_t size, uint8_t *dest) { uintptr_t p = maskAddress(ptr); assert(p + size < SIZE); -#if DEBUG - printf("Load(%d): %p, %p = actual: %u, expect: %u | %lu bytes\n", tag, ptr, (void *)p, typeNumber, shadow_begin[p], size); -#endif + memcpy(dest, &shadow_begin[p], size); +} +void checkType(uint8_t typeNumber, uint64_t size, uint8_t *metadata, void *ptr, uint32_t tag) { + uint8_t i = 1; /* Check if this an initialized but untyped memory.*/ - if (typeNumber != shadow_begin[p]) { - if (shadow_begin[p] != 0xFF) { - printf("Type mismatch(%u): %p expecting %s, found %s!\n", tag, ptr, typeNames[typeNumber], typeNames[shadow_begin[p]]); + if (typeNumber != metadata[0]) { + if (metadata[0] != 0xFF) { + printf("Type mismatch(%u): %p expecting %s, found %s!\n", tag, ptr, typeNames[typeNumber], typeNames[metadata[0]]); return; } else { /* If so, set type to the type being read. Check that none of the bytes are typed.*/ for (; i < size; ++i) { - if (0xFF != shadow_begin[p + i]) { - printf("Type alignment mismatch(%u): expecting %s, found %s!\n", tag, typeNames[typeNumber], typeNames[shadow_begin[p+i]]); + if (0xFF != metadata[i]) { + printf("Type alignment mismatch(%u): expecting %s, found %s!\n", tag, typeNames[typeNumber], typeNames[metadata[i]]); break; } } @@ -182,12 +179,29 @@ } for (; i < size; ++i) { - if (0 != shadow_begin[p + i]) { - printf("Type alignment mismatch(%u): expecting %s, found %s!\n", tag, typeNames[typeNumber], typeNames[shadow_begin[p]]); + if (0 != metadata[i]) { + printf("Type alignment mismatch(%u): expecting %s, found %s!\n", tag, typeNames[typeNumber], typeNames[metadata[0]]); break; } } + } +/** + * Check the loaded type against the type recorded in the shadow memory. + */ +void trackLoadInst(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) { + uint8_t *metadata = malloc(size); + + getTypeTag(ptr, size, metadata); + + checkType(typeNumber, size ,metadata, ptr, tag); +#if DEBUG + printf("Load(%d): %p, %p = actual: %u, expect: %u | %lu bytes\n", tag, ptr, (void *)p, typeNumber, shadow_begin[p], size); +#endif + + free(metadata); +} + /** * For memset type instructions, that set values. From aggarwa4 at illinois.edu Mon Jun 20 17:57:07 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 20 Jun 2011 22:57:07 -0000 Subject: [llvm-commits] [poolalloc] r133477 - /poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Message-ID: <20110620225708.045C32A6C12C@llvm.org> Author: aggarwa4 Date: Mon Jun 20 17:57:07 2011 New Revision: 133477 URL: http://llvm.org/viewvc/llvm-project?rev=133477&view=rev Log: WIP: Break up the calls to track Load into 2 parts, one to get the metadata, one to do check. Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=133477&r1=133476&r2=133477&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Mon Jun 20 17:57:07 2011 @@ -63,6 +63,7 @@ static Constant *RegisterArgv; static Constant *RegisterEnvp; static Constant *compareTypeAndNumber; +static Constant *getTypeTag; unsigned int TypeChecks::getTypeMarker(const Type * Ty) { if(DisablePointerTypeChecks) { @@ -156,11 +157,18 @@ Int64Ty,/*size*/ Int32Ty,/*tag*/ NULL); - trackLoadInst = M.getOrInsertFunction("trackLoadInst", + getTypeTag = M.getOrInsertFunction("getTypeTag", + VoidTy, + VoidPtrTy, /*ptr*/ + Int64Ty, /*size*/ + VoidPtrTy, /*dest for type tag*/ + NULL); + trackLoadInst = M.getOrInsertFunction("checkType", VoidTy, - VoidPtrTy,/*ptr*/ Int8Ty,/*type*/ Int64Ty,/*size*/ + VoidPtrTy, + VoidPtrTy,/*ptr*/ Int32Ty,/*tag*/ NULL); copyTypeInfo = M.getOrInsertFunction("copyTypeInfo", @@ -253,14 +261,14 @@ continue; } } - + // Modify all byval functions while(!ByValFunctions.empty()) { Function *F = ByValFunctions.back(); ByValFunctions.pop_back(); modified |= visitByValFunction(M, *F); } - + // NOTE:must visit before VAArgFunctions, to populate the map with the // correct cloned functions. @@ -273,7 +281,7 @@ // iterate through all the VAList funtions and modify call sites // to call the new function std::map::iterator FI = VAListFunctionsMap.begin(), - FE = VAListFunctionsMap.end(); + FE = VAListFunctionsMap.end(); for(; FI != FE; FI++) { visitVAListCall(FI->second); } @@ -291,7 +299,7 @@ continue; visitAddressTakenFunction(M, *F); } - + for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) { Function &F = *MI; if(F.isDeclaration()) @@ -337,7 +345,7 @@ Function *F = FI->first; Constant *CNew = ConstantExpr::getBitCast(FI->second, F->getType()); - + std::set toReplace; for(Function::use_iterator User = F->use_begin(); User != F->use_end();++User) { @@ -374,7 +382,7 @@ // Temporary fix. Revisit. // //for (unsigned index = 0; index < ReplaceWorklist.size(); ++index) { - C->replaceUsesOfWithOnConstant(F, CNew, ReplaceWorklist[0]); + C->replaceUsesOfWithOnConstant(F, CNew, ReplaceWorklist[0]); //} continue; } @@ -431,7 +439,7 @@ // For each used type, create a new entry. // Also add these strings to the Values list std::map::iterator TI = UsedTypes.begin(), - TE = UsedTypes.end(); + TE = UsedTypes.end(); for(;TI!=TE; ++TI) { std::string *type = new std::string(); llvm::raw_string_ostream *test = new llvm::raw_string_ostream(*type); @@ -502,146 +510,146 @@ } } -bool TypeChecks::visitVAListFunction(Module &M, Function &F_orig) { - if(!F_orig.hasInternalLinkage()) - return false; + bool TypeChecks::visitVAListFunction(Module &M, Function &F_orig) { + if(!F_orig.hasInternalLinkage()) + return false; - int VAListArgNum = 0; - // Check if one of the arguments is a va_list - const Type *ListType = M.getTypeByName("struct.__va_list_tag"); - if(!ListType) - return false; - const Type *ListPtrType = ListType->getPointerTo(); - Argument *VAListArg = NULL; - for (Function::arg_iterator I = F_orig.arg_begin(); - I != F_orig.arg_end(); ++I) { - VAListArgNum ++; - if(I->getType() == ListPtrType) { - VAListArg = I; - break; + int VAListArgNum = 0; + // Check if one of the arguments is a va_list + const Type *ListType = M.getTypeByName("struct.__va_list_tag"); + if(!ListType) + return false; + const Type *ListPtrType = ListType->getPointerTo(); + Argument *VAListArg = NULL; + for (Function::arg_iterator I = F_orig.arg_begin(); + I != F_orig.arg_end(); ++I) { + VAListArgNum ++; + if(I->getType() == ListPtrType) { + VAListArg = I; + break; + } } - } - - // Clone the function to add arguments for count, MD - - // 1. Create the new argument types vector - std::vectorTP; - TP.push_back(Int64Ty); // for count - TP.push_back(Int64Ty); // for count - TP.push_back(VoidPtrTy); // for MD - for (Function::arg_iterator I = F_orig.arg_begin(); - I != F_orig.arg_end(); ++I) { - TP.push_back(I->getType()); - } - // 2. Create the new function prototype - const FunctionType *NewFTy = FunctionType::get(F_orig.getReturnType(), - TP,/*argument types*/ - false);/*vararg*/ - Function *F = Function::Create(NewFTy, - GlobalValue::InternalLinkage, - F_orig.getNameStr() + ".INT", - &M); - - // 3. Set the mapping for args - Function::arg_iterator NI = F->arg_begin(); - DenseMap ValueMap; - NI->setName("TotalCount"); - NI++; - NI->setName("CurrentCount"); - NI++; - NI->setName("MD"); - NI++; - for (Function::arg_iterator II = F_orig.arg_begin(); - NI != F->arg_end(); ++II, ++NI) { - // Each new argument maps to the argument in the old function - // For these arguments, also copy over the attributes - ValueMap[II] = NI; - NI->setName(II->getName()); - NI->addAttr(F_orig.getAttributes() - .getParamAttributes(II->getArgNo() + 1)); - } - - // 4. Copy over the attributes for the function. - F->setAttributes(F->getAttributes() - .addAttr(0, F_orig.getAttributes().getRetAttributes())); - F->setAttributes(F->getAttributes() - .addAttr(~0, F_orig.getAttributes().getFnAttributes())); - - // 5. Perform the cloning. - SmallVector Returns; - CloneFunctionInto(F, &F_orig, ValueMap, Returns); - VAListFunctionsMap[&F_orig] = F; - inst_iterator InsPt = inst_begin(F); + // Clone the function to add arguments for count, MD - - // Store the information - Function::arg_iterator NII = F->arg_begin(); - AllocaInst *VASizeLoc = new AllocaInst(Int64Ty, "", &*InsPt); - new StoreInst(NII, VASizeLoc, &*InsPt); - NII++; - AllocaInst *Counter = new AllocaInst(Int64Ty, "",&*InsPt); - new StoreInst(NII, Counter, &*InsPt); - CounterMap[NII] = Counter; - NII++; - AllocaInst *VAMDLoc = new AllocaInst(VoidPtrTy, "", &*InsPt); - new StoreInst(NII, VAMDLoc, &*InsPt); - - // Find all va_copy calls - for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { - for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;I++) { - CallInst *CI = dyn_cast(I); - if(!CI) - continue; - Function *CalledF = dyn_cast(CI->getCalledFunction()); - if(!CalledF) - continue; - if(!CalledF->isIntrinsic()) - continue; - if(CalledF->getIntrinsicID() != Intrinsic::vacopy) - continue; - // Reinitialize the counter - AllocaInst *CounterDest = new AllocaInst(Int64Ty, "",&*InsPt); - Value *CounterSource = CounterMap[CI->getOperand(2)->stripPointerCasts()]; - LoadInst *CurrentValue = new LoadInst(CounterSource, "count", CI); - new StoreInst(CurrentValue, CounterDest, CI); - CounterMap[CI->getOperand(1)->stripPointerCasts()] = CounterDest; + // 1. Create the new argument types vector + std::vectorTP; + TP.push_back(Int64Ty); // for count + TP.push_back(Int64Ty); // for count + TP.push_back(VoidPtrTy); // for MD + for (Function::arg_iterator I = F_orig.arg_begin(); + I != F_orig.arg_end(); ++I) { + TP.push_back(I->getType()); + } + // 2. Create the new function prototype + const FunctionType *NewFTy = FunctionType::get(F_orig.getReturnType(), + TP,/*argument types*/ + false);/*vararg*/ + Function *F = Function::Create(NewFTy, + GlobalValue::InternalLinkage, + F_orig.getNameStr() + ".INT", + &M); + + // 3. Set the mapping for args + Function::arg_iterator NI = F->arg_begin(); + DenseMap ValueMap; + NI->setName("TotalCount"); + NI++; + NI->setName("CurrentCount"); + NI++; + NI->setName("MD"); + NI++; + for (Function::arg_iterator II = F_orig.arg_begin(); + NI != F->arg_end(); ++II, ++NI) { + // Each new argument maps to the argument in the old function + // For these arguments, also copy over the attributes + ValueMap[II] = NI; + NI->setName(II->getName()); + NI->addAttr(F_orig.getAttributes() + .getParamAttributes(II->getArgNo() + 1)); + } + + // 4. Copy over the attributes for the function. + F->setAttributes(F->getAttributes() + .addAttr(0, F_orig.getAttributes().getRetAttributes())); + F->setAttributes(F->getAttributes() + .addAttr(~0, F_orig.getAttributes().getFnAttributes())); + + // 5. Perform the cloning. + SmallVector Returns; + CloneFunctionInto(F, &F_orig, ValueMap, Returns); + + VAListFunctionsMap[&F_orig] = F; + inst_iterator InsPt = inst_begin(F); + + + // Store the information + Function::arg_iterator NII = F->arg_begin(); + AllocaInst *VASizeLoc = new AllocaInst(Int64Ty, "", &*InsPt); + new StoreInst(NII, VASizeLoc, &*InsPt); + NII++; + AllocaInst *Counter = new AllocaInst(Int64Ty, "",&*InsPt); + new StoreInst(NII, Counter, &*InsPt); + CounterMap[NII] = Counter; + NII++; + AllocaInst *VAMDLoc = new AllocaInst(VoidPtrTy, "", &*InsPt); + new StoreInst(NII, VAMDLoc, &*InsPt); + + // Find all va_copy calls + for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { + for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;I++) { + CallInst *CI = dyn_cast(I); + if(!CI) + continue; + Function *CalledF = dyn_cast(CI->getCalledFunction()); + if(!CalledF) + continue; + if(!CalledF->isIntrinsic()) + continue; + if(CalledF->getIntrinsicID() != Intrinsic::vacopy) + continue; + // Reinitialize the counter + AllocaInst *CounterDest = new AllocaInst(Int64Ty, "",&*InsPt); + Value *CounterSource = CounterMap[CI->getOperand(2)->stripPointerCasts()]; + LoadInst *CurrentValue = new LoadInst(CounterSource, "count", CI); + new StoreInst(CurrentValue, CounterDest, CI); + CounterMap[CI->getOperand(1)->stripPointerCasts()] = CounterDest; + } } - } - // instrument va_arg to increment the counter - for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { - for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { - VAArgInst *VI = dyn_cast(I++); - if(!VI) - continue; - Constant *One = ConstantInt::get(Int64Ty, 1); - Value *CounterSrc = CounterMap[VI->getOperand(0)->stripPointerCasts()]; - LoadInst *OldValue = new LoadInst(CounterSrc, "count", VI); - Instruction *NewValue = BinaryOperator::Create(BinaryOperator::Add, - OldValue, - One, - "count", - VI); - new StoreInst(NewValue, CounterSrc, VI); - std::vector Args; - Instruction *VASize = new LoadInst(VASizeLoc, "", VI); - Instruction *VAMetaData = new LoadInst(VAMDLoc, "", VI); - Args.push_back(VASize); - Args.push_back(OldValue); - Args.push_back(getTypeMarkerConstant(VI)); - Args.push_back(VAMetaData); - Args.push_back(getTagCounter()); - CallInst::Create(compareTypeAndNumber, - Args.begin(), - Args.end(), - "", VI); + // instrument va_arg to increment the counter + for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { + for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { + VAArgInst *VI = dyn_cast(I++); + if(!VI) + continue; + Constant *One = ConstantInt::get(Int64Ty, 1); + Value *CounterSrc = CounterMap[VI->getOperand(0)->stripPointerCasts()]; + LoadInst *OldValue = new LoadInst(CounterSrc, "count", VI); + Instruction *NewValue = BinaryOperator::Create(BinaryOperator::Add, + OldValue, + One, + "count", + VI); + new StoreInst(NewValue, CounterSrc, VI); + std::vector Args; + Instruction *VASize = new LoadInst(VASizeLoc, "", VI); + Instruction *VAMetaData = new LoadInst(VAMDLoc, "", VI); + Args.push_back(VASize); + Args.push_back(OldValue); + Args.push_back(getTypeMarkerConstant(VI)); + Args.push_back(VAMetaData); + Args.push_back(getTagCounter()); + CallInst::Create(compareTypeAndNumber, + Args.begin(), + Args.end(), + "", VI); + } } - } - return true; -} + return true; + } bool TypeChecks::visitAddressTakenFunction(Module &M, Function &F) { // Clone function @@ -1376,30 +1384,30 @@ return true; } -bool TypeChecks::visitMain(Module &M, Function &MainFunc) { - if(MainFunc.arg_size() < 2) - // No need to register - return false; + bool TypeChecks::visitMain(Module &M, Function &MainFunc) { + if(MainFunc.arg_size() < 2) + // No need to register + return false; + + Function::arg_iterator AI = MainFunc.arg_begin(); + Value *Argc = AI; + Value *Argv = ++AI; + + Instruction *InsertPt = MainFunc.front().begin(); + std::vector fargs; + fargs.push_back (Argc); + fargs.push_back (Argv); + CallInst::Create (RegisterArgv, fargs.begin(), fargs.end(), "", InsertPt); - Function::arg_iterator AI = MainFunc.arg_begin(); - Value *Argc = AI; - Value *Argv = ++AI; - - Instruction *InsertPt = MainFunc.front().begin(); - std::vector fargs; - fargs.push_back (Argc); - fargs.push_back (Argv); - CallInst::Create (RegisterArgv, fargs.begin(), fargs.end(), "", InsertPt); + if(MainFunc.arg_size() < 3) + return true; - if(MainFunc.arg_size() < 3) + Value *Envp = ++AI; + std::vector Args; + Args.push_back(Envp); + CallInst::Create(RegisterEnvp, Args.begin(), Args.end(), "", InsertPt); return true; - - Value *Envp = ++AI; - std::vector Args; - Args.push_back(Envp); - CallInst::Create(RegisterEnvp, Args.begin(), Args.end(), "", InsertPt); - return true; -} + } bool TypeChecks::visitGlobal(Module &M, GlobalVariable &GV, Constant *C, Instruction &I, SmallVector Indices) { @@ -1956,17 +1964,40 @@ // Insert runtime checks before all load instructions. bool TypeChecks::visitLoadInst(Module &M, LoadInst &LI) { + inst_iterator InsPt = inst_begin(LI.getParent()->getParent()); // Cast the pointer operand to i8* for the runtime function. CastInst *BCI = BitCastInst::CreatePointerCast(LI.getPointerOperand(), VoidPtrTy, "", &LI); + Value *Size = ConstantInt::get(Int32Ty, getSize(LI.getType())); + AllocaInst *AI = new AllocaInst(Int8Ty, Size, "", &*InsPt); + CastInst *BCI_MD = BitCastInst::CreatePointerCast(AI, VoidPtrTy, "", &*InsPt); + + std::vectorArgs1; + Args1.push_back(BCI); + Args1.push_back(getSizeConstant(LI.getType())); + Args1.push_back(BCI_MD); + CallInst::Create(getTypeTag, Args1.begin(), Args1.end(), "", &LI); std::vector Args; - Args.push_back(BCI); Args.push_back(getTypeMarkerConstant(&LI)); Args.push_back(getSizeConstant(LI.getType())); + Args.push_back(BCI_MD); + Args.push_back(BCI); Args.push_back(getTagCounter()); + CallInst::Create(trackLoadInst, Args.begin(), Args.end(), "", &LI); + + /*for(Value::use_iterator II = LI.use_begin(); II != LI.use_end(); ++II) { + + std::vector Args; + Args.push_back(getTypeMarkerConstant(&LI)); + Args.push_back(getSizeConstant(LI.getType())); + Args.push_back(BCI_MD); + Args.push_back(BCI); + Args.push_back(getTagCounter()); + CallInst::Create(trackLoadInst, Args.begin(), Args.end(), "", cast(II.getUse().getUser())); + }*/ // Create the call to the runtime check and place it before the load instruction. - CallInst::Create(trackLoadInst, Args.begin(), Args.end(), "", &LI); + //CallInst::Create(trackLoadInst, Args.begin(), Args.end(), "", &LI); numLoadChecks++; return true; } From gohman at apple.com Mon Jun 20 18:20:43 2011 From: gohman at apple.com (Dan Gohman) Date: Mon, 20 Jun 2011 23:20:43 -0000 Subject: [llvm-commits] [llvm] r133478 - /llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Message-ID: <20110620232043.BE5F72A6C12C@llvm.org> Author: djg Date: Mon Jun 20 18:20:43 2011 New Revision: 133478 URL: http://llvm.org/viewvc/llvm-project?rev=133478&view=rev Log: Completely short-circuit out ARC optimization if the ARC runtime functions do not appear in the module. Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp?rev=133478&r1=133477&r2=133478&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Mon Jun 20 18:20:43 2011 @@ -33,6 +33,7 @@ #include "llvm/Intrinsics.h" #include "llvm/GlobalVariable.h" #include "llvm/DerivedTypes.h" +#include "llvm/Module.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Support/CallSite.h" @@ -564,6 +565,29 @@ return 0; } +/// ModuleHasARC - Test if the given module looks interesting to run ARC +/// optimization on. +static bool ModuleHasARC(const Module &M) { + return + M.getNamedValue("objc_retain") || + M.getNamedValue("objc_release") || + M.getNamedValue("objc_autorelease") || + M.getNamedValue("objc_retainAutoreleasedReturnValue") || + M.getNamedValue("objc_retainBlock") || + M.getNamedValue("objc_autoreleaseReturnValue") || + M.getNamedValue("objc_autoreleasePoolPush") || + M.getNamedValue("objc_loadWeakRetained") || + M.getNamedValue("objc_loadWeak") || + M.getNamedValue("objc_destroyWeak") || + M.getNamedValue("objc_storeWeak") || + M.getNamedValue("objc_initWeak") || + M.getNamedValue("objc_moveWeak") || + M.getNamedValue("objc_copyWeak") || + M.getNamedValue("objc_retainedObject") || + M.getNamedValue("objc_unretainedObject") || + M.getNamedValue("objc_unretainedPointer"); +} + //===----------------------------------------------------------------------===// // ARC AliasAnalysis. //===----------------------------------------------------------------------===// @@ -749,8 +773,12 @@ /// ObjCARCExpand - Early ARC transformations. class ObjCARCExpand : public FunctionPass { virtual void getAnalysisUsage(AnalysisUsage &AU) const; + virtual bool doInitialization(Module &M); virtual bool runOnFunction(Function &F); + /// Run - A flag indicating whether this optimization pass should run. + bool Run; + public: static char ID; ObjCARCExpand() : FunctionPass(ID) { @@ -771,10 +799,19 @@ AU.setPreservesCFG(); } +bool ObjCARCExpand::doInitialization(Module &M) { + Run = ModuleHasARC(M); + return false; +} + bool ObjCARCExpand::runOnFunction(Function &F) { if (!EnableARCOpts) return false; + // If nothing in the Module uses ARC, don't do anything. + if (!Run) + return false; + bool Changed = false; for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ++I) { @@ -840,8 +877,9 @@ // usually can't sink them past other calls, which would be the main // case where it would be useful. +/// TODO: The pointer returned from objc_loadWeakRetained is retained. + #include "llvm/GlobalAlias.h" -#include "llvm/Module.h" #include "llvm/Constants.h" #include "llvm/LLVMContext.h" #include "llvm/Support/ErrorHandling.h" @@ -1365,10 +1403,12 @@ bool Changed; ProvenanceAnalysis PA; + /// Run - A flag indicating whether this optimization pass should run. + bool Run; + /// RetainFunc, RelaseFunc - Declarations for objc_retain, /// objc_retainBlock, and objc_release. - Function *RetainFunc, *RetainBlockFunc, *RetainRVFunc, *ReleaseFunc, - *AutoreleaseFunc; + Function *RetainFunc, *RetainBlockFunc, *RetainRVFunc, *ReleaseFunc; /// RetainRVCallee, etc. - Declarations for ObjC runtime /// functions, for use in creating calls to them. These are initialized @@ -3069,6 +3109,10 @@ if (!EnableARCOpts) return false; + Run = ModuleHasARC(M); + if (!Run) + return false; + // Identify the imprecise release metadata kind. ImpreciseReleaseMDKind = M.getContext().getMDKindID("clang.imprecise_release"); @@ -3078,7 +3122,6 @@ RetainBlockFunc = M.getFunction("objc_retainBlock"); RetainRVFunc = M.getFunction("objc_retainAutoreleasedReturnValue"); ReleaseFunc = M.getFunction("objc_release"); - AutoreleaseFunc = M.getFunction("objc_autorelease"); // Intuitively, objc_retain and others are nocapture, however in practice // they are not, because they return their argument value. And objc_release @@ -3098,6 +3141,10 @@ if (!EnableARCOpts) return false; + // If nothing in the Module uses ARC, don't do anything. + if (!Run) + return false; + Changed = false; PA.setAA(&getAnalysis()); @@ -3162,6 +3209,9 @@ DominatorTree *DT; ProvenanceAnalysis PA; + /// Run - A flag indicating whether this optimization pass should run. + bool Run; + /// StoreStrongCallee, etc. - Declarations for ObjC runtime /// functions, for use in creating calls to them. These are initialized /// lazily to avoid cluttering up the Module with unused declarations. @@ -3384,6 +3434,10 @@ } bool ObjCARCContract::doInitialization(Module &M) { + Run = ModuleHasARC(M); + if (!Run) + return false; + // These are initialized lazily. StoreStrongCallee = 0; RetainAutoreleaseCallee = 0; @@ -3407,6 +3461,10 @@ if (!EnableARCOpts) return false; + // If nothing in the Module uses ARC, don't do anything. + if (!Run) + return false; + Changed = false; AA = &getAnalysis(); DT = &getAnalysis(); From kledzik at apple.com Mon Jun 20 18:47:02 2011 From: kledzik at apple.com (Nick Kledzik) Date: Mon, 20 Jun 2011 23:47:02 -0000 Subject: [llvm-commits] [compiler-rt] r133481 - in /compiler-rt/trunk/make: lib_info.mk options.mk Message-ID: <20110620234702.2CF862A6C12C@llvm.org> Author: kledzik Date: Mon Jun 20 18:47:02 2011 New Revision: 133481 URL: http://llvm.org/viewvc/llvm-project?rev=133481&view=rev Log: add STRIP and LIPO as AvailableOptions Modified: compiler-rt/trunk/make/lib_info.mk compiler-rt/trunk/make/options.mk Modified: compiler-rt/trunk/make/lib_info.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/make/lib_info.mk?rev=133481&r1=133480&r2=133481&view=diff ============================================================================== --- compiler-rt/trunk/make/lib_info.mk (original) +++ compiler-rt/trunk/make/lib_info.mk Mon Jun 20 18:47:02 2011 @@ -48,4 +48,5 @@ CC CFLAGS FUNCTIONS OPTIMIZED \ RANLIB RANLIBFLAGS \ VISIBILITY_HIDDEN \ - KERNEL_USE + KERNEL_USE \ + STRIP LIPO Modified: compiler-rt/trunk/make/options.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/make/options.mk?rev=133481&r1=133480&r2=133481&view=diff ============================================================================== --- compiler-rt/trunk/make/options.mk (original) +++ compiler-rt/trunk/make/options.mk Mon Jun 20 18:47:02 2011 @@ -31,3 +31,6 @@ RANLIB := ranlib # FIXME: Remove these pipes once ranlib errors are fixed. RANLIBFLAGS := 2> /dev/null + +STRIP := strip +LIPO := lipo From dpatel at apple.com Mon Jun 20 18:55:02 2011 From: dpatel at apple.com (Devang Patel) Date: Mon, 20 Jun 2011 23:55:02 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r133482 - in /llvm-gcc-4.2/trunk/gcc: c-pch.c llvm-backend.cpp llvm.h testsuite/g++.dg/pch/template-2.C testsuite/g++.dg/pch/template-2.Hs Message-ID: <20110620235502.7B6F82A6C12C@llvm.org> Author: dpatel Date: Mon Jun 20 18:55:02 2011 New Revision: 133482 URL: http://llvm.org/viewvc/llvm-project?rev=133482&view=rev Log: If TypeUsers are lazily read from PCH only when a function is emitted then they may never happen. Read TypeUsers after reading PCH. Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/pch/template-2.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/pch/template-2.Hs Modified: llvm-gcc-4.2/trunk/gcc/c-pch.c llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp llvm-gcc-4.2/trunk/gcc/llvm.h Modified: llvm-gcc-4.2/trunk/gcc/c-pch.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-pch.c?rev=133482&r1=133481&r2=133482&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-pch.c (original) +++ llvm-gcc-4.2/trunk/gcc/c-pch.c Mon Jun 20 18:55:02 2011 @@ -446,6 +446,12 @@ been loaded. */ if (lang_post_pch_load) (*lang_post_pch_load) (); + /* LLVM LOCAL begin */ +#ifdef ENABLE_LLVM + llvm_post_pch_read(); +#endif + /* LLVM LOCAL end */ + } /* Indicate that no more PCH files should be read. */ Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=133482&r1=133481&r2=133482&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Mon Jun 20 18:55:02 2011 @@ -633,6 +633,11 @@ flag_llvm_pch_read = 1; } +// Initialize remainign llvm specific data structures after pch is loaded. +void llvm_post_pch_read() { + readLLVMTypeUsers(); +} + /// llvm_pch_write_init - Initialize PCH writing. void llvm_pch_write_init(void) { timevar_push(TV_LLVM_INIT); @@ -1123,17 +1128,6 @@ return; // Do not process broken code. } - // Initial fill of TypeRefinementDatabase::TypeUsers[] if we're - // using a PCH. Won't work until the GCC PCH has been read in and - // digested. - { - static bool done = false; - if (!done && flag_llvm_pch_read) { - readLLVMTypeUsers(); - done = true; - } - } - timevar_push(TV_LLVM_FUNCS); // Convert the AST to raw/ugly LLVM code. Modified: llvm-gcc-4.2/trunk/gcc/llvm.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm.h?rev=133482&r1=133481&r2=133482&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm.h Mon Jun 20 18:55:02 2011 @@ -103,6 +103,9 @@ /* Read bytecodes from PCH file. */ void llvm_pch_read(const unsigned char *, unsigned); +/* Initialize remainign llvm specific data structures after pch is loaded. */ +void llvm_post_pch_read(void); + /* llvm_asm_file_start - Start the .s file. */ void llvm_asm_file_start(void); Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/pch/template-2.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.dg/pch/template-2.C?rev=133482&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/pch/template-2.C (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/pch/template-2.C Mon Jun 20 18:55:02 2011 @@ -0,0 +1,2 @@ +/* { dg-options "-m32 -I." } */ +#include "template-2.H" Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/pch/template-2.Hs URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.dg/pch/template-2.Hs?rev=133482&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/pch/template-2.Hs (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/pch/template-2.Hs Mon Jun 20 18:55:02 2011 @@ -0,0 +1,34 @@ +/* { dg-options "-m32 -I." } */ + + +namespace ATL +{ + +typedef struct +{ +unsigned int size; +} my_module; + +class CAM1; +__attribute__((weak)) CAM1* _p1 = __null; +class CAM1 : public my_module +{ +}; + +template +class CAM1T : public CAM1 +{ +public : + CAM1T() throw() {} +}; + +class CAM2; +__attribute__((weak)) CAM2* _pModule = __null; +class CAM2 : public CAM1T +{ +public : + CAM2() {} +}; + +} + From cdavis at mymail.mines.edu Mon Jun 20 19:13:25 2011 From: cdavis at mymail.mines.edu (Charles Davis) Date: Mon, 20 Jun 2011 18:13:25 -0600 Subject: [llvm-commits] [llvm] r133452 - in /llvm/trunk: lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/bitcast2.ll test/CodeGen/X86/vec_set-8.ll test/CodeGen/X86/vec_set-9.ll test/CodeGen/X86/vec_set-C.ll test/CodeGen/X86/vec_shuffle-14.ll test/CodeGen/X86/vec_shuffle-17.ll test/MC/X86/x86-64.s test/MC/X86/x86_64-avx-encoding.s In-Reply-To: <20110620183327.3F55D2A6C12C@llvm.org> References: <20110620183327.3F55D2A6C12C@llvm.org> Message-ID: <4DFFE225.5010807@mymail.mines.edu> On 6/20/11 12:33 PM, Nick Lewycky wrote: > Author: nicholas > Date: Mon Jun 20 13:33:26 2011 > New Revision: 133452 > > URL: http://llvm.org/viewvc/llvm-project?rev=133452&view=rev > Log: > Emit movq for 64-bit register to XMM register moves, but continue to accept > movd when assembling. This breaks compiling compiler-rt on Mac OS X like so: /tmp/cc-E8HNBz.s:7:suffix or operands invalid for `movq' clang: error: assembler command failed with exit code 1 (use -v to see invocation) make[5]: *** [.../llvm/build1/tools/clang/runtime/compiler-rt/clang_darwin/cc_kext/x86_64/SubDir.lib/fixdfti.o] Error 1 There are several more errors like that. Xcode 4.0's assembler still has the movq bug. We still have to produce movd on Darwin when not using the integrated assembler. Chip From kledzik at apple.com Mon Jun 20 19:07:55 2011 From: kledzik at apple.com (Nick Kledzik) Date: Tue, 21 Jun 2011 00:07:55 -0000 Subject: [llvm-commits] [compiler-rt] r133487 - in /compiler-rt/trunk/make: AppleBI.mk platform/darwin_bni.mk Message-ID: <20110621000755.DC1D22A6C12C@llvm.org> Author: kledzik Date: Mon Jun 20 19:07:55 2011 New Revision: 133487 URL: http://llvm.org/viewvc/llvm-project?rev=133487&view=rev Log: clean up darwin platform to use xcrun. Set up variables in darwin_bni.mk. Use GetCNAVar in AppleBI.mk Modified: compiler-rt/trunk/make/AppleBI.mk compiler-rt/trunk/make/platform/darwin_bni.mk Modified: compiler-rt/trunk/make/AppleBI.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/make/AppleBI.mk?rev=133487&r1=133486&r2=133487&view=diff ============================================================================== --- compiler-rt/trunk/make/AppleBI.mk (original) +++ compiler-rt/trunk/make/AppleBI.mk Mon Jun 20 19:07:55 2011 @@ -14,17 +14,12 @@ ifeq (,$(SDKROOT)) INSTALL_TARGET = install-MacOSX - LD_OTHER_FLAGS = else INSTALL_TARGET = install-iOS - CFLAGS.Release.armv6 := $(CFLAGS) -Wall -Os -fomit-frame-pointer -g -isysroot $(SDKROOT) - CFLAGS.Release.armv7 := $(CFLAGS) -Wall -Os -fomit-frame-pointer -g -isysroot $(SDKROOT) - CFLAGS.Static.armv6 := $(CFLAGS) -Wall -Os -fomit-frame-pointer -g -isysroot $(SDKROOT) -static - CFLAGS.Static.armv7 := $(CFLAGS) -Wall -Os -fomit-frame-pointer -g -isysroot $(SDKROOT) -static - LD_OTHER_FLAGS = -Wl,-alias_list,$(SRCROOT)/lib/arm/softfloat-alias.list -isysroot $(SDKROOT) endif + # Log full compile lines in B&I logs and omit summary lines. Verb := Summary := @true @@ -49,7 +44,7 @@ cp $(SYMROOT)/libcompiler_rt-dyld.a \ $(DSTROOT)/usr/local/lib/dyld/libcompiler_rt.a mkdir -p $(DSTROOT)/usr/lib/system - strip -S $(SYMROOT)/libcompiler_rt.dylib \ + $(call GetCNAVar,STRIP,Platform.darwin_bni,Release,) -S $(SYMROOT)/libcompiler_rt.dylib \ -o $(DSTROOT)/usr/lib/system/libcompiler_rt.dylib cd $(DSTROOT)/usr/lib/system; \ ln -s libcompiler_rt.dylib libcompiler_rt_profile.dylib; \ @@ -58,16 +53,17 @@ # Rule to make each dylib slice $(OBJROOT)/libcompiler_rt-%.dylib : $(OBJROOT)/darwin_bni/Release/%/libcompiler_rt.a echo "const char vers[] = \"@(#) $(RC_ProjectName)-$(RC_ProjectSourceVersion)\"; " > $(OBJROOT)/version.c - $(CC.Release) $(OBJROOT)/version.c -arch $* -dynamiclib \ + $(call GetCNAVar,CC,Platform.darwin_bni,Release,$*) \ + $(OBJROOT)/version.c -arch $* -dynamiclib \ -install_name /usr/lib/system/libcompiler_rt.dylib \ -compatibility_version 1 -current_version $(RC_ProjectSourceVersion) \ -nodefaultlibs -lSystem -umbrella System -dead_strip \ - $(LD_OTHER_FLAGS) -Wl,-force_load,$^ -o $@ + $(DYLIB_FLAGS) -Wl,-force_load,$^ -o $@ # Rule to make fat dylib $(SYMROOT)/libcompiler_rt.dylib: $(foreach arch,$(RC_ARCHS), \ $(OBJROOT)/libcompiler_rt-$(arch).dylib) - lipo -create $^ -o $@ + $(call GetCNAVar,LIPO,Platform.darwin_bni,Release,) -create $^ -o $@ @@ -83,25 +79,27 @@ cp $(SYMROOT)/libcompiler_rt-dyld.a \ $(DSTROOT)/usr/local/lib/dyld/libcompiler_rt.a mkdir -p $(DSTROOT)/usr/lib/system - strip -S $(SYMROOT)/libcompiler_rt.dylib \ + $(call GetCNAVar,STRIP,Platform.darwin_bni,Release,) -S $(SYMROOT)/libcompiler_rt.dylib \ -o $(DSTROOT)/usr/lib/system/libcompiler_rt.dylib # Rule to make fat archive $(SYMROOT)/libcompiler_rt-static.a : $(foreach arch,$(RC_ARCHS), \ $(OBJROOT)/darwin_bni/Static/$(arch)/libcompiler_rt.a) - lipo -create $^ -o $@ + $(call GetCNAVar,LIPO,Platform.darwin_bni,Release,) -create $^ -o $@ -# rule to make each archive slice for dyld +# rule to make each archive slice for dyld (which removes a few archive members) $(OBJROOT)/libcompiler_rt-dyld-%.a : $(OBJROOT)/darwin_bni/Release/%/libcompiler_rt.a cp $^ $@ - ar -d $@ apple_versioning.o - ar -d $@ gcc_personality_v0.o - ar -d $@ eprintf.o - ranlib $@ + DEL_LIST=`$(AR) -t $@ | egrep 'apple_versioning|gcc_personality_v0|eprintf' | xargs echo` ; \ + if [ -n "$${DEL_LIST}" ] ; \ + then \ + $(call GetCNAVar,AR,Platform.darwin_bni,Release,) -d $@ $${DEL_LIST}; \ + $(call GetCNAVar,RANLIB,Platform.darwin_bni,Release,) $@ ; \ + fi # rule to make make archive for dyld $(SYMROOT)/libcompiler_rt-dyld.a : $(foreach arch,$(RC_ARCHS), \ $(OBJROOT)/libcompiler_rt-dyld-$(arch).a) - lipo -create $^ -o $@ + $(call GetCNAVar,LIPO,Platform.darwin_bni,Release,) -create $^ -o $@ Modified: compiler-rt/trunk/make/platform/darwin_bni.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/make/platform/darwin_bni.mk?rev=133487&r1=133486&r2=133487&view=diff ============================================================================== --- compiler-rt/trunk/make/platform/darwin_bni.mk (original) +++ compiler-rt/trunk/make/platform/darwin_bni.mk Mon Jun 20 19:07:55 2011 @@ -8,17 +8,30 @@ # and the resulting lib will just have generic versions for anything unknown. UniversalArchs := $(RC_ARCHS) -ifeq (,$(SDKROOT)) - CC.Release := $(CC) - CC.Static := $(CC) +ifneq (,$(SDKROOT)) + override CC := $(shell xcrun -sdk $(SDKROOT) -find clang) + AR := $(shell xcrun -sdk $(SDKROOT) -find ar) + RANLIB := $(shell xcrun -sdk $(SDKROOT) -find ranlib) + STRIP := $(shell xcrun -sdk $(SDKROOT) -find strip) + LIPO := $(shell xcrun -sdk $(SDKROOT) -find lipo) +endif + +ifneq ($(IPHONEOS_DEPLOYMENT_TARGET),) + DEPLOYMENT_FLAGS := -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET) else - CC.Release := /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/cc - CC.Static := /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/cc + ifneq ($(MACOSX_DEPLOYMENT_TARGET),) + DEPLOYMENT_FLAGS := -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) + endif endif +ifneq (,$(SDKROOT)) + DEPLOYMENT_FLAGS += -isysroot $(SDKROOT) +endif -CFLAGS := -Wall -Os -fomit-frame-pointer -g -CFLAGS.Static := $(CFLAGS) -static +CFLAGS := -Wall -Os -fomit-frame-pointer -g $(DEPLOYMENT_FLAGS) +CFLAGS.Static := $(CFLAGS) -static +DYLIB_FLAGS := $(DEPLOYMENT_FLAGS) \ + -Xarch_arm -Wl,-alias_list,$(SRCROOT)/lib/arm/softfloat-alias.list VISIBILITY_HIDDEN := 0 VISIBILITY_HIDDEN.Static := 1 From isanbard at gmail.com Mon Jun 20 19:35:15 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 21 Jun 2011 00:35:15 -0000 Subject: [llvm-commits] [llvm] r133493 - /llvm/trunk/include/llvm/Intrinsics.td Message-ID: <20110621003515.8595E2A6C12C@llvm.org> Author: void Date: Mon Jun 20 19:35:15 2011 New Revision: 133493 URL: http://llvm.org/viewvc/llvm-project?rev=133493&view=rev Log: Don't mark the eh.dispatch.setup with a memory access marker. We want this to stick around even during fast isel. Modified: llvm/trunk/include/llvm/Intrinsics.td Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=133493&r1=133492&r2=133493&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Mon Jun 20 19:35:15 2011 @@ -312,7 +312,7 @@ def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>; } -def int_eh_sjlj_dispatch_setup : Intrinsic<[], [llvm_i32_ty], [IntrReadMem]>; +def int_eh_sjlj_dispatch_setup : Intrinsic<[], [llvm_i32_ty]>; def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>; From ahatanak at gmail.com Mon Jun 20 19:40:49 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Tue, 21 Jun 2011 00:40:49 -0000 Subject: [llvm-commits] [llvm] r133494 - in /llvm/trunk: lib/Target/Mips/MipsAsmPrinter.cpp lib/Target/Mips/MipsISelDAGToDAG.cpp lib/Target/Mips/MipsISelLowering.cpp lib/Target/Mips/MipsISelLowering.h lib/Target/Mips/MipsInstrInfo.td lib/Target/Mips/MipsMachineFunction.h lib/Target/Mips/MipsRegisterInfo.cpp test/CodeGen/Mips/alloca.ll test/CodeGen/Mips/inlineasmmemop.ll Message-ID: <20110621004049.779FE2A6C12D@llvm.org> Author: ahatanak Date: Mon Jun 20 19:40:49 2011 New Revision: 133494 URL: http://llvm.org/viewvc/llvm-project?rev=133494&view=rev Log: Re-apply 132758 and 132768 which were speculatively reverted in 132777. Added: llvm/trunk/test/CodeGen/Mips/inlineasmmemop.ll Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.h llvm/trunk/lib/Target/Mips/MipsInstrInfo.td llvm/trunk/lib/Target/Mips/MipsMachineFunction.h llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp llvm/trunk/test/CodeGen/Mips/alloca.ll Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=133494&r1=133493&r2=133494&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Mon Jun 20 19:40:49 2011 @@ -56,6 +56,9 @@ bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &O); + bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O); void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O); void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, @@ -304,6 +307,19 @@ return false; } +bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, + unsigned OpNum, unsigned AsmVariant, + const char *ExtraCode, + raw_ostream &O) { + if (ExtraCode && ExtraCode[0]) + return true; // Unknown modifier. + + const MachineOperand &MO = MI->getOperand(OpNum); + assert(MO.isReg() && "unexpected inline asm memory operand"); + O << "0($" << MipsAsmPrinter::getRegisterName(MO.getReg()) << ")"; + return false; +} + void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum, raw_ostream &O) { const MachineOperand &MO = MI->getOperand(opNum); Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=133494&r1=133493&r2=133494&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Mon Jun 20 19:40:49 2011 @@ -94,6 +94,10 @@ inline SDValue getI32Imm(unsigned Imm) { return CurDAG->getTargetConstant(Imm, MVT::i32); } + + virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, + char ConstraintCode, + std::vector &OutOps); }; } @@ -462,6 +466,14 @@ return ResNode; } +bool MipsDAGToDAGISel:: +SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, + std::vector &OutOps) { + assert(ConstraintCode == 'm' && "unexpected asm memory constraint"); + OutOps.push_back(Op); + return false; +} + /// createMipsISelDag - This pass converts a legalized DAG into a /// MIPS-specific DAG, ready for instruction scheduling. FunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) { Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=133494&r1=133493&r2=133494&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon Jun 20 19:40:49 2011 @@ -59,6 +59,7 @@ case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64"; case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64"; case MipsISD::WrapperPIC: return "MipsISD::WrapperPIC"; + case MipsISD::DynAlloc: return "MipsISD::DynAlloc"; default: return NULL; } } @@ -1189,9 +1190,10 @@ SDValue MipsTargetLowering:: LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const { - unsigned StackAlignment = - getTargetMachine().getFrameLowering()->getStackAlignment(); - assert(StackAlignment >= + MachineFunction &MF = DAG.getMachineFunction(); + MipsFunctionInfo *MipsFI = MF.getInfo(); + + assert(getTargetMachine().getFrameLowering()->getStackAlignment() >= cast(Op.getOperand(2).getNode())->getZExtValue() && "Cannot lower if the alignment of the allocated space is larger than \ that of the stack."); @@ -1211,24 +1213,14 @@ // must be placed in the stack pointer register. Chain = DAG.getCopyToReg(StackPointer.getValue(1), dl, Mips::SP, Sub, SDValue()); - // Retrieve updated $sp. There is a glue input to prevent instructions that - // clobber $sp from being inserted between copytoreg and copyfromreg. - SDValue NewSP = DAG.getCopyFromReg(Chain, dl, Mips::SP, MVT::i32, - Chain.getValue(1)); - - // The stack space reserved by alloca is located right above the argument - // area. It is aligned on a boundary that is a multiple of StackAlignment. - MachineFunction &MF = DAG.getMachineFunction(); - MipsFunctionInfo *MipsFI = MF.getInfo(); - unsigned SPOffset = (MipsFI->getMaxCallFrameSize() + StackAlignment - 1) / - StackAlignment * StackAlignment; - SDValue AllocPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, NewSP, - DAG.getConstant(SPOffset, MVT::i32)); // This node always has two return values: a new stack pointer // value and a chain - SDValue Ops[2] = { AllocPtr, NewSP.getValue(1) }; - return DAG.getMergeValues(Ops, 2, dl); + SDVTList VTLs = DAG.getVTList(MVT::i32, MVT::Other); + SDValue Ptr = DAG.getFrameIndex(MipsFI->getDynAllocFI(), getPointerTy()); + SDValue Ops[] = { Chain, Ptr, Chain.getValue(1) }; + + return DAG.getNode(MipsISD::DynAlloc, dl, VTLs, Ops, 3); } SDValue MipsTargetLowering:: @@ -1770,6 +1762,10 @@ if (IsPIC && !MipsFI->getGPFI()) MipsFI->setGPFI(MFI->CreateFixedObject(4, 0, true)); + // Get the frame index of the stack frame object that points to the location + // of dynamically allocated area on the stack. + int DynAllocFI = MipsFI->getDynAllocFI(); + // Update size of the maximum argument space. // For O32, a minimum of four words (16 bytes) of argument space is // allocated. @@ -1781,14 +1777,17 @@ if (MaxCallFrameSize < NextStackOffset) { MipsFI->setMaxCallFrameSize(NextStackOffset); - if (IsPIC) { - // $gp restore slot must be aligned. - unsigned StackAlignment = TFL->getStackAlignment(); - NextStackOffset = (NextStackOffset + StackAlignment - 1) / - StackAlignment * StackAlignment; - int GPFI = MipsFI->getGPFI(); - MFI->setObjectOffset(GPFI, NextStackOffset); - } + // Set the offsets relative to $sp of the $gp restore slot and dynamically + // allocated stack space. These offsets must be aligned to a boundary + // determined by the stack alignment of the ABI. + unsigned StackAlignment = TFL->getStackAlignment(); + NextStackOffset = (NextStackOffset + StackAlignment - 1) / + StackAlignment * StackAlignment; + + if (IsPIC) + MFI->setObjectOffset(MipsFI->getGPFI(), NextStackOffset); + + MFI->setObjectOffset(DynAllocFI, NextStackOffset); } // With EABI is it possible to have 16 args on registers. Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=133494&r1=133493&r2=133494&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Mon Jun 20 19:40:49 2011 @@ -79,7 +79,9 @@ BuildPairF64, ExtractElementF64, - WrapperPIC + WrapperPIC, + + DynAlloc }; } Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=133494&r1=133493&r2=133494&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Mon Jun 20 19:40:49 2011 @@ -39,6 +39,9 @@ def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; +def SDT_MipsDynAlloc : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, + SDTCisVT<1, iPTR>]>; + // Call def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, @@ -99,6 +102,10 @@ def MipsWrapperPIC : SDNode<"MipsISD::WrapperPIC", SDTIntUnaryOp>; +// Pointer to dynamically allocated stack area. +def MipsDynAlloc : SDNode<"MipsISD::DynAlloc", SDT_MipsDynAlloc, + [SDNPHasChain, SDNPInGlue]>; + //===----------------------------------------------------------------------===// // Mips Instruction Predicate Definitions. //===----------------------------------------------------------------------===// @@ -675,6 +682,12 @@ // can be matched. It's similar to Sparc LEA_ADDRi def LEA_ADDiu : EffectiveAddress<"addiu\t$dst, ${addr:stackloc}">; +// DynAlloc node points to dynamically allocated stack space. +// $sp is added to the list of implicitly used registers to prevent dead code +// elimination from removing instructions that modify $sp. +let Uses = [SP] in +def DynAlloc : EffectiveAddress<"addiu\t$dst, ${addr:stackloc}">; + // MADD*/MSUB* def MADD : MArithR<0, "madd", MipsMAdd, 1>; def MADDU : MArithR<1, "maddu", MipsMAddu, 1>; @@ -852,6 +865,9 @@ def : Pat<(setuge CPURegs:$lhs, immSExt16:$rhs), (XORi (SLTiu CPURegs:$lhs, immSExt16:$rhs), 1)>; +// select MipsDynAlloc +def : Pat<(MipsDynAlloc addr:$f), (DynAlloc addr:$f)>; + //===----------------------------------------------------------------------===// // Floating Point Support //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/Mips/MipsMachineFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsMachineFunction.h?rev=133494&r1=133493&r2=133494&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsMachineFunction.h (original) +++ llvm/trunk/lib/Target/Mips/MipsMachineFunction.h Mon Jun 20 19:40:49 2011 @@ -27,6 +27,7 @@ class MipsFunctionInfo : public MachineFunctionInfo { private: + MachineFunction& MF; /// SRetReturnReg - Some subtargets require that sret lowering includes /// returning the value of the returned struct in a register. This field /// holds the virtual register into which the sret argument is passed. @@ -47,6 +48,7 @@ // LowerCall except for the frame object for restoring $gp. std::pair InArgFIRange, OutArgFIRange; int GPFI; // Index of the frame object for restoring $gp + mutable int DynAllocFI; // Frame index of dynamically allocated stack area. unsigned MaxCallFrameSize; /// AtomicFrameIndex - To implement atomic.swap and atomic.cmp.swap @@ -55,10 +57,10 @@ int AtomicFrameIndex; public: MipsFunctionInfo(MachineFunction& MF) - : SRetReturnReg(0), GlobalBaseReg(0), + : MF(MF), SRetReturnReg(0), GlobalBaseReg(0), VarArgsFrameIndex(0), InArgFIRange(std::make_pair(-1, 0)), - OutArgFIRange(std::make_pair(-1, 0)), GPFI(0), MaxCallFrameSize(0), - AtomicFrameIndex(-1) + OutArgFIRange(std::make_pair(-1, 0)), GPFI(0), DynAllocFI(0), + MaxCallFrameSize(0), AtomicFrameIndex(-1) {} bool isInArgFI(int FI) const { @@ -81,6 +83,16 @@ bool needGPSaveRestore() const { return getGPFI(); } bool isGPFI(int FI) const { return GPFI && GPFI == FI; } + // The first call to this function creates a frame object for dynamically + // allocated stack area. + int getDynAllocFI() const { + if (!DynAllocFI) + DynAllocFI = MF.getFrameInfo()->CreateFixedObject(4, 0, true); + + return DynAllocFI; + } + bool isDynAllocFI(int FI) const { return DynAllocFI && DynAllocFI == FI; } + unsigned getSRetReturnReg() const { return SRetReturnReg; } void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; } Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp?rev=133494&r1=133493&r2=133494&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp Mon Jun 20 19:40:49 2011 @@ -179,12 +179,14 @@ int Offset; // Calculate final offset. - // - There is no need to change the offset if the frame object is an outgoing - // argument or a $gp restore location, + // - There is no need to change the offset if the frame object is one of the + // following: an outgoing argument, pointer to a dynamically allocated + // stack space or a $gp restore location, // - If the frame object is any of the following, its offset must be adjusted // by adding the size of the stack: // incoming argument, callee-saved register location or local variable. - if (MipsFI->isOutArgFI(FrameIndex) || MipsFI->isGPFI(FrameIndex)) + if (MipsFI->isOutArgFI(FrameIndex) || MipsFI->isGPFI(FrameIndex) || + MipsFI->isDynAllocFI(FrameIndex)) Offset = spOffset; else Offset = spOffset + stackSize; @@ -213,7 +215,7 @@ // 3. Locations for callee-saved registers. // Everything else is referenced relative to whatever register // getFrameRegister() returns. - if (MipsFI->isOutArgFI(FrameIndex) || + if (MipsFI->isOutArgFI(FrameIndex) || MipsFI->isDynAllocFI(FrameIndex) || (FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI)) FrameReg = Mips::SP; else Modified: llvm/trunk/test/CodeGen/Mips/alloca.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/alloca.ll?rev=133494&r1=133493&r2=133494&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Mips/alloca.ll (original) +++ llvm/trunk/test/CodeGen/Mips/alloca.ll Mon Jun 20 19:40:49 2011 @@ -4,15 +4,15 @@ entry: ; CHECK: subu $[[T0:[0-9]+]], $sp, $[[SZ:[0-9]+]] ; CHECK: addu $sp, $zero, $[[T0]] -; CHECK: addu $[[SP1:[0-9]+]], $zero, $sp -; CHECK: subu $[[T1:[0-9]+]], $sp, $[[SZ]] -; CHECK: addu $sp, $zero, $[[T1]] -; CHECK: addu $[[SP2:[0-9]+]], $zero, $sp +; CHECK: addiu $[[T1:[0-9]+]], $sp, [[OFF:[0-9]+]] +; CHECK: subu $[[T2:[0-9]+]], $sp, $[[SZ]] +; CHECK: addu $sp, $zero, $[[T2]] +; CHECK: addiu $[[T3:[0-9]+]], $sp, [[OFF]] ; CHECK: lw $25, %call16(foo)($gp) -; CHECK: addiu $4, $[[SP1]], 24 +; CHECK: addu $4, $zero, $[[T1]] ; CHECK: jalr $25 ; CHECK: lw $25, %call16(foo)($gp) -; CHECK: addiu $4, $[[SP2]], 24 +; CHECK: addu $4, $zero, $[[T3]] ; CHECK: jalr $25 %tmp1 = alloca i8, i32 %size, align 4 %add.ptr = getelementptr inbounds i8* %tmp1, i32 5 @@ -29,3 +29,72 @@ declare i32 @foo(i8*) + at .str = private unnamed_addr constant [22 x i8] c"%d %d %d %d %d %d %d\0A\00", align 1 + +define i32 @alloca2(i32 %size) nounwind { +entry: +; dynamic allocated stack area and $gp restore slot have the same offsets +; relative to $sp. +; +; CHECK: alloca2 +; CHECK: .cprestore [[OFF:[0-9]+]] +; CHECK: subu $[[T0:[0-9]+]], $sp, $[[SZ:[0-9]+]] +; CHECK: addu $sp, $zero, $[[T0]] +; CHECK: addiu $[[T1:[0-9]+]], $sp, [[OFF]] + + %tmp1 = alloca i8, i32 %size, align 4 + %0 = bitcast i8* %tmp1 to i32* + %cmp = icmp sgt i32 %size, 10 + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry +; CHECK: addiu $4, $[[T1]], 40 + + %add.ptr = getelementptr inbounds i8* %tmp1, i32 40 + %1 = bitcast i8* %add.ptr to i32* + call void @foo3(i32* %1) nounwind + %arrayidx15.pre = getelementptr inbounds i8* %tmp1, i32 12 + %.pre = bitcast i8* %arrayidx15.pre to i32* + br label %if.end + +if.else: ; preds = %entry +; CHECK: addiu $4, $[[T1]], 12 + + %add.ptr5 = getelementptr inbounds i8* %tmp1, i32 12 + %2 = bitcast i8* %add.ptr5 to i32* + call void @foo3(i32* %2) nounwind + br label %if.end + +if.end: ; preds = %if.else, %if.then +; CHECK: lw $5, 0($[[T1]]) +; CHECK: lw $25, %call16(printf) + + %.pre-phi = phi i32* [ %2, %if.else ], [ %.pre, %if.then ] + %tmp7 = load i32* %0, align 4, !tbaa !0 + %arrayidx9 = getelementptr inbounds i8* %tmp1, i32 4 + %3 = bitcast i8* %arrayidx9 to i32* + %tmp10 = load i32* %3, align 4, !tbaa !0 + %arrayidx12 = getelementptr inbounds i8* %tmp1, i32 8 + %4 = bitcast i8* %arrayidx12 to i32* + %tmp13 = load i32* %4, align 4, !tbaa !0 + %tmp16 = load i32* %.pre-phi, align 4, !tbaa !0 + %arrayidx18 = getelementptr inbounds i8* %tmp1, i32 16 + %5 = bitcast i8* %arrayidx18 to i32* + %tmp19 = load i32* %5, align 4, !tbaa !0 + %arrayidx21 = getelementptr inbounds i8* %tmp1, i32 20 + %6 = bitcast i8* %arrayidx21 to i32* + %tmp22 = load i32* %6, align 4, !tbaa !0 + %arrayidx24 = getelementptr inbounds i8* %tmp1, i32 24 + %7 = bitcast i8* %arrayidx24 to i32* + %tmp25 = load i32* %7, align 4, !tbaa !0 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([22 x i8]* @.str, i32 0, i32 0), i32 %tmp7, i32 %tmp10, i32 %tmp13, i32 %tmp16, i32 %tmp19, i32 %tmp22, i32 %tmp25) nounwind + ret i32 0 +} + +declare void @foo3(i32*) + +declare i32 @printf(i8* nocapture, ...) nounwind + +!0 = metadata !{metadata !"int", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA", null} Added: llvm/trunk/test/CodeGen/Mips/inlineasmmemop.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/inlineasmmemop.ll?rev=133494&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/Mips/inlineasmmemop.ll (added) +++ llvm/trunk/test/CodeGen/Mips/inlineasmmemop.ll Mon Jun 20 19:40:49 2011 @@ -0,0 +1,23 @@ +; RUN: llc -march=mipsel -mcpu=4ke < %s | FileCheck %s + + at g1 = external global i32 + +define i32 @f1(i32 %x) nounwind { +entry: +; CHECK: addiu $[[T0:[0-9]+]], $sp +; CHECK: #APP +; CHECK: sw $4, 0($[[T0]]) +; CHECK: #NO_APP +; CHECK: lw $[[T1:[0-9]+]], %got(g1)($gp) +; CHECK: #APP +; CHECK: lw $[[T3:[0-9]+]], 0($[[T0]]) +; CHECK: #NO_APP +; CHECK: sw $[[T3]], 0($[[T1]]) + + %l1 = alloca i32, align 4 + call void asm "sw $1, $0", "=*m,r"(i32* %l1, i32 %x) nounwind + %0 = call i32 asm "lw $0, $1", "=r,*m"(i32* %l1) nounwind + store i32 %0, i32* @g1, align 4 + ret i32 %0 +} + From ahatanak at gmail.com Mon Jun 20 20:02:03 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Tue, 21 Jun 2011 01:02:03 -0000 Subject: [llvm-commits] [llvm] r133496 - /llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Message-ID: <20110621010203.65FFC2A6C12C@llvm.org> Author: ahatanak Date: Mon Jun 20 20:02:03 2011 New Revision: 133496 URL: http://llvm.org/viewvc/llvm-project?rev=133496&view=rev Log: Coding style fixes. 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=133496&r1=133495&r2=133496&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon Jun 20 20:02:03 2011 @@ -1350,7 +1350,7 @@ if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { // General Dynamic TLS Model SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, - 0, MipsII::MO_TLSGD); + 0, MipsII::MO_TLSGD); SDValue Tlsgd = DAG.getNode(MipsISD::TlsGd, dl, MVT::i32, TGA); SDValue GP = DAG.getRegister(Mips::GP, MVT::i32); SDValue Argument = DAG.getNode(ISD::ADD, dl, MVT::i32, GP, Tlsgd); @@ -1362,36 +1362,36 @@ Args.push_back(Entry); std::pair CallResult = LowerCallTo(DAG.getEntryNode(), - (const Type *) Type::getInt32Ty(*DAG.getContext()), - false, false, false, false, - 0, CallingConv::C, false, true, - DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, dl); + (const Type *) Type::getInt32Ty(*DAG.getContext()), + false, false, false, false, 0, CallingConv::C, false, true, + DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, + dl); return CallResult.first; - } else { - SDValue Offset; - if (GV->isDeclaration()) { - // Initial Exec TLS Model - SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, - MipsII::MO_GOTTPREL); - Offset = DAG.getLoad(MVT::i32, dl, - DAG.getEntryNode(), TGA, MachinePointerInfo(), - false, false, 0); - } else { - // Local Exec TLS Model - SDVTList VTs = DAG.getVTList(MVT::i32); - SDValue TGAHi = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, - MipsII::MO_TPREL_HI); - SDValue TGALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, - MipsII::MO_TPREL_LO); - SDValue Hi = DAG.getNode(MipsISD::TprelHi, dl, VTs, &TGAHi, 1); - SDValue Lo = DAG.getNode(MipsISD::TprelLo, dl, MVT::i32, TGALo); - Offset = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, Lo); - } + } - SDValue ThreadPointer = DAG.getNode(MipsISD::ThreadPointer, dl, PtrVT); - return DAG.getNode(ISD::ADD, dl, PtrVT, ThreadPointer, Offset); + SDValue Offset; + if (GV->isDeclaration()) { + // Initial Exec TLS Model + SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_GOTTPREL); + Offset = DAG.getLoad(MVT::i32, dl, + DAG.getEntryNode(), TGA, MachinePointerInfo(), + false, false, 0); + } else { + // Local Exec TLS Model + SDVTList VTs = DAG.getVTList(MVT::i32); + SDValue TGAHi = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_TPREL_HI); + SDValue TGALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_TPREL_LO); + SDValue Hi = DAG.getNode(MipsISD::TprelHi, dl, VTs, &TGAHi, 1); + SDValue Lo = DAG.getNode(MipsISD::TprelLo, dl, MVT::i32, TGALo); + Offset = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, Lo); } + + SDValue ThreadPointer = DAG.getNode(MipsISD::ThreadPointer, dl, PtrVT); + return DAG.getNode(ISD::ADD, dl, PtrVT, ThreadPointer, Offset); } SDValue MipsTargetLowering:: @@ -1964,7 +1964,8 @@ InFlag = Chain.getValue(1); // Create the CALLSEQ_END node. - Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NextStackOffset, true), + Chain = DAG.getCALLSEQ_END(Chain, + DAG.getIntPtrConstant(NextStackOffset, true), DAG.getIntPtrConstant(0, true), InFlag); InFlag = Chain.getValue(1); From ahatanak at gmail.com Mon Jun 20 20:28:11 2011 From: ahatanak at gmail.com (Akira Hatanaka) Date: Tue, 21 Jun 2011 01:28:11 -0000 Subject: [llvm-commits] [llvm] r133497 - /llvm/trunk/lib/Target/Mips/MipsCallingConv.td Message-ID: <20110621012811.D62702A6C12C@llvm.org> Author: ahatanak Date: Mon Jun 20 20:28:11 2011 New Revision: 133497 URL: http://llvm.org/viewvc/llvm-project?rev=133497&view=rev Log: Add A0 and A1 to the list of registers used for returning a value in order to handle functions with return type Complex long long. Modified: llvm/trunk/lib/Target/Mips/MipsCallingConv.td Modified: llvm/trunk/lib/Target/Mips/MipsCallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsCallingConv.td?rev=133497&r1=133496&r2=133497&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsCallingConv.td (original) +++ llvm/trunk/lib/Target/Mips/MipsCallingConv.td Mon Jun 20 20:28:11 2011 @@ -20,8 +20,8 @@ // Only the return rules are defined here for O32. The rules for argument // passing are defined in MipsISelLowering.cpp. def RetCC_MipsO32 : CallingConv<[ - // i32 are returned in registers V0, V1 - CCIfType<[i32], CCAssignToReg<[V0, V1]>>, + // i32 are returned in registers V0, V1, A0, A1 + CCIfType<[i32], CCAssignToReg<[V0, V1, A0, A1]>>, // f32 are returned in registers F0, F2 CCIfType<[f32], CCAssignToReg<[F0, F2]>>, From mcrosier at apple.com Mon Jun 20 21:09:04 2011 From: mcrosier at apple.com (Chad Rosier) Date: Tue, 21 Jun 2011 02:09:04 -0000 Subject: [llvm-commits] [llvm] r133499 - in /llvm/trunk: include/llvm/ include/llvm/Support/ lib/Target/CppBackend/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ Message-ID: <20110621020904.4CFD62A6C12C@llvm.org> Author: mcrosier Date: Mon Jun 20 21:09:03 2011 New Revision: 133499 URL: http://llvm.org/viewvc/llvm-project?rev=133499&view=rev Log: Revert r133435 and r133449 to appease buildbots. Modified: llvm/trunk/include/llvm/BasicBlock.h llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/Support/CFG.h llvm/trunk/include/llvm/Use.h llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp llvm/trunk/lib/VMCore/BasicBlock.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/lib/VMCore/User.cpp llvm/trunk/lib/VMCore/Value.cpp llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/include/llvm/BasicBlock.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BasicBlock.h?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/include/llvm/BasicBlock.h (original) +++ llvm/trunk/include/llvm/BasicBlock.h Mon Jun 20 21:09:03 2011 @@ -110,7 +110,7 @@ Function *getParent() { return Parent; } /// use_back - Specialize the methods defined in Value, as we know that an - /// BasicBlock can only be used by Users (specifically terminators + /// BasicBlock can only be used by Users (specifically PHI nodes, terminators, /// and BlockAddress's). User *use_back() { return cast(*use_begin());} const User *use_back() const { return cast(*use_begin());} @@ -248,10 +248,6 @@ /// other than direct branches, switches, etc. to it. bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; } - /// replaceSuccessorsPhiUsesWith - Update all phi nodes in all our successors - /// to refer to basic block New instead of to us. - void replaceSuccessorsPhiUsesWith(BasicBlock *New); - private: /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress /// objects using it. This is almost always 0, sometimes one, possibly but Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Mon Jun 20 21:09:03 2011 @@ -1814,7 +1814,7 @@ explicit PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr = "", Instruction *InsertBefore = 0) : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), - ReservedSpace(NumReservedValues) { + ReservedSpace(NumReservedValues * 2) { setName(NameStr); OperandList = allocHungoffUses(ReservedSpace); } @@ -1822,16 +1822,11 @@ PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), - ReservedSpace(NumReservedValues) { + ReservedSpace(NumReservedValues * 2) { setName(NameStr); OperandList = allocHungoffUses(ReservedSpace); } protected: - // allocHungoffUses - this is more complicated than the generic - // User::allocHungoffUses, because we have to allocate Uses for the incoming - // values and pointers to the incoming blocks, all in one allocation. - Use *allocHungoffUses(unsigned) const; - virtual PHINode *clone_impl() const; public: /// Constructors - NumReservedValues is a hint for the number of incoming @@ -1850,55 +1845,32 @@ /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - // Block iterator interface. This provides access to the list of incoming - // basic blocks, which parallels the list of incoming values. - - typedef BasicBlock **block_iterator; - typedef BasicBlock * const *const_block_iterator; - - block_iterator block_begin() { - Use::UserRef *ref = - reinterpret_cast(op_begin() + ReservedSpace); - return reinterpret_cast(ref + 1); - } - - const_block_iterator block_begin() const { - const Use::UserRef *ref = - reinterpret_cast(op_begin() + ReservedSpace); - return reinterpret_cast(ref + 1); - } - - block_iterator block_end() { - return block_begin() + getNumOperands(); - } - - const_block_iterator block_end() const { - return block_begin() + getNumOperands(); - } - /// getNumIncomingValues - Return the number of incoming edges /// - unsigned getNumIncomingValues() const { return getNumOperands(); } + unsigned getNumIncomingValues() const { return getNumOperands()/2; } /// getIncomingValue - Return incoming value number x /// Value *getIncomingValue(unsigned i) const { - return getOperand(i); + assert(i*2 < getNumOperands() && "Invalid value number!"); + return getOperand(i*2); } void setIncomingValue(unsigned i, Value *V) { - setOperand(i, V); + assert(i*2 < getNumOperands() && "Invalid value number!"); + setOperand(i*2, V); } static unsigned getOperandNumForIncomingValue(unsigned i) { - return i; + return i*2; } static unsigned getIncomingValueNumForOperand(unsigned i) { - return i; + assert(i % 2 == 0 && "Invalid incoming-value operand index!"); + return i/2; } /// getIncomingBlock - Return incoming basic block number @p i. /// BasicBlock *getIncomingBlock(unsigned i) const { - return block_begin()[i]; + return cast(getOperand(i*2+1)); } /// getIncomingBlock - Return incoming basic block corresponding @@ -1906,7 +1878,7 @@ /// BasicBlock *getIncomingBlock(const Use &U) const { assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?"); - return getIncomingBlock(&U - op_begin()); + return cast((&U + 1)->get()); } /// getIncomingBlock - Return incoming basic block corresponding @@ -1917,8 +1889,16 @@ return getIncomingBlock(I.getUse()); } + void setIncomingBlock(unsigned i, BasicBlock *BB) { - block_begin()[i] = BB; + setOperand(i*2+1, (Value*)BB); + } + static unsigned getOperandNumForIncomingBlock(unsigned i) { + return i*2+1; + } + static unsigned getIncomingBlockNumForOperand(unsigned i) { + assert(i % 2 == 1 && "Invalid incoming-block operand index!"); + return i/2; } /// addIncoming - Add an incoming value to the end of the PHI list @@ -1928,12 +1908,13 @@ assert(BB && "PHI node got a null basic block!"); assert(getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"); - if (NumOperands == ReservedSpace) + unsigned OpNo = NumOperands; + if (OpNo+2 > ReservedSpace) growOperands(); // Get more space! // Initialize some new operands. - ++NumOperands; - setIncomingValue(NumOperands - 1, V); - setIncomingBlock(NumOperands - 1, BB); + NumOperands = OpNo+2; + OperandList[OpNo] = V; + OperandList[OpNo+1] = (Value*)BB; } /// removeIncomingValue - Remove an incoming value. This is useful if a @@ -1956,16 +1937,14 @@ /// block in the value list for this PHI. Returns -1 if no instance. /// int getBasicBlockIndex(const BasicBlock *BB) const { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (block_begin()[i] == BB) - return i; + Use *OL = OperandList; + for (unsigned i = 0, e = getNumOperands(); i != e; i += 2) + if (OL[i+1].get() == (const Value*)BB) return i/2; return -1; } Value *getIncomingValueForBlock(const BasicBlock *BB) const { - int Idx = getBasicBlockIndex(BB); - assert(Idx >= 0 && "Invalid basic block argument!"); - return getIncomingValue(Idx); + return getIncomingValue(getBasicBlockIndex(BB)); } /// hasConstantValue - If the specified PHI node always merges together the Modified: llvm/trunk/include/llvm/Support/CFG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CFG.h?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CFG.h (original) +++ llvm/trunk/include/llvm/Support/CFG.h Mon Jun 20 21:09:03 2011 @@ -33,7 +33,7 @@ USE_iterator It; inline void advancePastNonTerminators() { - // Loop to ignore non terminator uses (for example BlockAddresses). + // Loop to ignore non terminator uses (for example PHI nodes). while (!It.atEnd() && !isa(*It)) ++It; } Modified: llvm/trunk/include/llvm/Use.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Use.h?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/include/llvm/Use.h (original) +++ llvm/trunk/include/llvm/Use.h Mon Jun 20 21:09:03 2011 @@ -112,16 +112,13 @@ Use *getNext() const { return Next; } - /// initTags - initialize the waymarking tags on an array of Uses, so that - /// getUser() can find the User from any of those Uses. - static Use *initTags(Use *Start, Use *Stop); - /// zap - This is used to destroy Use operands when the number of operands of /// a User changes. static void zap(Use *Start, const Use *Stop, bool del = false); private: const Use* getImpliedUser() const; + static Use *initTags(Use *Start, Use *Stop); Value *Val; Use *Next; @@ -143,6 +140,7 @@ } friend class Value; + friend class User; }; // simplify_type - Allow clients to treat uses just like values when using Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Mon Jun 20 21:09:03 2011 @@ -1356,7 +1356,7 @@ for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) { Out << iName << "->addIncoming(" << opNames[PHINode::getOperandNumForIncomingValue(i)] << ", " - << getOpName(phi->getIncomingBlock(i)) << ");"; + << opNames[PHINode::getOperandNumForIncomingBlock(i)] << ");"; nl(Out); } break; Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Mon Jun 20 21:09:03 2011 @@ -1021,10 +1021,6 @@ while (PHINode *PN = dyn_cast(Succ->begin())) ReplaceUsesOfWith(PN, PN->getIncomingValue(0), Worklist, L, LPM); - // If Succ has any successors with PHI nodes, update them to have - // entries coming from Pred instead of Succ. - Succ->replaceAllUsesWith(Pred); - // Move all of the successor contents from Succ to Pred. Pred->getInstList().splice(BI, Succ->getInstList(), Succ->begin(), Succ->end()); @@ -1032,6 +1028,10 @@ BI->eraseFromParent(); RemoveFromWorklist(BI, Worklist); + // If Succ has any successors with PHI nodes, update them to have + // entries coming from Pred instead of Succ. + Succ->replaceAllUsesWith(Pred); + // Remove Succ from the loop tree. LI->removeBlock(Succ); LPM->deleteSimpleAnalysisValue(Succ, L); Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Mon Jun 20 21:09:03 2011 @@ -153,13 +153,13 @@ // Delete the unconditional branch from the predecessor... PredBB->getInstList().pop_back(); + // Move all definitions in the successor to the predecessor... + PredBB->getInstList().splice(PredBB->end(), BB->getInstList()); + // Make all PHI nodes that referred to BB now refer to Pred as their // source... BB->replaceAllUsesWith(PredBB); - // Move all definitions in the successor to the predecessor... - PredBB->getInstList().splice(PredBB->end(), BB->getInstList()); - // Inherit predecessors name if it exists. if (!PredBB->hasName()) PredBB->takeName(BB); Modified: llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp Mon Jun 20 21:09:03 2011 @@ -193,22 +193,44 @@ // If there are any PHI nodes in DestBB, we need to update them so that they // merge incoming values from NewBB instead of from TIBB. - { - unsigned BBIdx = 0; - for (BasicBlock::iterator I = DestBB->begin(); isa(I); ++I) { - // We no longer enter through TIBB, now we come in through NewBB. - // Revector exactly one entry in the PHI node that used to come from - // TIBB to come from NewBB. - PHINode *PN = cast(I); - - // Reuse the previous value of BBIdx if it lines up. In cases where we - // have multiple phi nodes with *lots* of predecessors, this is a speed - // win because we don't have to scan the PHI looking for TIBB. This - // happens because the BB list of PHI nodes are usually in the same - // order. - if (PN->getIncomingBlock(BBIdx) != TIBB) - BBIdx = PN->getBasicBlockIndex(TIBB); - PN->setIncomingBlock(BBIdx, NewBB); + if (PHINode *APHI = dyn_cast(DestBB->begin())) { + // This conceptually does: + // foreach (PHINode *PN in DestBB) + // PN->setIncomingBlock(PN->getIncomingBlock(TIBB), NewBB); + // but is optimized for two cases. + + if (APHI->getNumIncomingValues() <= 8) { // Small # preds case. + unsigned BBIdx = 0; + for (BasicBlock::iterator I = DestBB->begin(); isa(I); ++I) { + // We no longer enter through TIBB, now we come in through NewBB. + // Revector exactly one entry in the PHI node that used to come from + // TIBB to come from NewBB. + PHINode *PN = cast(I); + + // Reuse the previous value of BBIdx if it lines up. In cases where we + // have multiple phi nodes with *lots* of predecessors, this is a speed + // win because we don't have to scan the PHI looking for TIBB. This + // happens because the BB list of PHI nodes are usually in the same + // order. + if (PN->getIncomingBlock(BBIdx) != TIBB) + BBIdx = PN->getBasicBlockIndex(TIBB); + PN->setIncomingBlock(BBIdx, NewBB); + } + } else { + // However, the foreach loop is slow for blocks with lots of predecessors + // because PHINode::getIncomingBlock is O(n) in # preds. Instead, walk + // the user list of TIBB to find the PHI nodes. + SmallPtrSet UpdatedPHIs; + + for (Value::use_iterator UI = TIBB->use_begin(), E = TIBB->use_end(); + UI != E; ) { + Value::use_iterator Use = UI++; + if (PHINode *PN = dyn_cast(*Use)) { + // Remove one entry from each PHI. + if (PN->getParent() == DestBB && UpdatedPHIs.insert(PN)) + PN->setOperand(Use.getOperandNo(), NewBB); + } + } } } Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Mon Jun 20 21:09:03 2011 @@ -572,12 +572,12 @@ // removed, so we just need to splice the blocks. BI->eraseFromParent(); - // Make all PHI nodes that referred to Dest now refer to I as their source. - Dest->replaceAllUsesWith(I); - // Move all the instructions in the succ to the pred. I->getInstList().splice(I->end(), Dest->getInstList()); + // Make all PHI nodes that referred to Dest now refer to I as their source. + Dest->replaceAllUsesWith(I); + // Remove the dest block. Dest->eraseFromParent(); Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Mon Jun 20 21:09:03 2011 @@ -1097,15 +1097,15 @@ TheCall->replaceAllUsesWith(Returns[0]->getReturnValue()); } - // Update PHI nodes that use the ReturnBB to use the AfterCallBB. - BasicBlock *ReturnBB = Returns[0]->getParent(); - ReturnBB->replaceAllUsesWith(AfterCallBB); - // Splice the code from the return block into the block that it will return // to, which contains the code that was after the call. + BasicBlock *ReturnBB = Returns[0]->getParent(); AfterCallBB->getInstList().splice(AfterCallBB->begin(), ReturnBB->getInstList()); + // Update PHI nodes that use the ReturnBB to use the AfterCallBB. + ReturnBB->replaceAllUsesWith(AfterCallBB); + // Delete the return instruction now and empty ReturnBB now. Returns[0]->eraseFromParent(); ReturnBB->eraseFromParent(); @@ -1125,8 +1125,8 @@ // Splice the code entry block into calling block, right before the // unconditional branch. - CalleeEntry->replaceAllUsesWith(OrigBB); // Update PHI nodes OrigBB->getInstList().splice(Br, CalleeEntry->getInstList()); + CalleeEntry->replaceAllUsesWith(OrigBB); // Update PHI nodes // Remove the unconditional branch. OrigBB->getInstList().erase(Br); Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Mon Jun 20 21:09:03 2011 @@ -427,6 +427,10 @@ BasicBlock *PredBB = DestBB->getSinglePredecessor(); assert(PredBB && "Block doesn't have a single predecessor!"); + // Splice all the instructions from PredBB to DestBB. + PredBB->getTerminator()->eraseFromParent(); + DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList()); + // Zap anything that took the address of DestBB. Not doing this will give the // address an invalid value. if (DestBB->hasAddressTaken()) { @@ -441,10 +445,6 @@ // Anything that branched to PredBB now branches to DestBB. PredBB->replaceAllUsesWith(DestBB); - // Splice all the instructions from PredBB to DestBB. - PredBB->getTerminator()->eraseFromParent(); - DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList()); - if (P) { DominatorTree *DT = P->getAnalysisIfAvailable(); if (DT) { @@ -660,17 +660,12 @@ // them, which helps expose duplicates, but we have to check all the // operands to be safe in case instcombine hasn't run. uintptr_t Hash = 0; - // This hash algorithm is quite weak as hash functions go, but it seems - // to do a good enough job for this particular purpose, and is very quick. for (User::op_iterator I = PN->op_begin(), E = PN->op_end(); I != E; ++I) { + // This hash algorithm is quite weak as hash functions go, but it seems + // to do a good enough job for this particular purpose, and is very quick. Hash ^= reinterpret_cast(static_cast(*I)); Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7)); } - for (PHINode::block_iterator I = PN->block_begin(), E = PN->block_end(); - I != E; ++I) { - Hash ^= reinterpret_cast(static_cast(*I)); - Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7)); - } // Avoid colliding with the DenseMap sentinels ~0 and ~0-1. Hash >>= 1; // If we've never seen this hash value before, it's a unique PHI. Modified: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Mon Jun 20 21:09:03 2011 @@ -47,14 +47,6 @@ if (It != VMap.end()) I->setOperand(op, It->second); } - - if (PHINode *PN = dyn_cast(I)) { - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { - ValueToValueMapTy::iterator It = VMap.find(PN->getIncomingBlock(i)); - if (It != VMap.end()) - PN->setIncomingBlock(i, cast(It->second)); - } - } } /// FoldBlockIntoPredecessor - Folds a basic block into its predecessor if it @@ -83,13 +75,13 @@ // Delete the unconditional branch from the predecessor... OnlyPred->getInstList().pop_back(); + // Move all definitions in the successor to the predecessor... + OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList()); + // Make all PHI nodes that referred to BB now refer to Pred as their // source... BB->replaceAllUsesWith(OnlyPred); - // Move all definitions in the successor to the predecessor... - OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList()); - std::string OldName = BB->getName(); // Erase basic block from the function... @@ -255,14 +247,16 @@ // the successor of the latch block. The successor of the exit block will // be updated specially after unrolling all the way. if (*BB != LatchBlock) - for (succ_iterator SI = succ_begin(*BB), SE = succ_end(*BB); SI != SE; - ++SI) - if (!L->contains(*SI)) - for (BasicBlock::iterator BBI = (*SI)->begin(), BBE = (*SI)->end(); - PHINode *phi = dyn_cast(BBI); ++BBI) { - Value *Incoming = phi->getIncomingValueForBlock(*BB); - phi->addIncoming(Incoming, New); - } + for (Value::use_iterator UI = (*BB)->use_begin(), UE = (*BB)->use_end(); + UI != UE;) { + Instruction *UseInst = cast(*UI); + ++UI; + if (isa(UseInst) && !L->contains(UseInst)) { + PHINode *phi = cast(UseInst); + Value *Incoming = phi->getIncomingValueForBlock(*BB); + phi->addIncoming(Incoming, New); + } + } // Keep track of new headers and latches as we create them, so that // we can insert the proper branches later. @@ -294,20 +288,24 @@ // successor blocks, update them to use the appropriate values computed as the // last iteration of the loop. if (Count != 1) { + SmallPtrSet Users; + for (Value::use_iterator UI = LatchBlock->use_begin(), + UE = LatchBlock->use_end(); UI != UE; ++UI) + if (PHINode *phi = dyn_cast(*UI)) + Users.insert(phi); + BasicBlock *LastIterationBB = cast(LastValueMap[LatchBlock]); - for (succ_iterator SI = succ_begin(LatchBlock), SE = succ_end(LatchBlock); + for (SmallPtrSet::iterator SI = Users.begin(), SE = Users.end(); SI != SE; ++SI) { - for (BasicBlock::iterator BBI = (*SI)->begin(), BBE = (*SI)->end(); - PHINode *PN = dyn_cast(BBI); ++BBI) { - Value *InVal = PN->removeIncomingValue(LatchBlock, false); - // If this value was defined in the loop, take the value defined by the - // last iteration of the loop. - if (Instruction *InValI = dyn_cast(InVal)) { - if (L->contains(InValI)) - InVal = LastValueMap[InVal]; - } - PN->addIncoming(InVal, LastIterationBB); + PHINode *PN = *SI; + Value *InVal = PN->removeIncomingValue(LatchBlock, false); + // If this value was defined in the loop, take the value defined by the + // last iteration of the loop. + if (Instruction *InValI = dyn_cast(InVal)) { + if (L->contains(InValI)) + InVal = LastValueMap[InVal]; } + PN->addIncoming(InVal, LastIterationBB); } } @@ -354,16 +352,11 @@ // Replace the conditional branch with an unconditional one. BranchInst::Create(Dest, Term); Term->eraseFromParent(); - } - } - - // Merge adjacent basic blocks, if possible. - for (unsigned i = 0, e = Latches.size(); i != e; ++i) { - BranchInst *Term = cast(Latches[i]->getTerminator()); - if (Term->isUnconditional()) { - BasicBlock *Dest = Term->getSuccessor(0); - if (BasicBlock *Fold = FoldBlockIntoPredecessor(Dest, LI)) + // Merge adjacent basic blocks, if possible. + if (BasicBlock *Fold = FoldBlockIntoPredecessor(Dest, LI)) { std::replace(Latches.begin(), Latches.end(), Dest, Fold); + std::replace(Headers.begin(), Headers.end(), Dest, Fold); + } } } Modified: llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp Mon Jun 20 21:09:03 2011 @@ -16,7 +16,6 @@ #include "llvm/Type.h" #include "llvm/Constants.h" #include "llvm/Function.h" -#include "llvm/Instructions.h" #include "llvm/Metadata.h" #include "llvm/ADT/SmallVector.h" using namespace llvm; @@ -129,19 +128,6 @@ "Referenced value not in value map!"); } - // Remap phi nodes' incoming blocks. - if (PHINode *PN = dyn_cast(I)) { - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { - Value *V = MapValue(PN->getIncomingBlock(i), VMap, Flags); - // If we aren't ignoring missing entries, assert that something happened. - if (V != 0) - PN->setIncomingBlock(i, cast(V)); - else - assert((Flags & RF_IgnoreMissingEntries) && - "Referenced block not in value map!"); - } - } - // Remap attached metadata. SmallVector, 4> MDs; I->getAllMetadata(MDs); Modified: llvm/trunk/lib/VMCore/BasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/BasicBlock.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/BasicBlock.cpp (original) +++ llvm/trunk/lib/VMCore/BasicBlock.cpp Mon Jun 20 21:09:03 2011 @@ -308,19 +308,3 @@ return New; } -void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) { - TerminatorInst *TI = getTerminator(); - if (!TI) - // Cope with being called on a BasicBlock that doesn't have a terminator - // yet. Clang's CodeGenFunction::EmitReturnBlock() likes to do this. - return; - for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) { - BasicBlock *Succ = TI->getSuccessor(i); - for (iterator II = Succ->begin(); PHINode *PN = dyn_cast(II); - ++II) { - int i; - while ((i = PN->getBasicBlockIndex(this)) >= 0) - PN->setIncomingBlock(i, New); - } - } -} Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Mon Jun 20 21:09:03 2011 @@ -87,8 +87,11 @@ : Instruction(PN.getType(), Instruction::PHI, allocHungoffUses(PN.getNumOperands()), PN.getNumOperands()), ReservedSpace(PN.getNumOperands()) { - std::copy(PN.op_begin(), PN.op_end(), op_begin()); - std::copy(PN.block_begin(), PN.block_end(), block_begin()); + Use *OL = OperandList; + for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) { + OL[i] = PN.getOperand(i); + OL[i+1] = PN.getOperand(i+1); + } SubclassOptionalData = PN.SubclassOptionalData; } @@ -96,37 +99,31 @@ dropHungoffUses(); } -Use *PHINode::allocHungoffUses(unsigned N) const { - // Allocate the array of Uses of the incoming values, followed by a pointer - // (with bottom bit set) to the User, followed by the array of pointers to - // the incoming basic blocks. - size_t size = N * sizeof(Use) + sizeof(Use::UserRef) - + N * sizeof(BasicBlock*); - Use *Begin = static_cast(::operator new(size)); - Use *End = Begin + N; - (void) new(End) Use::UserRef(const_cast(this), 1); - return Use::initTags(Begin, End); -} - // removeIncomingValue - Remove an incoming value. This is useful if a // predecessor basic block is deleted. Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) { - Value *Removed = getIncomingValue(Idx); + unsigned NumOps = getNumOperands(); + Use *OL = OperandList; + assert(Idx*2 < NumOps && "BB not in PHI node!"); + Value *Removed = OL[Idx*2]; // Move everything after this operand down. // // FIXME: we could just swap with the end of the list, then erase. However, - // clients might not expect this to happen. The code as it is thrashes the + // client might not expect this to happen. The code as it is thrashes the // use/def lists, which is kinda lame. - std::copy(op_begin() + Idx + 1, op_end(), op_begin() + Idx); - std::copy(block_begin() + Idx + 1, block_end(), block_begin() + Idx); + for (unsigned i = (Idx+1)*2; i != NumOps; i += 2) { + OL[i-2] = OL[i]; + OL[i-2+1] = OL[i+1]; + } // Nuke the last value. - Op<-1>().set(0); - --NumOperands; + OL[NumOps-2].set(0); + OL[NumOps-2+1].set(0); + NumOperands = NumOps-2; // If the PHI node is dead, because it has zero entries, nuke it now. - if (getNumOperands() == 0 && DeletePHIIfEmpty) { + if (NumOps == 2 && DeletePHIIfEmpty) { // If anyone is using this PHI, make them use a dummy value instead... replaceAllUsesWith(UndefValue::get(getType())); eraseFromParent(); @@ -140,18 +137,15 @@ /// void PHINode::growOperands() { unsigned e = getNumOperands(); - unsigned NumOps = e + e / 2; - if (NumOps < 2) NumOps = 2; // 2 op PHI nodes are VERY common. - - Use *OldOps = op_begin(); - BasicBlock **OldBlocks = block_begin(); + // Multiply by 1.5 and round down so the result is still even. + unsigned NumOps = e + e / 4 * 2; + if (NumOps < 4) NumOps = 4; // 4 op PHI nodes are VERY common. ReservedSpace = NumOps; - OperandList = allocHungoffUses(ReservedSpace); - - std::copy(OldOps, OldOps + e, op_begin()); - std::copy(OldBlocks, OldBlocks + e, block_begin()); - + Use *OldOps = OperandList; + Use *NewOps = allocHungoffUses(NumOps); + std::copy(OldOps, OldOps + e, NewOps); + OperandList = NewOps; Use::zap(OldOps, OldOps + e, true); } Modified: llvm/trunk/lib/VMCore/User.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/User.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/User.cpp (original) +++ llvm/trunk/lib/VMCore/User.cpp Mon Jun 20 21:09:03 2011 @@ -40,10 +40,8 @@ //===----------------------------------------------------------------------===// Use *User::allocHungoffUses(unsigned N) const { - // Allocate the array of Uses, followed by a pointer (with bottom bit set) to - // the User. - size_t size = N * sizeof(Use) + sizeof(Use::UserRef); - Use *Begin = static_cast(::operator new(size)); + Use *Begin = static_cast(::operator new(sizeof(Use) * N + + sizeof(Use::UserRef))); Use *End = Begin + N; (void) new(End) Use::UserRef(const_cast(this), 1); return Use::initTags(Begin, End); Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Mon Jun 20 21:09:03 2011 @@ -305,9 +305,6 @@ U.set(New); } - - if (BasicBlock *BB = dyn_cast(this)) - BB->replaceSuccessorsPhiUsesWith(cast(New)); } void Value::replaceAllUsesWith(Value *New) { Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=133499&r1=133498&r2=133499&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Mon Jun 20 21:09:03 2011 @@ -1139,6 +1139,9 @@ for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { Assert1(PN.getType() == PN.getIncomingValue(i)->getType(), "PHI node operands are not the same type as the result!", &PN); + Assert1(isa(PN.getOperand( + PHINode::getOperandNumForIncomingBlock(i))), + "PHI node incoming block is not a BasicBlock!", &PN); } // All other PHI node constraints are checked in the visitBasicBlock method. From chenwj at iis.sinica.edu.tw Mon Jun 20 20:36:34 2011 From: chenwj at iis.sinica.edu.tw (=?utf-8?B?6Zmz6Z+L5Lu7?=) Date: Tue, 21 Jun 2011 09:36:34 +0800 Subject: [llvm-commits] [PATCH][Target/PTX] Add address_size directive to PTX backend In-Reply-To: References: <20110617073109.GA93378@cs.nctu.edu.tw> <20110618065617.GA25444@cs.nctu.edu.tw> <20110619121258.GA50677@cs.nctu.edu.tw> <347A9771-6ADD-4454-86D6-2842AEA82D44@gmail.com> <20110620015129.GA56262@cs.nctu.edu.tw> Message-ID: <20110621013634.GA86556@cs.nctu.edu.tw> > I hate to nit-pick, but do we really need the address size field and associated enumeration? It's always tied to the 64-bit flag, and we do not need to create any TableGen predicates from the value. > > I think this patch can be as simple as: > > if (ST.supportsPTX23()) { > std::string addrSize = is64Bit() ? "64" : "32"; > OutStreamer.EmitRawText(Twine("\t.address_size " + addrSize)); > } Done. Regards, chenwj -- Wei-Ren Chen (???) Computer Systems Lab, Institute of Information Science, Academia Sinica, Taiwan (R.O.C.) Tel:886-2-2788-3799 #1667 -------------- next part -------------- Index: test/CodeGen/PTX/options.ll =================================================================== --- test/CodeGen/PTX/options.ll (revision 133496) +++ test/CodeGen/PTX/options.ll (working copy) @@ -5,6 +5,8 @@ ; RUN: llc < %s -march=ptx32 -mattr=sm10 | grep ".target sm_10" ; RUN: llc < %s -march=ptx32 -mattr=sm13 | grep ".target sm_13" ; RUN: llc < %s -march=ptx32 -mattr=sm20 | grep ".target sm_20" +; RUN: llc < %s -march=ptx32 -mattr=ptx23 | grep ".address_size 32" +; RUN: llc < %s -march=ptx64 -mattr=ptx23 | grep ".address_size 64" define ptx_device void @t1() { ret void Index: lib/Target/PTX/PTXAsmPrinter.cpp =================================================================== --- lib/Target/PTX/PTXAsmPrinter.cpp (revision 133496) +++ lib/Target/PTX/PTXAsmPrinter.cpp (working copy) @@ -163,6 +163,13 @@ OutStreamer.EmitRawText(Twine("\t.target " + ST.getTargetString() + (ST.supportsDouble() ? "" : ", map_f64_to_f32"))); + // .address_size directive is optional, but it must immediately follow + // the .target directive if present within a module + if (ST.supportsPTX23()) { + std::string addrSize = ST.is64Bit() ? "64" : "32"; + OutStreamer.EmitRawText(Twine("\t.address_size " + addrSize)); + } + OutStreamer.AddBlankLine(); // declare global variables From evan.cheng at apple.com Mon Jun 20 21:41:38 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 20 Jun 2011 19:41:38 -0700 Subject: [llvm-commits] [llvm] r133289 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrThumb2.td test/CodeGen/ARM/rev.ll In-Reply-To: <5FA0FBB4-F54C-4C4C-9C34-EB3EE73F6462@apple.com> References: <20110617204721.8235E2A6C12C@llvm.org> <17797AD1-4AD0-4029-85E9-808F1E61821A@apple.com> <5FA0FBB4-F54C-4C4C-9C34-EB3EE73F6462@apple.com> Message-ID: I'm working on a fix. Evan On Jun 18, 2011, at 12:10 AM, Chris Lattner wrote: > > On Jun 17, 2011, at 11:06 PM, Eli Friedman wrote: > >> On Fri, Jun 17, 2011 at 9:53 PM, Chris Lattner wrote: >>> >>> On Jun 17, 2011, at 1:47 PM, Evan Cheng wrote: >>> >>>> Author: evancheng >>>> Date: Fri Jun 17 15:47:21 2011 >>>> New Revision: 133289 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=133289&view=rev >>>> Log: >>>> Add an alternative rev16 pattern. We should figure out a better way to handle these complex rev patterns. rdar://9609108 >>> >>> Is rev16 just a bswap? >> >> It's bswap+rotate by 16. > > Ok, can/should the pattern be written in terms of bswap+rotate? > > -Chris From atrick at apple.com Mon Jun 20 22:22:38 2011 From: atrick at apple.com (Andrew Trick) Date: Tue, 21 Jun 2011 03:22:38 -0000 Subject: [llvm-commits] [llvm] r133502 - in /llvm/trunk: lib/Transforms/Scalar/IndVarSimplify.cpp test/Transforms/IndVarSimplify/iv-zext.ll Message-ID: <20110621032238.34E8D2A6C12C@llvm.org> Author: atrick Date: Mon Jun 20 22:22:38 2011 New Revision: 133502 URL: http://llvm.org/viewvc/llvm-project?rev=133502&view=rev Log: indvars -disable-iv-rewrite: Adds support for eliminating identity ops. This is a rewrite of the IV simplification algorithm used by -disable-iv-rewrite. To avoid perturbing the default mode, I temporarily split the driver and created SimplifyIVUsersNoRewrite. The idea is to avoid doing opcode/pattern matching inside IndVarSimplify. SCEV already does it. We want to optimize with the full generality of SCEV, but optimize def-use chains top down on-demand rather than rewriting the entire expression bottom-up. This was easy to do for operations that SCEV can prove are identity function. So we're now eliminating bitmasks and zero extends this way. A result of this rewrite is that indvars -disable-iv-rewrite no longer requires IVUsers. Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp llvm/trunk/test/Transforms/IndVarSimplify/iv-zext.ll Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=133502&r1=133501&r2=133502&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Mon Jun 20 22:22:38 2011 @@ -62,14 +62,15 @@ #include "llvm/ADT/STLExtras.h" using namespace llvm; -STATISTIC(NumRemoved , "Number of aux indvars removed"); -STATISTIC(NumWidened , "Number of indvars widened"); -STATISTIC(NumInserted, "Number of canonical indvars added"); -STATISTIC(NumReplaced, "Number of exit values replaced"); -STATISTIC(NumLFTR , "Number of loop exit tests replaced"); -STATISTIC(NumElimExt , "Number of IV sign/zero extends eliminated"); -STATISTIC(NumElimRem , "Number of IV remainder operations eliminated"); -STATISTIC(NumElimCmp , "Number of IV comparisons eliminated"); +STATISTIC(NumRemoved , "Number of aux indvars removed"); +STATISTIC(NumWidened , "Number of indvars widened"); +STATISTIC(NumInserted , "Number of canonical indvars added"); +STATISTIC(NumReplaced , "Number of exit values replaced"); +STATISTIC(NumLFTR , "Number of loop exit tests replaced"); +STATISTIC(NumElimIdentity, "Number of IV identities eliminated"); +STATISTIC(NumElimExt , "Number of IV sign/zero extends eliminated"); +STATISTIC(NumElimRem , "Number of IV remainder operations eliminated"); +STATISTIC(NumElimCmp , "Number of IV comparisons eliminated"); // DisableIVRewrite mode currently affects IVUsers, so is defined in libAnalysis // and referenced here. @@ -84,12 +85,22 @@ ScalarEvolution *SE; DominatorTree *DT; TargetData *TD; + + PHINode *CurrIV; // Current IV being simplified. + + // Instructions processed by SimplifyIVUsers for CurrIV. + SmallPtrSet Simplified; + + // Use-def pairs if IVUsers waiting to be processed for CurrIV. + SmallVector, 8> SimpleIVUsers; + SmallVector DeadInsts; bool Changed; public: static char ID; // Pass identification, replacement for typeid - IndVarSimplify() : LoopPass(ID), IU(0), LI(0), SE(0), DT(0), TD(0) { + IndVarSimplify() : LoopPass(ID), IU(0), LI(0), SE(0), DT(0), TD(0), + CurrIV(0), Changed(false) { initializeIndVarSimplifyPass(*PassRegistry::getPassRegistry()); } @@ -105,7 +116,8 @@ AU.addPreserved(); AU.addPreservedID(LoopSimplifyID); AU.addPreservedID(LCSSAID); - AU.addPreserved(); + if (!DisableIVRewrite) + AU.addPreserved(); AU.setPreservesCFG(); } @@ -113,11 +125,16 @@ bool isValidRewrite(Value *FromVal, Value *ToVal); void SimplifyIVUsers(SCEVExpander &Rewriter); + void SimplifyIVUsersNoRewrite(Loop *L, SCEVExpander &Rewriter); + + bool EliminateIVUser(Instruction *UseInst, Instruction *IVOperand); void EliminateIVComparison(ICmpInst *ICmp, Value *IVOperand); void EliminateIVRemainder(BinaryOperator *Rem, Value *IVOperand, bool IsSigned, PHINode *IVPhi); + void pushIVUsers(Instruction *Def); + bool isSimpleIVUser(Instruction *I, const Loop *L); void RewriteNonIntegerIVs(Loop *L); ICmpInst *LinearFunctionTestReplace(Loop *L, const SCEV *BackedgeTakenCount, @@ -483,6 +500,36 @@ SE->forgetLoop(L); } +/// SimplifyIVUsers - Iteratively perform simplification on IVUsers within this +/// loop. IVUsers is treated as a worklist. Each successive simplification may +/// push more users which may themselves be candidates for simplification. +/// +/// This is the old approach to IV simplification to be replaced by +/// SimplifyIVUsersNoRewrite. +/// +void IndVarSimplify::SimplifyIVUsers(SCEVExpander &Rewriter) { + // Each round of simplification involves a round of eliminating operations + // followed by a round of widening IVs. A single IVUsers worklist is used + // across all rounds. The inner loop advances the user. If widening exposes + // more uses, then another pass through the outer loop is triggered. + for (IVUsers::iterator I = IU->begin(); I != IU->end(); ++I) { + Instruction *UseInst = I->getUser(); + Value *IVOperand = I->getOperandValToReplace(); + + if (ICmpInst *ICmp = dyn_cast(UseInst)) { + EliminateIVComparison(ICmp, IVOperand); + continue; + } + if (BinaryOperator *Rem = dyn_cast(UseInst)) { + bool IsSigned = Rem->getOpcode() == Instruction::SRem; + if (IsSigned || Rem->getOpcode() == Instruction::URem) { + EliminateIVRemainder(Rem, IVOperand, IsSigned, I->getPhi()); + continue; + } + } + } +} + namespace { // Collect information about induction variables that are used by sign/zero // extend operations. This information is recorded by CollectExtend and @@ -493,33 +540,30 @@ WideIVInfo() : WidestNativeType(0), IsSigned(false) {} }; - typedef std::map WideIVMap; } /// CollectExtend - Update information about the induction variable that is /// extended by this sign or zero extend operation. This is used to determine /// the final width of the IV before actually widening it. -static void CollectExtend(CastInst *Cast, PHINode *Phi, bool IsSigned, - WideIVMap &IVMap, ScalarEvolution *SE, - const TargetData *TD) { +static void CollectExtend(CastInst *Cast, bool IsSigned, WideIVInfo &WI, + ScalarEvolution *SE, const TargetData *TD) { const Type *Ty = Cast->getType(); uint64_t Width = SE->getTypeSizeInBits(Ty); if (TD && !TD->isLegalInteger(Width)) return; - WideIVInfo &IVInfo = IVMap[Phi]; - if (!IVInfo.WidestNativeType) { - IVInfo.WidestNativeType = SE->getEffectiveSCEVType(Ty); - IVInfo.IsSigned = IsSigned; + if (!WI.WidestNativeType) { + WI.WidestNativeType = SE->getEffectiveSCEVType(Ty); + WI.IsSigned = IsSigned; return; } // We extend the IV to satisfy the sign of its first user, arbitrarily. - if (IVInfo.IsSigned != IsSigned) + if (WI.IsSigned != IsSigned) return; - if (Width > SE->getTypeSizeInBits(IVInfo.WidestNativeType)) - IVInfo.WidestNativeType = SE->getEffectiveSCEVType(Ty); + if (Width > SE->getTypeSizeInBits(WI.WidestNativeType)) + WI.WidestNativeType = SE->getEffectiveSCEVType(Ty); } namespace { @@ -529,43 +573,44 @@ /// inserting truncs whenever we stop propagating the type. /// class WidenIV { + // Parameters PHINode *OrigPhi; const Type *WideType; bool IsSigned; - IVUsers *IU; - LoopInfo *LI; - Loop *L; + // Context + LoopInfo *LI; + Loop *L; ScalarEvolution *SE; - DominatorTree *DT; - SmallVectorImpl &DeadInsts; + DominatorTree *DT; + // Result PHINode *WidePhi; Instruction *WideInc; const SCEV *WideIncExpr; + SmallVectorImpl &DeadInsts; - SmallPtrSet Processed; + SmallPtrSet Widened; public: - WidenIV(PHINode *PN, const WideIVInfo &IVInfo, IVUsers *IUsers, - LoopInfo *LInfo, ScalarEvolution *SEv, DominatorTree *DTree, + WidenIV(PHINode *PN, const WideIVInfo &WI, LoopInfo *LInfo, + ScalarEvolution *SEv, DominatorTree *DTree, SmallVectorImpl &DI) : OrigPhi(PN), - WideType(IVInfo.WidestNativeType), - IsSigned(IVInfo.IsSigned), - IU(IUsers), + WideType(WI.WidestNativeType), + IsSigned(WI.IsSigned), LI(LInfo), L(LI->getLoopFor(OrigPhi->getParent())), SE(SEv), DT(DTree), - DeadInsts(DI), WidePhi(0), WideInc(0), - WideIncExpr(0) { + WideIncExpr(0), + DeadInsts(DI) { assert(L->getHeader() == OrigPhi->getParent() && "Phi must be an IV"); } - bool CreateWideIV(SCEVExpander &Rewriter); + PHINode *CreateWideIV(SCEVExpander &Rewriter); protected: Instruction *CloneIVUser(Instruction *NarrowUse, @@ -580,52 +625,6 @@ }; } // anonymous namespace -/// SimplifyIVUsers - Iteratively perform simplification on IVUsers within this -/// loop. IVUsers is treated as a worklist. Each successive simplification may -/// push more users which may themselves be candidates for simplification. -/// -void IndVarSimplify::SimplifyIVUsers(SCEVExpander &Rewriter) { - WideIVMap IVMap; - - // Each round of simplification involves a round of eliminating operations - // followed by a round of widening IVs. A single IVUsers worklist is used - // across all rounds. The inner loop advances the user. If widening exposes - // more uses, then another pass through the outer loop is triggered. - for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E;) { - for(; I != E; ++I) { - Instruction *UseInst = I->getUser(); - Value *IVOperand = I->getOperandValToReplace(); - - if (DisableIVRewrite) { - if (CastInst *Cast = dyn_cast(UseInst)) { - bool IsSigned = Cast->getOpcode() == Instruction::SExt; - if (IsSigned || Cast->getOpcode() == Instruction::ZExt) { - CollectExtend(Cast, I->getPhi(), IsSigned, IVMap, SE, TD); - continue; - } - } - } - if (ICmpInst *ICmp = dyn_cast(UseInst)) { - EliminateIVComparison(ICmp, IVOperand); - continue; - } - if (BinaryOperator *Rem = dyn_cast(UseInst)) { - bool IsSigned = Rem->getOpcode() == Instruction::SRem; - if (IsSigned || Rem->getOpcode() == Instruction::URem) { - EliminateIVRemainder(Rem, IVOperand, IsSigned, I->getPhi()); - continue; - } - } - } - for (WideIVMap::const_iterator I = IVMap.begin(), E = IVMap.end(); - I != E; ++I) { - WidenIV Widener(I->first, I->second, IU, LI, SE, DT, DeadInsts); - if (Widener.CreateWideIV(Rewriter)) - Changed = true; - } - } -} - static Value *getExtend( Value *NarrowOper, const Type *WideType, bool IsSigned, IRBuilder<> &Builder) { return IsSigned ? Builder.CreateSExt(NarrowOper, WideType) : @@ -744,7 +743,7 @@ return 0; // Handle data flow merges and bizarre phi cycles. - if (!Processed.insert(NarrowUse)) + if (!Widened.insert(NarrowUse)) return 0; // Our raison d'etre! Eliminate sign and zero extension. @@ -775,9 +774,11 @@ NarrowUse->replaceAllUsesWith(NewDef); DeadInsts.push_back(NarrowUse); } - // Now that the extend is gone, expose it's uses to IVUsers for potential - // further simplification within SimplifyIVUsers. - IU->AddUsersIfInteresting(WideDef, WidePhi); + // Now that the extend is gone, we want to expose it's uses for potential + // further simplification. We don't need to directly inform SimplifyIVUsers + // of the new users, because their parent IV will be processed later as a + // new loop phi. If we preserved IVUsers analysis, we would also want to + // push the uses of WideDef here. // No further widening is needed. The deceased [sz]ext had done it for us. return 0; @@ -807,7 +808,7 @@ // outside the loop without overflow. This suggests that the wide use // evaluates to the same expression as the extended narrow use, but doesn't // absolutely guarantee it. Hence the following failsafe check. In rare cases - // where it fails, we simple throw away the newly created wide use. + // where it fails, we simply throw away the newly created wide use. if (WideAddRec != SE->getSCEV(WideUse)) { DEBUG(dbgs() << "Wide use expression mismatch: " << *WideUse << ": " << *SE->getSCEV(WideUse) << " != " << *WideAddRec << "\n"); @@ -822,18 +823,18 @@ /// CreateWideIV - Process a single induction variable. First use the /// SCEVExpander to create a wide induction variable that evaluates to the same /// recurrence as the original narrow IV. Then use a worklist to forward -/// traverse the narrow IV's def-use chain. After WidenIVUse as processed all +/// traverse the narrow IV's def-use chain. After WidenIVUse has processed all /// interesting IV users, the narrow IV will be isolated for removal by /// DeleteDeadPHIs. /// /// It would be simpler to delete uses as they are processed, but we must avoid /// invalidating SCEV expressions. /// -bool WidenIV::CreateWideIV(SCEVExpander &Rewriter) { +PHINode *WidenIV::CreateWideIV(SCEVExpander &Rewriter) { // Is this phi an induction variable? const SCEVAddRecExpr *AddRec = dyn_cast(SE->getSCEV(OrigPhi)); if (!AddRec) - return false; + return NULL; // Widen the induction variable expression. const SCEV *WideIVExpr = IsSigned ? @@ -846,9 +847,9 @@ // Can the IV be extended outside the loop without overflow? AddRec = dyn_cast(WideIVExpr); if (!AddRec || AddRec->getLoop() != L) - return false; + return NULL; - // An AddRec must have loop-invariant operands. Since this AddRec it + // An AddRec must have loop-invariant operands. Since this AddRec is // materialized by a loop header phi, the expression cannot have any post-loop // operands, so they must dominate the loop header. assert(SE->properlyDominates(AddRec->getStart(), L->getHeader()) && @@ -876,7 +877,7 @@ ++NumWidened; // Traverse the def-use chain using a worklist starting at the original IV. - assert(Processed.empty() && "expect initial state" ); + assert(Widened.empty() && "expect initial state" ); // Each worklist entry has a Narrow def-use link and Wide def. SmallVector, 8> NarrowIVUsers; @@ -906,7 +907,7 @@ if (NarrowDef->use_empty()) DeadInsts.push_back(NarrowDef); } - return true; + return WidePhi; } void IndVarSimplify::EliminateIVComparison(ICmpInst *ICmp, Value *IVOperand) { @@ -989,15 +990,144 @@ } // Inform IVUsers about the new users. - if (Instruction *I = dyn_cast(Rem->getOperand(0))) - IU->AddUsersIfInteresting(I, IVPhi); - + if (IU) { + if (Instruction *I = dyn_cast(Rem->getOperand(0))) + IU->AddUsersIfInteresting(I, IVPhi); + } DEBUG(dbgs() << "INDVARS: Simplified rem: " << *Rem << '\n'); ++NumElimRem; Changed = true; DeadInsts.push_back(Rem); } +/// EliminateIVUser - Eliminate an operation that consumes a simple IV and has +/// no observable side-effect given the range of IV values. +bool IndVarSimplify::EliminateIVUser(Instruction *UseInst, + Instruction *IVOperand) { + if (ICmpInst *ICmp = dyn_cast(UseInst)) { + EliminateIVComparison(ICmp, IVOperand); + return true; + } + if (BinaryOperator *Rem = dyn_cast(UseInst)) { + bool IsSigned = Rem->getOpcode() == Instruction::SRem; + if (IsSigned || Rem->getOpcode() == Instruction::URem) { + EliminateIVRemainder(Rem, IVOperand, IsSigned, CurrIV); + return true; + } + } + + // Eliminate any operation that SCEV can prove is an identity function. + if (!SE->isSCEVable(UseInst->getType()) || + (SE->getSCEV(UseInst) != SE->getSCEV(IVOperand))) + return false; + + UseInst->replaceAllUsesWith(IVOperand); + + DEBUG(dbgs() << "INDVARS: Eliminated identity: " << *UseInst << '\n'); + ++NumElimIdentity; + Changed = true; + DeadInsts.push_back(UseInst); + return true; +} + +/// pushIVUsers - Add all uses of Def to the current IV's worklist. +/// +void IndVarSimplify::pushIVUsers(Instruction *Def) { + + for (Value::use_iterator UI = Def->use_begin(), E = Def->use_end(); + UI != E; ++UI) { + Instruction *User = cast(*UI); + + // Avoid infinite or exponential worklist processing. + // Also ensure unique worklist users. + if (Simplified.insert(User)) + SimpleIVUsers.push_back(std::make_pair(User, Def)); + } +} + +/// isSimpleIVUser - Return true if this instruction generates a simple SCEV +/// expression in terms of that IV. +/// +/// This is similar to IVUsers' isInsteresting() but processes each instruction +/// non-recursively when the operand is already known to be a simpleIVUser. +/// +bool IndVarSimplify::isSimpleIVUser(Instruction *I, const Loop *L) { + if (!SE->isSCEVable(I->getType())) + return false; + + // Get the symbolic expression for this instruction. + const SCEV *S = SE->getSCEV(I); + + // Only consider affine recurrences. + const SCEVAddRecExpr *AR = dyn_cast(S); + if (AR && AR->getLoop() == L) + return true; + + return false; +} + +/// SimplifyIVUsersNoRewrite - Iteratively perform simplification on a worklist +/// of IV users. Each successive simplification may push more users which may +/// themselves be candidates for simplification. +/// +/// The "NoRewrite" algorithm does not require IVUsers analysis. Instead, it +/// simplifies instructions in-place during analysis. Rather than rewriting +/// induction variables bottom-up from their users, it transforms a chain of +/// IVUsers top-down, updating the IR only when it encouters a clear +/// optimization opportunitiy. A SCEVExpander "Rewriter" instance is still +/// needed, but only used to generate a new IV (phi) of wider type for sign/zero +/// extend elimination. +/// +/// Once DisableIVRewrite is default, LSR will be the only client of IVUsers. +/// +void IndVarSimplify::SimplifyIVUsersNoRewrite(Loop *L, SCEVExpander &Rewriter) { + // Simplification is performed independently for each IV, as represented by a + // loop header phi. Each round of simplification first iterates through the + // SimplifyIVUsers worklist, then determines whether the current IV should be + // widened. Widening adds a new phi to LoopPhis, inducing another round of + // simplification on the wide IV. + SmallVector LoopPhis; + for (BasicBlock::iterator I = L->getHeader()->begin(); isa(I); ++I) { + LoopPhis.push_back(cast(I)); + } + while (!LoopPhis.empty()) { + CurrIV = LoopPhis.pop_back_val(); + Simplified.clear(); + assert(SimpleIVUsers.empty() && "expect empty IV users list"); + + WideIVInfo WI; + + pushIVUsers(CurrIV); + + while (!SimpleIVUsers.empty()) { + Instruction *UseInst, *Operand; + tie(UseInst, Operand) = SimpleIVUsers.pop_back_val(); + + if (EliminateIVUser(UseInst, Operand)) { + pushIVUsers(Operand); + continue; + } + if (CastInst *Cast = dyn_cast(UseInst)) { + bool IsSigned = Cast->getOpcode() == Instruction::SExt; + if (IsSigned || Cast->getOpcode() == Instruction::ZExt) { + CollectExtend(Cast, IsSigned, WI, SE, TD); + } + continue; + } + if (isSimpleIVUser(UseInst, L)) { + pushIVUsers(UseInst); + } + } + if (WI.WidestNativeType) { + WidenIV Widener(CurrIV, WI, LI, SE, DT, DeadInsts); + if (PHINode *WidePhi = Widener.CreateWideIV(Rewriter)) { + Changed = true; + LoopPhis.push_back(WidePhi); + } + } + } +} + bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { // If LoopSimplify form is not available, stay out of trouble. Some notes: // - LSR currently only supports LoopSimplify-form loops. Indvars' @@ -1010,12 +1140,15 @@ if (!L->isLoopSimplifyForm()) return false; - IU = &getAnalysis(); + if (!DisableIVRewrite) + IU = &getAnalysis(); LI = &getAnalysis(); SE = &getAnalysis(); DT = &getAnalysis(); TD = getAnalysisIfAvailable(); + CurrIV = NULL; + Simplified.clear(); DeadInsts.clear(); Changed = false; @@ -1040,7 +1173,10 @@ RewriteLoopExitValues(L, Rewriter); // Eliminate redundant IV users. - SimplifyIVUsers(Rewriter); + if (DisableIVRewrite) + SimplifyIVUsersNoRewrite(L, Rewriter); + else + SimplifyIVUsers(Rewriter); // Compute the type of the largest recurrence expression, and decide whether // a canonical induction variable should be inserted. @@ -1146,7 +1282,7 @@ // For completeness, inform IVUsers of the IV use in the newly-created // loop exit test instruction. - if (NewICmp) + if (NewICmp && IU) IU->AddUsersIfInteresting(cast(NewICmp->getOperand(0)), IndVar); @@ -1579,5 +1715,6 @@ } // Add a new IVUsers entry for the newly-created integer PHI. - IU->AddUsersIfInteresting(NewPHI, NewPHI); + if (IU) + IU->AddUsersIfInteresting(NewPHI, NewPHI); } Modified: llvm/trunk/test/Transforms/IndVarSimplify/iv-zext.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/iv-zext.ll?rev=133502&r1=133501&r2=133502&view=diff ============================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/iv-zext.ll (original) +++ llvm/trunk/test/Transforms/IndVarSimplify/iv-zext.ll Mon Jun 20 22:22:38 2011 @@ -1,4 +1,5 @@ ; RUN: opt < %s -indvars -S | FileCheck %s +; RUN: opt < %s -indvars -disable-iv-rewrite -S | FileCheck %s ; CHECK-NOT: and ; CHECK-NOT: zext From nlewycky at google.com Tue Jun 21 00:52:23 2011 From: nlewycky at google.com (Nick Lewycky) Date: Mon, 20 Jun 2011 22:52:23 -0700 Subject: [llvm-commits] patch: fix emission of npot vectors which need trailing padding Message-ID: Hi! This patch fixes an inconsistency that manifests like this: typedef float float3 __attribute__((ext_vector_type(3))); struct Foo { float3 x; float3 y; }; struct Foo foo = { {0, 0, 0}, {1, 2, 3} }; This lowers to a struct with <3 x float>, which TargetData says is 16 bytes on ARM. In LLVM IR, the first element becomes a constant aggregate zero, which is emitted by looking at how many bytes it is (sixteen) and writing out a zero-fill. The second element is emitted as three contiguous elements, resulting in a total of 12 bytes. The StructLayout object claims that each of those should be 16 bytes, so I changed the AsmPrinter in CodeGen to apply padding to the end of an array to match what TargetData thinks the length of the array is. Patch attached, please review! Nick -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110620/3d99b3d8/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: asmprinter-vector-elts-2.patch Type: application/octet-stream Size: 878 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110620/3d99b3d8/attachment.obj From sabre at nondot.org Tue Jun 21 01:00:04 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 20 Jun 2011 23:00:04 -0700 Subject: [llvm-commits] [llvm] r133412 - in /llvm/trunk: include/llvm/Constants.h lib/Analysis/ConstantFolding.cpp lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/CodeGen/ShadowStackGC.cpp lib/Transforms/IPO/GlobalOpt.cpp lib/Transform In-Reply-To: References: Message-ID: <6ACAF514-D83B-46F3-BBD9-13F295FB1FA2@nondot.org> On Jun 20, 2011, at 8:43 AM, Jay Foad wrote: >> It would be "really really nice" if the ConstantStruct::get and >> ConstantVector::get methods didn't make temporary std::vectors. > > How about this then? > > Patch 1 extends ConstantUniqueMap with a new template parameter > ValRefType, representing a const reference to ValType. Normally this > would just be const ValType&, but when ValType is a std::vector, we > want to use ArrayRef as the reference type. > > I had to add a conversion operator to ArrayRef to get this to work. Is > this reasonable? (I've only been using C++ for 15 years so I haven't > really got the hang of it yet.) This also makes the existing > ArrayRef::vec() somewhat redundant, but I didn't remove it. > > Patches 2/3/4 tidy up the get() methods of ConstantVector/Array/Struct > to use ArrayRef throughout. > > Tested with "make all check-all", LLVM and Clang. I don't think > llvm-gcc-4.2 or dragonegg need any changes, based on a quick grep. Wow, looks great to me Jay, you're awesome! -Chris From clattner at apple.com Tue Jun 21 01:01:26 2011 From: clattner at apple.com (Chris Lattner) Date: Mon, 20 Jun 2011 23:01:26 -0700 Subject: [llvm-commits] Adding add.with.overflow intrinsic support to CBackend. In-Reply-To: <528BA51E-6300-4AB0-9EC9-345DC43CDD28@apple.com> References: <20110620143801.6C0D72A6C124@llvm.org> <528BA51E-6300-4AB0-9EC9-345DC43CDD28@apple.com> Message-ID: <64948E02-0090-48D3-8427-72394EF982AF@apple.com> On Jun 20, 2011, at 11:32 AM, Anna Zaks wrote: > Hi, > > Attached is a CBackend patch for review. It adds support for sadd.with.overflow and uadd.with.overflow intrinsics. Essentially, we emit implementation for each add.with.overflow intrinsic that occurs in the module. > > Issues are lack of support for arbitrary size integers and assumption about the two's compliment representation for integers (casts from signed to unsigned and backwards). However, it seems that these are the limitations of the current CBackend implementation as well. > > We know that the CBackend is no longer supported and might get completely rewritten, but this patch removes the known blockers for us and might be useful for someone else as well. Sure, seems reasonable. Please commit, thanks! -Chris From evan.cheng at apple.com Tue Jun 21 01:01:08 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 21 Jun 2011 06:01:08 -0000 Subject: [llvm-commits] [llvm] r133503 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrThumb.td lib/Target/ARM/ARMInstrThumb2.td test/CodeGen/ARM/rev.ll test/CodeGen/X86/bswap.ll Message-ID: <20110621060108.6A5C22A6C12C@llvm.org> Author: evancheng Date: Tue Jun 21 01:01:08 2011 New Revision: 133503 URL: http://llvm.org/viewvc/llvm-project?rev=133503&view=rev Log: Teach dag combine to match halfword byteswap patterns. 1. (((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8) => (bswap x) >> 16 2. ((x&0xff)<<8)|((x&0xff00)>>8)|((x&0xff000000)>>8)|((x&0x00ff0000)<<8)) => (rotl (bswap x) 16) This allows us to eliminate most of the def : Pat patterns for ARM rev16 revsh instructions. It catches many more cases for ARM and x86. rdar://9609108 Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td llvm/trunk/test/CodeGen/ARM/rev.ll llvm/trunk/test/CodeGen/X86/bswap.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=133503&r1=133502&r2=133503&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Jun 21 01:01:08 2011 @@ -238,6 +238,9 @@ SDValue ConstantFoldBITCASTofBUILD_VECTOR(SDNode *, EVT); SDValue BuildSDIV(SDNode *N); SDValue BuildUDIV(SDNode *N); + SDValue MatchBSwapHWordLow(SDNode *N, SDValue N0, SDValue N1, + bool DemandHighBits = true); + SDValue MatchBSwapHWord(SDNode *N, SDValue N0, SDValue N1); SDNode *MatchRotate(SDValue LHS, SDValue RHS, DebugLoc DL); SDValue ReduceLoadWidth(SDNode *N); SDValue ReduceLoadOpStoreWidth(SDNode *N); @@ -2512,6 +2515,244 @@ return SDValue(); } +/// MatchBSwapHWord - Match (a >> 8) | (a << 8) as (bswap a) >> 16 +/// +SDValue DAGCombiner::MatchBSwapHWordLow(SDNode *N, SDValue N0, SDValue N1, + bool DemandHighBits) { + if (!LegalOperations) + return SDValue(); + + EVT VT = N->getValueType(0); + if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16) + return SDValue(); + if (!TLI.isOperationLegal(ISD::BSWAP, VT)) + return SDValue(); + + // Recognize (and (shl a, 8), 0xff), (and (srl a, 8), 0xff00) + bool LookPassAnd0 = false; + bool LookPassAnd1 = false; + if (N0.getOpcode() == ISD::AND && N0.getOperand(0).getOpcode() == ISD::SRL) + std::swap(N0, N1); + if (N1.getOpcode() == ISD::AND && N1.getOperand(0).getOpcode() == ISD::SHL) + std::swap(N0, N1); + if (N0.getOpcode() == ISD::AND) { + if (!N0.getNode()->hasOneUse()) + return SDValue(); + ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); + if (!N01C || N01C->getZExtValue() != 0xFF00) + return SDValue(); + N0 = N0.getOperand(0); + LookPassAnd0 = true; + } + + if (N1.getOpcode() == ISD::AND) { + if (!N1.getNode()->hasOneUse()) + return SDValue(); + ConstantSDNode *N11C = dyn_cast(N1.getOperand(1)); + if (!N11C || N11C->getZExtValue() != 0xFF) + return SDValue(); + N1 = N1.getOperand(0); + LookPassAnd1 = true; + } + + if (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SHL) + std::swap(N0, N1); + if (N0.getOpcode() != ISD::SHL || N1.getOpcode() != ISD::SRL) + return SDValue(); + if (!N0.getNode()->hasOneUse() || + !N1.getNode()->hasOneUse()) + return SDValue(); + + ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); + ConstantSDNode *N11C = dyn_cast(N1.getOperand(1)); + if (!N01C || !N11C) + return SDValue(); + if (N01C->getZExtValue() != 8 || N11C->getZExtValue() != 8) + return SDValue(); + + // Look for (shl (and a, 0xff), 8), (srl (and a, 0xff00), 8) + SDValue N00 = N0->getOperand(0); + if (!LookPassAnd0 && N00.getOpcode() == ISD::AND) { + if (!N00.getNode()->hasOneUse()) + return SDValue(); + ConstantSDNode *N001C = dyn_cast(N00.getOperand(1)); + if (!N001C || N001C->getZExtValue() != 0xFF) + return SDValue(); + N00 = N00.getOperand(0); + LookPassAnd0 = true; + } + + SDValue N10 = N1->getOperand(0); + if (!LookPassAnd1 && N10.getOpcode() == ISD::AND) { + if (!N10.getNode()->hasOneUse()) + return SDValue(); + ConstantSDNode *N101C = dyn_cast(N10.getOperand(1)); + if (!N101C || N101C->getZExtValue() != 0xFF00) + return SDValue(); + N10 = N10.getOperand(0); + LookPassAnd1 = true; + } + + if (N00 != N10) + return SDValue(); + + // Make sure everything beyond the low halfword is zero since the SRL 16 + // will clear the top bits. + unsigned OpSizeInBits = VT.getSizeInBits(); + if (DemandHighBits && OpSizeInBits > 16 && + (!LookPassAnd0 || !LookPassAnd1) && + !DAG.MaskedValueIsZero(N10, APInt::getHighBitsSet(OpSizeInBits, 16))) + return SDValue(); + + SDValue Res = DAG.getNode(ISD::BSWAP, N->getDebugLoc(), VT, N00); + if (OpSizeInBits > 16) + Res = DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, Res, + DAG.getConstant(OpSizeInBits-16, getShiftAmountTy(VT))); + return Res; +} + +/// isBSwapHWordElement - Return true if the specified node is an element +/// that makes up a 32-bit packed halfword byteswap. i.e. +/// ((x&0xff)<<8)|((x&0xff00)>>8)|((x&0x00ff0000)<<8)|((x&0xff000000)>>8) +static bool isBSwapHWordElement(SDValue N, SmallVector &Parts) { + if (!N.getNode()->hasOneUse()) + return false; + + unsigned Opc = N.getOpcode(); + if (Opc != ISD::AND && Opc != ISD::SHL && Opc != ISD::SRL) + return false; + + ConstantSDNode *N1C = dyn_cast(N.getOperand(1)); + if (!N1C) + return false; + + unsigned Num; + switch (N1C->getZExtValue()) { + default: + return false; + case 0xFF: Num = 0; break; + case 0xFF00: Num = 1; break; + case 0xFF0000: Num = 2; break; + case 0xFF000000: Num = 3; break; + } + + // Look for (x & 0xff) << 8 as well as ((x << 8) & 0xff00). + SDValue N0 = N.getOperand(0); + if (Opc == ISD::AND) { + if (Num == 0 || Num == 2) { + // (x >> 8) & 0xff + // (x >> 8) & 0xff0000 + if (N0.getOpcode() != ISD::SRL) + return false; + ConstantSDNode *C = dyn_cast(N0.getOperand(1)); + if (!C || C->getZExtValue() != 8) + return false; + } else { + // (x << 8) & 0xff00 + // (x << 8) & 0xff000000 + if (N0.getOpcode() != ISD::SHL) + return false; + ConstantSDNode *C = dyn_cast(N0.getOperand(1)); + if (!C || C->getZExtValue() != 8) + return false; + } + } else if (Opc == ISD::SHL) { + // (x & 0xff) << 8 + // (x & 0xff0000) << 8 + if (Num != 0 && Num != 2) + return false; + ConstantSDNode *C = dyn_cast(N.getOperand(1)); + if (!C || C->getZExtValue() != 8) + return false; + } else { // Opc == ISD::SRL + // (x & 0xff00) >> 8 + // (x & 0xff000000) >> 8 + if (Num != 1 && Num != 3) + return false; + ConstantSDNode *C = dyn_cast(N.getOperand(1)); + if (!C || C->getZExtValue() != 8) + return false; + } + + if (Parts[Num]) + return false; + + Parts[Num] = N0.getOperand(0).getNode(); + return true; +} + +/// MatchBSwapHWord - Match a 32-bit packed halfword bswap. That is +/// ((x&0xff)<<8)|((x&0xff00)>>8)|((x&0x00ff0000)<<8)|((x&0xff000000)>>8) +/// => (rotl (bswap x), 16) +SDValue DAGCombiner::MatchBSwapHWord(SDNode *N, SDValue N0, SDValue N1) { + if (!LegalOperations) + return SDValue(); + + EVT VT = N->getValueType(0); + if (VT != MVT::i32) + return SDValue(); + if (!TLI.isOperationLegal(ISD::BSWAP, VT)) + return SDValue(); + + SmallVector Parts(4, (SDNode*)0); + // Look for either + // (or (or (and), (and)), (or (and), (and))) + // (or (or (or (and), (and)), (and)), (and)) + if (N0.getOpcode() != ISD::OR) + return SDValue(); + SDValue N00 = N0.getOperand(0); + SDValue N01 = N0.getOperand(1); + + if (N1.getOpcode() == ISD::OR) { + // (or (or (and), (and)), (or (and), (and))) + SDValue N000 = N00.getOperand(0); + if (!isBSwapHWordElement(N000, Parts)) + return SDValue(); + + SDValue N001 = N00.getOperand(1); + if (!isBSwapHWordElement(N001, Parts)) + return SDValue(); + SDValue N010 = N01.getOperand(0); + if (!isBSwapHWordElement(N010, Parts)) + return SDValue(); + SDValue N011 = N01.getOperand(1); + if (!isBSwapHWordElement(N011, Parts)) + return SDValue(); + } else { + // (or (or (or (and), (and)), (and)), (and)) + if (!isBSwapHWordElement(N1, Parts)) + return SDValue(); + if (!isBSwapHWordElement(N01, Parts)) + return SDValue(); + if (N00.getOpcode() != ISD::OR) + return SDValue(); + SDValue N000 = N00.getOperand(0); + if (!isBSwapHWordElement(N000, Parts)) + return SDValue(); + SDValue N001 = N00.getOperand(1); + if (!isBSwapHWordElement(N001, Parts)) + return SDValue(); + } + + // Make sure the parts are all coming from the same node. + if (Parts[0] != Parts[1] || Parts[0] != Parts[2] || Parts[0] != Parts[3]) + return SDValue(); + + SDValue BSwap = DAG.getNode(ISD::BSWAP, N->getDebugLoc(), VT, + SDValue(Parts[0],0)); + + // Result of the bswap should be rotated by 16. If it's not legal, than + // do (x << 16) | (x >> 16). + SDValue ShAmt = DAG.getConstant(16, getShiftAmountTy(VT)); + if (TLI.isOperationLegalOrCustom(ISD::ROTL, VT)) + return DAG.getNode(ISD::ROTL, N->getDebugLoc(), VT, BSwap, ShAmt); + else if (TLI.isOperationLegalOrCustom(ISD::ROTR, VT)) + return DAG.getNode(ISD::ROTR, N->getDebugLoc(), VT, BSwap, ShAmt); + return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, + DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, BSwap, ShAmt), + DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, BSwap, ShAmt)); +} + SDValue DAGCombiner::visitOR(SDNode *N) { SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); @@ -2547,6 +2788,15 @@ // fold (or x, c) -> c iff (x & ~c) == 0 if (N1C && DAG.MaskedValueIsZero(N0, ~N1C->getAPIntValue())) return N1; + + // Recognize halfword bswaps as (bswap + rotl 16) or (bswap + shl 16) + SDValue BSwap = MatchBSwapHWord(N, N0, N1); + if (BSwap.getNode() != 0) + return BSwap; + BSwap = MatchBSwapHWordLow(N, N0, N1); + if (BSwap.getNode() != 0) + return BSwap; + // reassociate or SDValue ROR = ReassociateOps(ISD::OR, N->getDebugLoc(), N0, N1); if (ROR.getNode() != 0) @@ -4606,6 +4856,16 @@ CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! } + + // Form (sext_inreg (bswap >> 16)) or (sext_inreg (rotl (bswap) 16)) + if (EVTBits <= 16 && N0.getOpcode() == ISD::OR) { + SDValue BSwap = MatchBSwapHWordLow(N0.getNode(), N0.getOperand(0), + N0.getOperand(1), false); + if (BSwap.getNode() != 0) + return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), VT, + BSwap, N1); + } + return SDValue(); } @@ -5231,7 +5491,8 @@ // fold (sint_to_fp c1) -> c1fp if (N0C && OpVT != MVT::ppcf128 && // ...but only if the target supports immediate floating-point values - (Level == llvm::Unrestricted || TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) + (Level == llvm::Unrestricted || + TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) return DAG.getNode(ISD::SINT_TO_FP, N->getDebugLoc(), VT, N0); // If the input is a legal type, and SINT_TO_FP is not legal on this target, @@ -5255,7 +5516,8 @@ // fold (uint_to_fp c1) -> c1fp if (N0C && OpVT != MVT::ppcf128 && // ...but only if the target supports immediate floating-point values - (Level == llvm::Unrestricted || TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) + (Level == llvm::Unrestricted || + TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) return DAG.getNode(ISD::UINT_TO_FP, N->getDebugLoc(), VT, N0); // If the input is a legal type, and UINT_TO_FP is not legal on this target, Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=133503&r1=133502&r2=133503&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Jun 21 01:01:08 2011 @@ -3008,41 +3008,22 @@ IIC_iUNAr, "rev", "\t$Rd, $Rm", [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>; +let AddedComplexity = 5 in def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm), IIC_iUNAr, "rev16", "\t$Rd, $Rm", - [(set GPR:$Rd, - (or (and (srl GPR:$Rm, (i32 8)), 0xFF), - (or (and (shl GPR:$Rm, (i32 8)), 0xFF00), - (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000), - (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>, + [(set GPR:$Rd, (rotr (bswap GPR:$Rm), (i32 16)))]>, Requires<[IsARM, HasV6]>; -def : ARMV6Pat<(or (or (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000), - (and (shl GPR:$Rm, (i32 8)), 0xFF000000)), - (and (srl GPR:$Rm, (i32 8)), 0xFF)), - (and (shl GPR:$Rm, (i32 8)), 0xFF00)), - (REV16 GPR:$Rm)>; - +let AddedComplexity = 5 in def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm), IIC_iUNAr, "revsh", "\t$Rd, $Rm", - [(set GPR:$Rd, - (sext_inreg - (or (srl GPR:$Rm, (i32 8)), - (shl GPR:$Rm, (i32 8))), i16))]>, + [(set GPR:$Rd, (sra (bswap GPR:$Rm), (i32 16)))]>, Requires<[IsARM, HasV6]>; -def : ARMV6Pat<(sext_inreg (or (srl (and GPR:$Rm, 0xFF00), (i32 8)), - (shl GPR:$Rm, (i32 8))), i16), - (REVSH GPR:$Rm)>; - def : ARMV6Pat<(or (sra (shl GPR:$Rm, (i32 24)), (i32 16)), (and (srl GPR:$Rm, (i32 8)), 0xFF)), (REVSH GPR:$Rm)>; -// Need the AddedComplexity or else MOVs + REV would be chosen. -let AddedComplexity = 5 in -def : ARMV6Pat<(sra (bswap GPR:$Rm), (i32 16)), (REVSH GPR:$Rm)>; - def lsl_shift_imm : SDNodeXFormgetZExtValue()); return CurDAG->getTargetConstant(Sh, MVT::i32); Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=133503&r1=133502&r2=133503&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Jun 21 01:01:08 2011 @@ -1176,31 +1176,16 @@ T1pIMiscEncode<{1,0,1,0,0,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iUNAr, "rev16", "\t$Rd, $Rm", - [(set tGPR:$Rd, - (or (and (srl tGPR:$Rm, (i32 8)), 0xFF), - (or (and (shl tGPR:$Rm, (i32 8)), 0xFF00), - (or (and (srl tGPR:$Rm, (i32 8)), 0xFF0000), - (and (shl tGPR:$Rm, (i32 8)), 0xFF000000)))))]>, + [(set tGPR:$Rd, (rotr (bswap tGPR:$Rm), (i32 16)))]>, Requires<[IsThumb, IsThumb1Only, HasV6]>; def tREVSH : // A8.6.136 T1pIMiscEncode<{1,0,1,0,1,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iUNAr, "revsh", "\t$Rd, $Rm", - [(set tGPR:$Rd, - (sext_inreg - (or (srl tGPR:$Rm, (i32 8)), - (shl tGPR:$Rm, (i32 8))), i16))]>, + [(set tGPR:$Rd, (sra (bswap tGPR:$Rm), (i32 16)))]>, Requires<[IsThumb, IsThumb1Only, HasV6]>; -def : T1Pat<(sext_inreg (or (srl (and tGPR:$Rm, 0xFF00), (i32 8)), - (shl tGPR:$Rm, (i32 8))), i16), - (tREVSH tGPR:$Rm)>, - Requires<[IsThumb, IsThumb1Only, HasV6]>; - -def : T1Pat<(sra (bswap tGPR:$Rm), (i32 16)), (tREVSH tGPR:$Rm)>, - Requires<[IsThumb, IsThumb1Only, HasV6]>; - // Rotate right register def tROR : // A8.6.139 T1sItDPEncode<0b0111, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=133503&r1=133502&r2=133503&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Tue Jun 21 01:01:08 2011 @@ -2587,35 +2587,16 @@ def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr, "rev16", ".w\t$Rd, $Rm", - [(set rGPR:$Rd, - (or (and (srl rGPR:$Rm, (i32 8)), 0xFF), - (or (and (shl rGPR:$Rm, (i32 8)), 0xFF00), - (or (and (srl rGPR:$Rm, (i32 8)), 0xFF0000), - (and (shl rGPR:$Rm, (i32 8)), 0xFF000000)))))]>; - -def : T2Pat<(or (or (or (and (srl rGPR:$Rm, (i32 8)), 0xFF0000), - (and (shl rGPR:$Rm, (i32 8)), 0xFF000000)), - (and (srl rGPR:$Rm, (i32 8)), 0xFF)), - (and (shl rGPR:$Rm, (i32 8)), 0xFF00)), - (t2REV16 rGPR:$Rm)>; + [(set rGPR:$Rd, (rotr (bswap rGPR:$Rm), (i32 16)))]>; def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr, "revsh", ".w\t$Rd, $Rm", - [(set rGPR:$Rd, - (sext_inreg - (or (srl rGPR:$Rm, (i32 8)), - (shl rGPR:$Rm, (i32 8))), i16))]>; - -def : T2Pat<(sext_inreg (or (srl (and rGPR:$Rm, 0xFF00), (i32 8)), - (shl rGPR:$Rm, (i32 8))), i16), - (t2REVSH rGPR:$Rm)>; + [(set rGPR:$Rd, (sra (bswap rGPR:$Rm), (i32 16)))]>; def : T2Pat<(or (sra (shl rGPR:$Rm, (i32 24)), (i32 16)), - (and (srl rGPR:$Rm, (i32 8)), 0xFF)), + (and (srl rGPR:$Rm, (i32 8)), 0xFF)), (t2REVSH rGPR:$Rm)>; -def : T2Pat<(sra (bswap rGPR:$Rm), (i32 16)), (t2REVSH rGPR:$Rm)>; - def t2PKHBT : T2ThreeReg< (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh), IIC_iBITsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh", Modified: llvm/trunk/test/CodeGen/ARM/rev.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/rev.ll?rev=133503&r1=133502&r2=133503&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/rev.ll (original) +++ llvm/trunk/test/CodeGen/ARM/rev.ll Tue Jun 21 01:01:08 2011 @@ -84,3 +84,43 @@ %or10 = or i32 %or6, %shl ret i32 %or10 } + +; rdar://9164521 +define i32 @test7(i32 %a) nounwind readnone { +entry: +; CHECK: test7 +; CHECK: rev r0, r0 +; CHECK: lsr r0, r0, #16 + %and = lshr i32 %a, 8 + %shr3 = and i32 %and, 255 + %and2 = shl i32 %a, 8 + %shl = and i32 %and2, 65280 + %or = or i32 %shr3, %shl + ret i32 %or +} + +define i32 @test8(i32 %a) nounwind readnone { +entry: +; CHECK: test8 +; CHECK: revsh r0, r0 + %and = lshr i32 %a, 8 + %shr4 = and i32 %and, 255 + %and2 = shl i32 %a, 8 + %or = or i32 %shr4, %and2 + %sext = shl i32 %or, 16 + %conv3 = ashr exact i32 %sext, 16 + ret i32 %conv3 +} + +define zeroext i16 @test9(i16 zeroext %v) nounwind readnone { +entry: +; CHECK: test9 +; CHECK: rev r0, r0 +; CHECK: lsr r0, r0, #16 + %conv = zext i16 %v to i32 + %shr4 = lshr i32 %conv, 8 + %shl = shl nuw nsw i32 %conv, 8 + %or = or i32 %shr4, %shl + %conv3 = trunc i32 %or to i16 + ret i16 %conv3 +} Modified: llvm/trunk/test/CodeGen/X86/bswap.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bswap.ll?rev=133503&r1=133502&r2=133503&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/bswap.ll (original) +++ llvm/trunk/test/CodeGen/X86/bswap.ll Tue Jun 21 01:01:08 2011 @@ -1,8 +1,6 @@ ; bswap should be constant folded when it is passed a constant argument -; RUN: llc < %s -march=x86 | \ -; RUN: grep bswapl | count 3 -; RUN: llc < %s -march=x86 | grep rolw | count 1 +; RUN: llc < %s -march=x86 | FileCheck %s declare i16 @llvm.bswap.i16(i16) @@ -11,17 +9,51 @@ declare i64 @llvm.bswap.i64(i64) define i16 @W(i16 %A) { +; CHECK: W: +; CHECK: rolw $8, %ax %Z = call i16 @llvm.bswap.i16( i16 %A ) ; [#uses=1] ret i16 %Z } define i32 @X(i32 %A) { +; CHECK: X: +; CHECK: bswapl %eax %Z = call i32 @llvm.bswap.i32( i32 %A ) ; [#uses=1] ret i32 %Z } define i64 @Y(i64 %A) { +; CHECK: Y: +; CHECK: bswapl %eax +; CHECK: bswapl %edx %Z = call i64 @llvm.bswap.i64( i64 %A ) ; [#uses=1] ret i64 %Z } +; rdar://9164521 +define i32 @test1(i32 %a) nounwind readnone { +entry: +; CHECK: test1 +; CHECK: bswapl %eax +; CHECK: shrl $16, %eax + %and = lshr i32 %a, 8 + %shr3 = and i32 %and, 255 + %and2 = shl i32 %a, 8 + %shl = and i32 %and2, 65280 + %or = or i32 %shr3, %shl + ret i32 %or +} + +define i32 @test2(i32 %a) nounwind readnone { +entry: +; CHECK: test2 +; CHECK: bswapl %eax +; CHECK: sarl $16, %eax + %and = lshr i32 %a, 8 + %shr4 = and i32 %and, 255 + %and2 = shl i32 %a, 8 + %or = or i32 %shr4, %and2 + %sext = shl i32 %or, 16 + %conv3 = ashr exact i32 %sext, 16 + ret i32 %conv3 +} From sabre at nondot.org Tue Jun 21 01:22:34 2011 From: sabre at nondot.org (Chris Lattner) Date: Tue, 21 Jun 2011 06:22:34 -0000 Subject: [llvm-commits] [llvm] r133504 - /llvm/trunk/include/llvm/ADT/StringMap.h Message-ID: <20110621062234.20F6E2A6C12C@llvm.org> Author: lattner Date: Tue Jun 21 01:22:33 2011 New Revision: 133504 URL: http://llvm.org/viewvc/llvm-project?rev=133504&view=rev Log: use the MapEntryTy typedef instead of writing it out long form, add some fixme's about methods that should be removed. Merged from type-system-rewrite. Modified: llvm/trunk/include/llvm/ADT/StringMap.h Modified: llvm/trunk/include/llvm/ADT/StringMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringMap.h?rev=133504&r1=133503&r2=133504&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringMap.h (original) +++ llvm/trunk/include/llvm/ADT/StringMap.h Tue Jun 21 01:22:33 2011 @@ -307,7 +307,7 @@ return ValueTy(); } - ValueTy& operator[](StringRef Key) { + ValueTy &operator[](StringRef Key) { return GetOrCreateValue(Key).getValue(); } @@ -355,8 +355,7 @@ /// exists, return it. Otherwise, default construct a value, insert it, and /// return. template - StringMapEntry &GetOrCreateValue(StringRef Key, - InitTy Val) { + MapEntryTy &GetOrCreateValue(StringRef Key, InitTy Val) { unsigned BucketNo = LookupBucketFor(Key); ItemBucket &Bucket = TheTable[BucketNo]; if (Bucket.Item && Bucket.Item != getTombstoneVal()) @@ -378,19 +377,19 @@ return *NewItem; } - StringMapEntry &GetOrCreateValue(StringRef Key) { + MapEntryTy &GetOrCreateValue(StringRef Key) { return GetOrCreateValue(Key, ValueTy()); } + // FIXME: Remove this method. template - StringMapEntry &GetOrCreateValue(const char *KeyStart, - const char *KeyEnd, - InitTy Val) { + MapEntryTy &GetOrCreateValue(const char *KeyStart, const char *KeyEnd, + InitTy Val) { return GetOrCreateValue(StringRef(KeyStart, KeyEnd - KeyStart), Val); } - StringMapEntry &GetOrCreateValue(const char *KeyStart, - const char *KeyEnd) { + // FIXME: Remove this method. + MapEntryTy &GetOrCreateValue(const char *KeyStart, const char *KeyEnd) { return GetOrCreateValue(StringRef(KeyStart, KeyEnd - KeyStart)); } From clattner at apple.com Tue Jun 21 01:56:25 2011 From: clattner at apple.com (Chris Lattner) Date: Mon, 20 Jun 2011 23:56:25 -0700 Subject: [llvm-commits] [llvm] r133503 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrThumb.td lib/Target/ARM/ARMInstrThumb2.td test/CodeGen/ARM/rev.ll test/CodeGen/X86/bswap.ll In-Reply-To: <20110621060108.6A5C22A6C12C@llvm.org> References: <20110621060108.6A5C22A6C12C@llvm.org> Message-ID: On Jun 20, 2011, at 11:01 PM, Evan Cheng wrote: > Author: evancheng > Date: Tue Jun 21 01:01:08 2011 > New Revision: 133503 > > URL: http://llvm.org/viewvc/llvm-project?rev=133503&view=rev > Log: > Teach dag combine to match halfword byteswap patterns. > 1. (((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8) > => (bswap x) >> 16 > 2. ((x&0xff)<<8)|((x&0xff00)>>8)|((x&0xff000000)>>8)|((x&0x00ff0000)<<8)) > => (rotl (bswap x) 16) > > This allows us to eliminate most of the def : Pat patterns for ARM rev16 > revsh instructions. It catches many more cases for ARM and x86. Nice! -Chris From jay.foad at gmail.com Tue Jun 21 02:22:18 2011 From: jay.foad at gmail.com (Jay Foad) Date: Tue, 21 Jun 2011 08:22:18 +0100 Subject: [llvm-commits] [llvm] r133412 - in /llvm/trunk: include/llvm/Constants.h lib/Analysis/ConstantFolding.cpp lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/CodeGen/ShadowStackGC.cpp lib/Transforms/IPO/GlobalOpt.cpp lib/Transform In-Reply-To: <6ACAF514-D83B-46F3-BBD9-13F295FB1FA2@nondot.org> References: <6ACAF514-D83B-46F3-BBD9-13F295FB1FA2@nondot.org> Message-ID: >> Patch 1 extends ConstantUniqueMap with a new template parameter >> ValRefType, representing a const reference to ValType. Normally this >> would just be const ValType&, but when ValType is a std::vector, we >> want to use ArrayRef as the reference type. > Wow, looks great to me Jay Just to double check, are you OK with me adding the conversion operator ArrayRef::operator std::vector() const; And should I remove the now redundant method which just did the same thing: std::vector ArrayRef::vec() const; ? Thanks, Jay. From jay.foad at gmail.com Tue Jun 21 03:33:49 2011 From: jay.foad at gmail.com (Jay Foad) Date: Tue, 21 Jun 2011 08:33:49 -0000 Subject: [llvm-commits] [llvm] r133509 - /llvm/trunk/test/Transforms/LoopDeletion/2011-06-21-phioperands.ll Message-ID: <20110621083349.391362A6C12C@llvm.org> Author: foad Date: Tue Jun 21 03:33:49 2011 New Revision: 133509 URL: http://llvm.org/viewvc/llvm-project?rev=133509&view=rev Log: Add a reduced test case for the buildbot failure (clang self-hosted build) caused by r133435. Added: llvm/trunk/test/Transforms/LoopDeletion/2011-06-21-phioperands.ll Added: llvm/trunk/test/Transforms/LoopDeletion/2011-06-21-phioperands.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopDeletion/2011-06-21-phioperands.ll?rev=133509&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopDeletion/2011-06-21-phioperands.ll (added) +++ llvm/trunk/test/Transforms/LoopDeletion/2011-06-21-phioperands.ll Tue Jun 21 03:33:49 2011 @@ -0,0 +1,182 @@ +; RUN: opt %s -loop-deletion -disable-output + +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" + +%0 = type { %"class.llvm::SmallVectorImpl", [1 x %"union.llvm::SmallVectorBase::U"] } +%"class.clang::SourceLocation" = type { i32 } +%"class.clang::driver::Arg" = type { %"class.clang::driver::Option"*, %"class.clang::driver::Arg"*, i32, i8, %0 } +%"class.clang::driver::Option" = type { i32 (...)**, i32, %"class.clang::SourceLocation", i8*, %"class.clang::driver::OptionGroup"*, %"class.clang::driver::Option"*, i8 } +%"class.clang::driver::OptionGroup" = type { %"class.clang::driver::Option" } +%"class.llvm::SmallVectorBase" = type { i8*, i8*, i8*, %"union.llvm::SmallVectorBase::U" } +%"class.llvm::SmallVectorImpl" = type { %"class.llvm::SmallVectorTemplateBase" } +%"class.llvm::SmallVectorTemplateBase" = type { %"class.llvm::SmallVectorTemplateCommon" } +%"class.llvm::SmallVectorTemplateCommon" = type { %"class.llvm::SmallVectorBase" } +%"union.llvm::SmallVectorBase::U" = type { x86_fp80 } + +define void @_ZNK5clang6driver7ArgList20AddAllArgsTranslatedERN4llvm11SmallVectorIPKcLj16EEENS0_12OptSpecifierES5_b(i1 zeroext %Joined) nounwind align 2 { +entry: + br i1 undef, label %entry.split.us, label %entry.entry.split_crit_edge + +entry.entry.split_crit_edge: ; preds = %entry + br label %entry.split + +entry.split.us: ; preds = %entry + br label %for.cond.i14.us + +for.cond.i14.us: ; preds = %for.inc.i38.us, %entry.split.us + br i1 true, label %for.cond.i50.us-lcssa.us, label %if.end.i23.us + +for.inc.i38.us: ; preds = %if.end.i23.us + br label %for.cond.i14.us + +if.end.i23.us: ; preds = %for.cond.i14.us + br i1 true, label %for.cond.i50.us-lcssa.us, label %for.inc.i38.us + +for.cond.i50.us-lcssa.us: ; preds = %if.end.i23.us, %for.cond.i14.us + br label %for.cond.i50 + +entry.split: ; preds = %entry.entry.split_crit_edge + br label %for.cond.i14 + +for.cond.i14: ; preds = %for.inc.i38, %entry.split + br i1 undef, label %for.cond.i50.us-lcssa, label %if.end.i23 + +if.end.i23: ; preds = %for.cond.i14 + br i1 undef, label %for.cond.i50.us-lcssa, label %for.inc.i38 + +for.inc.i38: ; preds = %if.end.i23 + br label %for.cond.i14 + +for.cond.i50.us-lcssa: ; preds = %if.end.i23, %for.cond.i14 + br label %for.cond.i50 + +for.cond.i50: ; preds = %for.cond.i50.us-lcssa, %for.cond.i50.us-lcssa.us + br label %for.cond + +for.cond.loopexit.us-lcssa: ; preds = %if.end.i, %for.cond.i + br label %for.cond.loopexit + +for.cond.loopexit: ; preds = %for.cond.loopexit.us-lcssa.us, %for.cond.loopexit.us-lcssa + br label %for.cond + +for.cond: ; preds = %for.cond.loopexit, %for.cond.i50 + br i1 undef, label %for.end, label %for.body + +for.body: ; preds = %for.cond + br i1 %Joined, label %if.then, label %if.else + +if.then: ; preds = %for.body + br i1 undef, label %cond.false.i.i, label %_ZN4llvm9StringRefC1EPKc.exit + +cond.false.i.i: ; preds = %if.then + unreachable + +_ZN4llvm9StringRefC1EPKc.exit: ; preds = %if.then + br i1 undef, label %_ZNK5clang6driver3Arg8getValueERKNS0_7ArgListEj.exit, label %cond.false.i.i91 + +cond.false.i.i91: ; preds = %_ZN4llvm9StringRefC1EPKc.exit + unreachable + +_ZNK5clang6driver3Arg8getValueERKNS0_7ArgListEj.exit: ; preds = %_ZN4llvm9StringRefC1EPKc.exit + br i1 undef, label %cond.false.i.i.i, label %if.end13.i.i.i.i + +if.end13.i.i.i.i: ; preds = %_ZNK5clang6driver3Arg8getValueERKNS0_7ArgListEj.exit + br i1 undef, label %land.lhs.true16.i.i.i.i, label %if.end19.i.i.i.i + +land.lhs.true16.i.i.i.i: ; preds = %if.end13.i.i.i.i + br i1 undef, label %cond.false.i.i.i, label %_ZNK4llvm5Twine8isBinaryEv.exit8.i.i.i.i + +_ZNK4llvm5Twine8isBinaryEv.exit8.i.i.i.i: ; preds = %land.lhs.true16.i.i.i.i + br i1 undef, label %cond.false.i.i.i, label %if.end19.i.i.i.i + +if.end19.i.i.i.i: ; preds = %_ZNK4llvm5Twine8isBinaryEv.exit8.i.i.i.i, %if.end13.i.i.i.i + br i1 undef, label %land.lhs.true22.i.i.i.i, label %_ZN4llvmplERKNS_9StringRefEPKc.exit + +land.lhs.true22.i.i.i.i: ; preds = %if.end19.i.i.i.i + br i1 undef, label %cond.false.i.i.i, label %_ZNK4llvm5Twine8isBinaryEv.exit.i.i.i.i + +_ZNK4llvm5Twine8isBinaryEv.exit.i.i.i.i: ; preds = %land.lhs.true22.i.i.i.i + br i1 undef, label %cond.false.i.i.i, label %_ZN4llvmplERKNS_9StringRefEPKc.exit + +cond.false.i.i.i: ; preds = %_ZNK4llvm5Twine8isBinaryEv.exit.i.i.i.i, %land.lhs.true22.i.i.i.i, %_ZNK4llvm5Twine8isBinaryEv.exit8.i.i.i.i, %land.lhs.true16.i.i.i.i, %_ZNK5clang6driver3Arg8getValueERKNS0_7ArgListEj.exit + unreachable + +_ZN4llvmplERKNS_9StringRefEPKc.exit: ; preds = %_ZNK4llvm5Twine8isBinaryEv.exit.i.i.i.i, %if.end19.i.i.i.i + br i1 undef, label %Retry.i, label %if.end.i99 + +Retry.i: ; preds = %if.end.i99, %_ZN4llvmplERKNS_9StringRefEPKc.exit + br i1 undef, label %_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit, label %new.notnull.i + +new.notnull.i: ; preds = %Retry.i + br label %_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit + +if.end.i99: ; preds = %_ZN4llvmplERKNS_9StringRefEPKc.exit + br label %Retry.i + +_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit: ; preds = %new.notnull.i, %Retry.i + br label %for.cond.i.preheader + +if.else: ; preds = %for.body + br i1 undef, label %Retry.i108, label %if.end.i113 + +Retry.i108: ; preds = %if.end.i113, %if.else + br i1 undef, label %_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit114, label %new.notnull.i110 + +new.notnull.i110: ; preds = %Retry.i108 + br label %_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit114 + +if.end.i113: ; preds = %if.else + br label %Retry.i108 + +_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit114: ; preds = %new.notnull.i110, %Retry.i108 + br i1 undef, label %_ZNK5clang6driver3Arg8getValueERKNS0_7ArgListEj.exit125, label %cond.false.i.i123 + +cond.false.i.i123: ; preds = %_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit114 + unreachable + +_ZNK5clang6driver3Arg8getValueERKNS0_7ArgListEj.exit125: ; preds = %_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit114 + br i1 undef, label %Retry.i134, label %if.end.i139 + +Retry.i134: ; preds = %if.end.i139, %_ZNK5clang6driver3Arg8getValueERKNS0_7ArgListEj.exit125 + br i1 undef, label %_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit140, label %new.notnull.i136 + +new.notnull.i136: ; preds = %Retry.i134 + br label %_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit140 + +if.end.i139: ; preds = %_ZNK5clang6driver3Arg8getValueERKNS0_7ArgListEj.exit125 + br label %Retry.i134 + +_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit140: ; preds = %new.notnull.i136, %Retry.i134 + br label %for.cond.i.preheader + +for.cond.i.preheader: ; preds = %_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit140, %_ZN4llvm15SmallVectorImplIPKcE9push_backERKS2_.exit + br i1 undef, label %for.cond.i.preheader.split.us, label %for.cond.i.preheader.for.cond.i.preheader.split_crit_edge + +for.cond.i.preheader.for.cond.i.preheader.split_crit_edge: ; preds = %for.cond.i.preheader + br label %for.cond.i.preheader.split + +for.cond.i.preheader.split.us: ; preds = %for.cond.i.preheader + br label %for.cond.i.us + +for.cond.i.us: ; preds = %if.end.i.us, %for.cond.i.preheader.split.us + br i1 true, label %for.cond.loopexit.us-lcssa.us, label %if.end.i.us + +if.end.i.us: ; preds = %for.cond.i.us + br i1 true, label %for.cond.loopexit.us-lcssa.us, label %for.cond.i.us + +for.cond.loopexit.us-lcssa.us: ; preds = %if.end.i.us, %for.cond.i.us + %tmp178218.us.lcssa = phi %"class.clang::driver::Arg"** [ undef, %if.end.i.us ], [ undef, %for.cond.i.us ] + br label %for.cond.loopexit + +for.cond.i.preheader.split: ; preds = %for.cond.i.preheader.for.cond.i.preheader.split_crit_edge + br label %for.cond.i + +for.cond.i: ; preds = %if.end.i, %for.cond.i.preheader.split + br i1 undef, label %for.cond.loopexit.us-lcssa, label %if.end.i + +if.end.i: ; preds = %for.cond.i + br i1 undef, label %for.cond.loopexit.us-lcssa, label %for.cond.i + +for.end: ; preds = %for.cond + ret void +} From renato.golin at arm.com Tue Jun 21 03:45:09 2011 From: renato.golin at arm.com (Renato Golin) Date: Tue, 21 Jun 2011 09:45:09 +0100 Subject: [llvm-commits] patch: fix emission of npot vectors which need trailing padding In-Reply-To: References: Message-ID: On 21 June 2011 06:52, Nick Lewycky wrote: > This lowers to a struct with <3 x float>, which TargetData says is 16 bytes > on ARM. Hi Nick, This only makes sense for ARM with NEON/VFP, unless selection-DAG identifies it and remove the padding to avoid extra instructions being generated for the CPU when NEON/VFP is not present. Anyone knows if that's the case? > In LLVM IR, the first element becomes a constant aggregate zero, > which is emitted by looking at how many bytes it is (sixteen) and writing > out a zero-fill. The second element is emitted as three contiguous elements, > resulting in a total of 12 bytes. I agree, we should have consistency here. > The StructLayout object claims that each of those should be 16 bytes, so I > changed the AsmPrinter in CodeGen to apply padding to the end of an array to > match what TargetData thinks the length of the array is. Patch attached, > please review! Not sure you changed the right place. I agree that alignment is important for all platforms but I wouldn't make such an assumption without a set of tests for each one of them. If everyone is happy that such padding needs to be dealt with by the generic CodeGen, I won't oppose, but would be good to have at least one test for each major architecture. Otherwise, if you move it to ARMAsmPrinter, I still suggest you to write a simple IR-to-ASM test and check data sizes. cheers, --renato From baldrick at free.fr Tue Jun 21 03:43:19 2011 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Jun 2011 08:43:19 -0000 Subject: [llvm-commits] [dragonegg] r133510 - /dragonegg/trunk/www/index.html Message-ID: <20110621084319.5EF502A6C12C@llvm.org> Author: baldrick Date: Tue Jun 21 03:43:19 2011 New Revision: 133510 URL: http://llvm.org/viewvc/llvm-project?rev=133510&view=rev Log: Add debian note to web-page. 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=133510&r1=133509&r2=133510&view=diff ============================================================================== --- dragonegg/trunk/www/index.html (original) +++ dragonegg/trunk/www/index.html Tue Jun 21 03:43:19 2011 @@ -281,7 +281,9 @@

	svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm

Build LLVM in the usual way.

-

Install gcc-4.5 or gcc-4.6 (you do not need to build your own copy).

+

Install gcc-4.5 or gcc-4.6 (you do not need to build your own copy). On + debian and ubuntu you need to install the corresponding plugin-dev package + (gcc-4.5-plugin-dev or gcc-4.6-plugin-dev).

Doing

	GCC=path_to_just_installed_gcc make

in the dragonegg directory should then build dragonegg.so. From jay.foad at gmail.com Tue Jun 21 05:02:43 2011 From: jay.foad at gmail.com (Jay Foad) Date: Tue, 21 Jun 2011 10:02:43 -0000 Subject: [llvm-commits] [llvm] r133512 - /llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Message-ID: <20110621100243.C70E02A6C12C@llvm.org> Author: foad Date: Tue Jun 21 05:02:43 2011 New Revision: 133512 URL: http://llvm.org/viewvc/llvm-project?rev=133512&view=rev Log: Don't use PN->replaceUsesOfWith() to change a PHINode's incoming blocks, because it won't work after my phi operand changes, because the incoming blocks will no longer be Uses. Modified: llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp?rev=133512&r1=133511&r2=133512&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Tue Jun 21 05:02:43 2011 @@ -190,7 +190,9 @@ BasicBlock* exitingBlock = exitingBlocks[0]; BasicBlock::iterator BI = exitBlock->begin(); while (PHINode* P = dyn_cast(BI)) { - P->replaceUsesOfWith(exitingBlock, preheader); + int j = P->getBasicBlockIndex(exitingBlock); + assert(j >= 0 && "Can't find exiting block in exit block's phi node!"); + P->setIncomingBlock(j, preheader); for (unsigned i = 1; i < exitingBlocks.size(); ++i) P->removeIncomingValue(exitingBlocks[i]); ++BI; From jay.foad at gmail.com Tue Jun 21 05:33:19 2011 From: jay.foad at gmail.com (Jay Foad) Date: Tue, 21 Jun 2011 10:33:19 -0000 Subject: [llvm-commits] [llvm] r133513 - in /llvm/trunk: include/llvm/ include/llvm/Support/ lib/Target/CppBackend/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ Message-ID: <20110621103319.B0D332A6C12C@llvm.org> Author: foad Date: Tue Jun 21 05:33:19 2011 New Revision: 133513 URL: http://llvm.org/viewvc/llvm-project?rev=133513&view=rev Log: Reinstate r133435 and r133449 (reverted in r133499) now that the clang self-hosted build failure has been fixed (r133512). Modified: llvm/trunk/include/llvm/BasicBlock.h llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/Support/CFG.h llvm/trunk/include/llvm/Use.h llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp llvm/trunk/lib/VMCore/BasicBlock.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/lib/VMCore/User.cpp llvm/trunk/lib/VMCore/Value.cpp llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/include/llvm/BasicBlock.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BasicBlock.h?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/include/llvm/BasicBlock.h (original) +++ llvm/trunk/include/llvm/BasicBlock.h Tue Jun 21 05:33:19 2011 @@ -110,7 +110,7 @@ Function *getParent() { return Parent; } /// use_back - Specialize the methods defined in Value, as we know that an - /// BasicBlock can only be used by Users (specifically PHI nodes, terminators, + /// BasicBlock can only be used by Users (specifically terminators /// and BlockAddress's). User *use_back() { return cast(*use_begin());} const User *use_back() const { return cast(*use_begin());} @@ -248,6 +248,10 @@ /// other than direct branches, switches, etc. to it. bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; } + /// replaceSuccessorsPhiUsesWith - Update all phi nodes in all our successors + /// to refer to basic block New instead of to us. + void replaceSuccessorsPhiUsesWith(BasicBlock *New); + private: /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress /// objects using it. This is almost always 0, sometimes one, possibly but Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Tue Jun 21 05:33:19 2011 @@ -1814,7 +1814,7 @@ explicit PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr = "", Instruction *InsertBefore = 0) : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), - ReservedSpace(NumReservedValues * 2) { + ReservedSpace(NumReservedValues) { setName(NameStr); OperandList = allocHungoffUses(ReservedSpace); } @@ -1822,11 +1822,16 @@ PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), - ReservedSpace(NumReservedValues * 2) { + ReservedSpace(NumReservedValues) { setName(NameStr); OperandList = allocHungoffUses(ReservedSpace); } protected: + // allocHungoffUses - this is more complicated than the generic + // User::allocHungoffUses, because we have to allocate Uses for the incoming + // values and pointers to the incoming blocks, all in one allocation. + Use *allocHungoffUses(unsigned) const; + virtual PHINode *clone_impl() const; public: /// Constructors - NumReservedValues is a hint for the number of incoming @@ -1845,32 +1850,55 @@ /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + // Block iterator interface. This provides access to the list of incoming + // basic blocks, which parallels the list of incoming values. + + typedef BasicBlock **block_iterator; + typedef BasicBlock * const *const_block_iterator; + + block_iterator block_begin() { + Use::UserRef *ref = + reinterpret_cast(op_begin() + ReservedSpace); + return reinterpret_cast(ref + 1); + } + + const_block_iterator block_begin() const { + const Use::UserRef *ref = + reinterpret_cast(op_begin() + ReservedSpace); + return reinterpret_cast(ref + 1); + } + + block_iterator block_end() { + return block_begin() + getNumOperands(); + } + + const_block_iterator block_end() const { + return block_begin() + getNumOperands(); + } + /// getNumIncomingValues - Return the number of incoming edges /// - unsigned getNumIncomingValues() const { return getNumOperands()/2; } + unsigned getNumIncomingValues() const { return getNumOperands(); } /// getIncomingValue - Return incoming value number x /// Value *getIncomingValue(unsigned i) const { - assert(i*2 < getNumOperands() && "Invalid value number!"); - return getOperand(i*2); + return getOperand(i); } void setIncomingValue(unsigned i, Value *V) { - assert(i*2 < getNumOperands() && "Invalid value number!"); - setOperand(i*2, V); + setOperand(i, V); } static unsigned getOperandNumForIncomingValue(unsigned i) { - return i*2; + return i; } static unsigned getIncomingValueNumForOperand(unsigned i) { - assert(i % 2 == 0 && "Invalid incoming-value operand index!"); - return i/2; + return i; } /// getIncomingBlock - Return incoming basic block number @p i. /// BasicBlock *getIncomingBlock(unsigned i) const { - return cast(getOperand(i*2+1)); + return block_begin()[i]; } /// getIncomingBlock - Return incoming basic block corresponding @@ -1878,7 +1906,7 @@ /// BasicBlock *getIncomingBlock(const Use &U) const { assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?"); - return cast((&U + 1)->get()); + return getIncomingBlock(&U - op_begin()); } /// getIncomingBlock - Return incoming basic block corresponding @@ -1889,16 +1917,8 @@ return getIncomingBlock(I.getUse()); } - void setIncomingBlock(unsigned i, BasicBlock *BB) { - setOperand(i*2+1, (Value*)BB); - } - static unsigned getOperandNumForIncomingBlock(unsigned i) { - return i*2+1; - } - static unsigned getIncomingBlockNumForOperand(unsigned i) { - assert(i % 2 == 1 && "Invalid incoming-block operand index!"); - return i/2; + block_begin()[i] = BB; } /// addIncoming - Add an incoming value to the end of the PHI list @@ -1908,13 +1928,12 @@ assert(BB && "PHI node got a null basic block!"); assert(getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"); - unsigned OpNo = NumOperands; - if (OpNo+2 > ReservedSpace) + if (NumOperands == ReservedSpace) growOperands(); // Get more space! // Initialize some new operands. - NumOperands = OpNo+2; - OperandList[OpNo] = V; - OperandList[OpNo+1] = (Value*)BB; + ++NumOperands; + setIncomingValue(NumOperands - 1, V); + setIncomingBlock(NumOperands - 1, BB); } /// removeIncomingValue - Remove an incoming value. This is useful if a @@ -1937,14 +1956,16 @@ /// block in the value list for this PHI. Returns -1 if no instance. /// int getBasicBlockIndex(const BasicBlock *BB) const { - Use *OL = OperandList; - for (unsigned i = 0, e = getNumOperands(); i != e; i += 2) - if (OL[i+1].get() == (const Value*)BB) return i/2; + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (block_begin()[i] == BB) + return i; return -1; } Value *getIncomingValueForBlock(const BasicBlock *BB) const { - return getIncomingValue(getBasicBlockIndex(BB)); + int Idx = getBasicBlockIndex(BB); + assert(Idx >= 0 && "Invalid basic block argument!"); + return getIncomingValue(Idx); } /// hasConstantValue - If the specified PHI node always merges together the Modified: llvm/trunk/include/llvm/Support/CFG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CFG.h?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CFG.h (original) +++ llvm/trunk/include/llvm/Support/CFG.h Tue Jun 21 05:33:19 2011 @@ -33,7 +33,7 @@ USE_iterator It; inline void advancePastNonTerminators() { - // Loop to ignore non terminator uses (for example PHI nodes). + // Loop to ignore non terminator uses (for example BlockAddresses). while (!It.atEnd() && !isa(*It)) ++It; } Modified: llvm/trunk/include/llvm/Use.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Use.h?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/include/llvm/Use.h (original) +++ llvm/trunk/include/llvm/Use.h Tue Jun 21 05:33:19 2011 @@ -112,13 +112,16 @@ Use *getNext() const { return Next; } + /// initTags - initialize the waymarking tags on an array of Uses, so that + /// getUser() can find the User from any of those Uses. + static Use *initTags(Use *Start, Use *Stop); + /// zap - This is used to destroy Use operands when the number of operands of /// a User changes. static void zap(Use *Start, const Use *Stop, bool del = false); private: const Use* getImpliedUser() const; - static Use *initTags(Use *Start, Use *Stop); Value *Val; Use *Next; @@ -140,7 +143,6 @@ } friend class Value; - friend class User; }; // simplify_type - Allow clients to treat uses just like values when using Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Tue Jun 21 05:33:19 2011 @@ -1356,7 +1356,7 @@ for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) { Out << iName << "->addIncoming(" << opNames[PHINode::getOperandNumForIncomingValue(i)] << ", " - << opNames[PHINode::getOperandNumForIncomingBlock(i)] << ");"; + << getOpName(phi->getIncomingBlock(i)) << ");"; nl(Out); } break; Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Tue Jun 21 05:33:19 2011 @@ -1021,6 +1021,10 @@ while (PHINode *PN = dyn_cast(Succ->begin())) ReplaceUsesOfWith(PN, PN->getIncomingValue(0), Worklist, L, LPM); + // If Succ has any successors with PHI nodes, update them to have + // entries coming from Pred instead of Succ. + Succ->replaceAllUsesWith(Pred); + // Move all of the successor contents from Succ to Pred. Pred->getInstList().splice(BI, Succ->getInstList(), Succ->begin(), Succ->end()); @@ -1028,10 +1032,6 @@ BI->eraseFromParent(); RemoveFromWorklist(BI, Worklist); - // If Succ has any successors with PHI nodes, update them to have - // entries coming from Pred instead of Succ. - Succ->replaceAllUsesWith(Pred); - // Remove Succ from the loop tree. LI->removeBlock(Succ); LPM->deleteSimpleAnalysisValue(Succ, L); Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Tue Jun 21 05:33:19 2011 @@ -153,13 +153,13 @@ // Delete the unconditional branch from the predecessor... PredBB->getInstList().pop_back(); - // Move all definitions in the successor to the predecessor... - PredBB->getInstList().splice(PredBB->end(), BB->getInstList()); - // Make all PHI nodes that referred to BB now refer to Pred as their // source... BB->replaceAllUsesWith(PredBB); + // Move all definitions in the successor to the predecessor... + PredBB->getInstList().splice(PredBB->end(), BB->getInstList()); + // Inherit predecessors name if it exists. if (!PredBB->hasName()) PredBB->takeName(BB); Modified: llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp Tue Jun 21 05:33:19 2011 @@ -193,44 +193,22 @@ // If there are any PHI nodes in DestBB, we need to update them so that they // merge incoming values from NewBB instead of from TIBB. - if (PHINode *APHI = dyn_cast(DestBB->begin())) { - // This conceptually does: - // foreach (PHINode *PN in DestBB) - // PN->setIncomingBlock(PN->getIncomingBlock(TIBB), NewBB); - // but is optimized for two cases. - - if (APHI->getNumIncomingValues() <= 8) { // Small # preds case. - unsigned BBIdx = 0; - for (BasicBlock::iterator I = DestBB->begin(); isa(I); ++I) { - // We no longer enter through TIBB, now we come in through NewBB. - // Revector exactly one entry in the PHI node that used to come from - // TIBB to come from NewBB. - PHINode *PN = cast(I); - - // Reuse the previous value of BBIdx if it lines up. In cases where we - // have multiple phi nodes with *lots* of predecessors, this is a speed - // win because we don't have to scan the PHI looking for TIBB. This - // happens because the BB list of PHI nodes are usually in the same - // order. - if (PN->getIncomingBlock(BBIdx) != TIBB) - BBIdx = PN->getBasicBlockIndex(TIBB); - PN->setIncomingBlock(BBIdx, NewBB); - } - } else { - // However, the foreach loop is slow for blocks with lots of predecessors - // because PHINode::getIncomingBlock is O(n) in # preds. Instead, walk - // the user list of TIBB to find the PHI nodes. - SmallPtrSet UpdatedPHIs; - - for (Value::use_iterator UI = TIBB->use_begin(), E = TIBB->use_end(); - UI != E; ) { - Value::use_iterator Use = UI++; - if (PHINode *PN = dyn_cast(*Use)) { - // Remove one entry from each PHI. - if (PN->getParent() == DestBB && UpdatedPHIs.insert(PN)) - PN->setOperand(Use.getOperandNo(), NewBB); - } - } + { + unsigned BBIdx = 0; + for (BasicBlock::iterator I = DestBB->begin(); isa(I); ++I) { + // We no longer enter through TIBB, now we come in through NewBB. + // Revector exactly one entry in the PHI node that used to come from + // TIBB to come from NewBB. + PHINode *PN = cast(I); + + // Reuse the previous value of BBIdx if it lines up. In cases where we + // have multiple phi nodes with *lots* of predecessors, this is a speed + // win because we don't have to scan the PHI looking for TIBB. This + // happens because the BB list of PHI nodes are usually in the same + // order. + if (PN->getIncomingBlock(BBIdx) != TIBB) + BBIdx = PN->getBasicBlockIndex(TIBB); + PN->setIncomingBlock(BBIdx, NewBB); } } Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Tue Jun 21 05:33:19 2011 @@ -572,12 +572,12 @@ // removed, so we just need to splice the blocks. BI->eraseFromParent(); - // Move all the instructions in the succ to the pred. - I->getInstList().splice(I->end(), Dest->getInstList()); - // Make all PHI nodes that referred to Dest now refer to I as their source. Dest->replaceAllUsesWith(I); + // Move all the instructions in the succ to the pred. + I->getInstList().splice(I->end(), Dest->getInstList()); + // Remove the dest block. Dest->eraseFromParent(); Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Tue Jun 21 05:33:19 2011 @@ -1097,15 +1097,15 @@ TheCall->replaceAllUsesWith(Returns[0]->getReturnValue()); } + // Update PHI nodes that use the ReturnBB to use the AfterCallBB. + BasicBlock *ReturnBB = Returns[0]->getParent(); + ReturnBB->replaceAllUsesWith(AfterCallBB); + // Splice the code from the return block into the block that it will return // to, which contains the code that was after the call. - BasicBlock *ReturnBB = Returns[0]->getParent(); AfterCallBB->getInstList().splice(AfterCallBB->begin(), ReturnBB->getInstList()); - // Update PHI nodes that use the ReturnBB to use the AfterCallBB. - ReturnBB->replaceAllUsesWith(AfterCallBB); - // Delete the return instruction now and empty ReturnBB now. Returns[0]->eraseFromParent(); ReturnBB->eraseFromParent(); @@ -1125,8 +1125,8 @@ // Splice the code entry block into calling block, right before the // unconditional branch. - OrigBB->getInstList().splice(Br, CalleeEntry->getInstList()); CalleeEntry->replaceAllUsesWith(OrigBB); // Update PHI nodes + OrigBB->getInstList().splice(Br, CalleeEntry->getInstList()); // Remove the unconditional branch. OrigBB->getInstList().erase(Br); Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Tue Jun 21 05:33:19 2011 @@ -427,10 +427,6 @@ BasicBlock *PredBB = DestBB->getSinglePredecessor(); assert(PredBB && "Block doesn't have a single predecessor!"); - // Splice all the instructions from PredBB to DestBB. - PredBB->getTerminator()->eraseFromParent(); - DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList()); - // Zap anything that took the address of DestBB. Not doing this will give the // address an invalid value. if (DestBB->hasAddressTaken()) { @@ -445,6 +441,10 @@ // Anything that branched to PredBB now branches to DestBB. PredBB->replaceAllUsesWith(DestBB); + // Splice all the instructions from PredBB to DestBB. + PredBB->getTerminator()->eraseFromParent(); + DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList()); + if (P) { DominatorTree *DT = P->getAnalysisIfAvailable(); if (DT) { @@ -660,12 +660,17 @@ // them, which helps expose duplicates, but we have to check all the // operands to be safe in case instcombine hasn't run. uintptr_t Hash = 0; + // This hash algorithm is quite weak as hash functions go, but it seems + // to do a good enough job for this particular purpose, and is very quick. for (User::op_iterator I = PN->op_begin(), E = PN->op_end(); I != E; ++I) { - // This hash algorithm is quite weak as hash functions go, but it seems - // to do a good enough job for this particular purpose, and is very quick. Hash ^= reinterpret_cast(static_cast(*I)); Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7)); } + for (PHINode::block_iterator I = PN->block_begin(), E = PN->block_end(); + I != E; ++I) { + Hash ^= reinterpret_cast(static_cast(*I)); + Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7)); + } // Avoid colliding with the DenseMap sentinels ~0 and ~0-1. Hash >>= 1; // If we've never seen this hash value before, it's a unique PHI. Modified: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Tue Jun 21 05:33:19 2011 @@ -47,6 +47,14 @@ if (It != VMap.end()) I->setOperand(op, It->second); } + + if (PHINode *PN = dyn_cast(I)) { + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + ValueToValueMapTy::iterator It = VMap.find(PN->getIncomingBlock(i)); + if (It != VMap.end()) + PN->setIncomingBlock(i, cast(It->second)); + } + } } /// FoldBlockIntoPredecessor - Folds a basic block into its predecessor if it @@ -75,13 +83,13 @@ // Delete the unconditional branch from the predecessor... OnlyPred->getInstList().pop_back(); - // Move all definitions in the successor to the predecessor... - OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList()); - // Make all PHI nodes that referred to BB now refer to Pred as their // source... BB->replaceAllUsesWith(OnlyPred); + // Move all definitions in the successor to the predecessor... + OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList()); + std::string OldName = BB->getName(); // Erase basic block from the function... @@ -247,16 +255,14 @@ // the successor of the latch block. The successor of the exit block will // be updated specially after unrolling all the way. if (*BB != LatchBlock) - for (Value::use_iterator UI = (*BB)->use_begin(), UE = (*BB)->use_end(); - UI != UE;) { - Instruction *UseInst = cast(*UI); - ++UI; - if (isa(UseInst) && !L->contains(UseInst)) { - PHINode *phi = cast(UseInst); - Value *Incoming = phi->getIncomingValueForBlock(*BB); - phi->addIncoming(Incoming, New); - } - } + for (succ_iterator SI = succ_begin(*BB), SE = succ_end(*BB); SI != SE; + ++SI) + if (!L->contains(*SI)) + for (BasicBlock::iterator BBI = (*SI)->begin(), BBE = (*SI)->end(); + PHINode *phi = dyn_cast(BBI); ++BBI) { + Value *Incoming = phi->getIncomingValueForBlock(*BB); + phi->addIncoming(Incoming, New); + } // Keep track of new headers and latches as we create them, so that // we can insert the proper branches later. @@ -288,24 +294,20 @@ // successor blocks, update them to use the appropriate values computed as the // last iteration of the loop. if (Count != 1) { - SmallPtrSet Users; - for (Value::use_iterator UI = LatchBlock->use_begin(), - UE = LatchBlock->use_end(); UI != UE; ++UI) - if (PHINode *phi = dyn_cast(*UI)) - Users.insert(phi); - BasicBlock *LastIterationBB = cast(LastValueMap[LatchBlock]); - for (SmallPtrSet::iterator SI = Users.begin(), SE = Users.end(); + for (succ_iterator SI = succ_begin(LatchBlock), SE = succ_end(LatchBlock); SI != SE; ++SI) { - PHINode *PN = *SI; - Value *InVal = PN->removeIncomingValue(LatchBlock, false); - // If this value was defined in the loop, take the value defined by the - // last iteration of the loop. - if (Instruction *InValI = dyn_cast(InVal)) { - if (L->contains(InValI)) - InVal = LastValueMap[InVal]; + for (BasicBlock::iterator BBI = (*SI)->begin(), BBE = (*SI)->end(); + PHINode *PN = dyn_cast(BBI); ++BBI) { + Value *InVal = PN->removeIncomingValue(LatchBlock, false); + // If this value was defined in the loop, take the value defined by the + // last iteration of the loop. + if (Instruction *InValI = dyn_cast(InVal)) { + if (L->contains(InValI)) + InVal = LastValueMap[InVal]; + } + PN->addIncoming(InVal, LastIterationBB); } - PN->addIncoming(InVal, LastIterationBB); } } @@ -352,11 +354,16 @@ // Replace the conditional branch with an unconditional one. BranchInst::Create(Dest, Term); Term->eraseFromParent(); - // Merge adjacent basic blocks, if possible. - if (BasicBlock *Fold = FoldBlockIntoPredecessor(Dest, LI)) { + } + } + + // Merge adjacent basic blocks, if possible. + for (unsigned i = 0, e = Latches.size(); i != e; ++i) { + BranchInst *Term = cast(Latches[i]->getTerminator()); + if (Term->isUnconditional()) { + BasicBlock *Dest = Term->getSuccessor(0); + if (BasicBlock *Fold = FoldBlockIntoPredecessor(Dest, LI)) std::replace(Latches.begin(), Latches.end(), Dest, Fold); - std::replace(Headers.begin(), Headers.end(), Dest, Fold); - } } } Modified: llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp Tue Jun 21 05:33:19 2011 @@ -16,6 +16,7 @@ #include "llvm/Type.h" #include "llvm/Constants.h" #include "llvm/Function.h" +#include "llvm/Instructions.h" #include "llvm/Metadata.h" #include "llvm/ADT/SmallVector.h" using namespace llvm; @@ -128,6 +129,19 @@ "Referenced value not in value map!"); } + // Remap phi nodes' incoming blocks. + if (PHINode *PN = dyn_cast(I)) { + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + Value *V = MapValue(PN->getIncomingBlock(i), VMap, Flags); + // If we aren't ignoring missing entries, assert that something happened. + if (V != 0) + PN->setIncomingBlock(i, cast(V)); + else + assert((Flags & RF_IgnoreMissingEntries) && + "Referenced block not in value map!"); + } + } + // Remap attached metadata. SmallVector, 4> MDs; I->getAllMetadata(MDs); Modified: llvm/trunk/lib/VMCore/BasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/BasicBlock.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/BasicBlock.cpp (original) +++ llvm/trunk/lib/VMCore/BasicBlock.cpp Tue Jun 21 05:33:19 2011 @@ -308,3 +308,19 @@ return New; } +void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) { + TerminatorInst *TI = getTerminator(); + if (!TI) + // Cope with being called on a BasicBlock that doesn't have a terminator + // yet. Clang's CodeGenFunction::EmitReturnBlock() likes to do this. + return; + for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) { + BasicBlock *Succ = TI->getSuccessor(i); + for (iterator II = Succ->begin(); PHINode *PN = dyn_cast(II); + ++II) { + int i; + while ((i = PN->getBasicBlockIndex(this)) >= 0) + PN->setIncomingBlock(i, New); + } + } +} Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Tue Jun 21 05:33:19 2011 @@ -87,11 +87,8 @@ : Instruction(PN.getType(), Instruction::PHI, allocHungoffUses(PN.getNumOperands()), PN.getNumOperands()), ReservedSpace(PN.getNumOperands()) { - Use *OL = OperandList; - for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) { - OL[i] = PN.getOperand(i); - OL[i+1] = PN.getOperand(i+1); - } + std::copy(PN.op_begin(), PN.op_end(), op_begin()); + std::copy(PN.block_begin(), PN.block_end(), block_begin()); SubclassOptionalData = PN.SubclassOptionalData; } @@ -99,31 +96,37 @@ dropHungoffUses(); } +Use *PHINode::allocHungoffUses(unsigned N) const { + // Allocate the array of Uses of the incoming values, followed by a pointer + // (with bottom bit set) to the User, followed by the array of pointers to + // the incoming basic blocks. + size_t size = N * sizeof(Use) + sizeof(Use::UserRef) + + N * sizeof(BasicBlock*); + Use *Begin = static_cast(::operator new(size)); + Use *End = Begin + N; + (void) new(End) Use::UserRef(const_cast(this), 1); + return Use::initTags(Begin, End); +} + // removeIncomingValue - Remove an incoming value. This is useful if a // predecessor basic block is deleted. Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) { - unsigned NumOps = getNumOperands(); - Use *OL = OperandList; - assert(Idx*2 < NumOps && "BB not in PHI node!"); - Value *Removed = OL[Idx*2]; + Value *Removed = getIncomingValue(Idx); // Move everything after this operand down. // // FIXME: we could just swap with the end of the list, then erase. However, - // client might not expect this to happen. The code as it is thrashes the + // clients might not expect this to happen. The code as it is thrashes the // use/def lists, which is kinda lame. - for (unsigned i = (Idx+1)*2; i != NumOps; i += 2) { - OL[i-2] = OL[i]; - OL[i-2+1] = OL[i+1]; - } + std::copy(op_begin() + Idx + 1, op_end(), op_begin() + Idx); + std::copy(block_begin() + Idx + 1, block_end(), block_begin() + Idx); // Nuke the last value. - OL[NumOps-2].set(0); - OL[NumOps-2+1].set(0); - NumOperands = NumOps-2; + Op<-1>().set(0); + --NumOperands; // If the PHI node is dead, because it has zero entries, nuke it now. - if (NumOps == 2 && DeletePHIIfEmpty) { + if (getNumOperands() == 0 && DeletePHIIfEmpty) { // If anyone is using this PHI, make them use a dummy value instead... replaceAllUsesWith(UndefValue::get(getType())); eraseFromParent(); @@ -137,15 +140,18 @@ /// void PHINode::growOperands() { unsigned e = getNumOperands(); - // Multiply by 1.5 and round down so the result is still even. - unsigned NumOps = e + e / 4 * 2; - if (NumOps < 4) NumOps = 4; // 4 op PHI nodes are VERY common. + unsigned NumOps = e + e / 2; + if (NumOps < 2) NumOps = 2; // 2 op PHI nodes are VERY common. + + Use *OldOps = op_begin(); + BasicBlock **OldBlocks = block_begin(); ReservedSpace = NumOps; - Use *OldOps = OperandList; - Use *NewOps = allocHungoffUses(NumOps); - std::copy(OldOps, OldOps + e, NewOps); - OperandList = NewOps; + OperandList = allocHungoffUses(ReservedSpace); + + std::copy(OldOps, OldOps + e, op_begin()); + std::copy(OldBlocks, OldBlocks + e, block_begin()); + Use::zap(OldOps, OldOps + e, true); } Modified: llvm/trunk/lib/VMCore/User.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/User.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/User.cpp (original) +++ llvm/trunk/lib/VMCore/User.cpp Tue Jun 21 05:33:19 2011 @@ -40,8 +40,10 @@ //===----------------------------------------------------------------------===// Use *User::allocHungoffUses(unsigned N) const { - Use *Begin = static_cast(::operator new(sizeof(Use) * N - + sizeof(Use::UserRef))); + // Allocate the array of Uses, followed by a pointer (with bottom bit set) to + // the User. + size_t size = N * sizeof(Use) + sizeof(Use::UserRef); + Use *Begin = static_cast(::operator new(size)); Use *End = Begin + N; (void) new(End) Use::UserRef(const_cast(this), 1); return Use::initTags(Begin, End); Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Tue Jun 21 05:33:19 2011 @@ -305,6 +305,9 @@ U.set(New); } + + if (BasicBlock *BB = dyn_cast(this)) + BB->replaceSuccessorsPhiUsesWith(cast(New)); } void Value::replaceAllUsesWith(Value *New) { Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=133513&r1=133512&r2=133513&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Tue Jun 21 05:33:19 2011 @@ -1139,9 +1139,6 @@ for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { Assert1(PN.getType() == PN.getIncomingValue(i)->getType(), "PHI node operands are not the same type as the result!", &PN); - Assert1(isa(PN.getOperand( - PHINode::getOperandNumForIncomingBlock(i))), - "PHI node incoming block is not a BasicBlock!", &PN); } // All other PHI node constraints are checked in the visitBasicBlock method. From fvbommel at gmail.com Tue Jun 21 06:41:35 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Tue, 21 Jun 2011 13:41:35 +0200 Subject: [llvm-commits] [llvm] r133512 - /llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp In-Reply-To: <20110621100243.C70E02A6C12C@llvm.org> References: <20110621100243.C70E02A6C12C@llvm.org> Message-ID: On 21 June 2011 12:02, Jay Foad wrote: > Log: > Don't use PN->replaceUsesOfWith() to change a PHINode's incoming blocks, > because it won't work after my phi operand changes, because the incoming > blocks will no longer be Uses. > ? while (PHINode* P = dyn_cast(BI)) { > - ? ?P->replaceUsesOfWith(exitingBlock, preheader); > + ? ?int j = P->getBasicBlockIndex(exitingBlock); > + ? ?assert(j >= 0 && "Can't find exiting block in exit block's phi node!"); > + ? ?P->setIncomingBlock(j, preheader); replaceUsesOfWith() can handle multiple uses of the same value, but this version only handles a single use. Are you sure there can only be a single incoming edge from each basic block here? From jay.foad at gmail.com Tue Jun 21 06:57:35 2011 From: jay.foad at gmail.com (Jay Foad) Date: Tue, 21 Jun 2011 12:57:35 +0100 Subject: [llvm-commits] [llvm] r133512 - /llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp In-Reply-To: References: <20110621100243.C70E02A6C12C@llvm.org> Message-ID: On 21 June 2011 12:41, Frits van Bommel wrote: > On 21 June 2011 12:02, Jay Foad wrote: >> Log: >> Don't use PN->replaceUsesOfWith() to change a PHINode's incoming blocks, >> because it won't work after my phi operand changes, because the incoming >> blocks will no longer be Uses. > >> ? while (PHINode* P = dyn_cast(BI)) { >> - ? ?P->replaceUsesOfWith(exitingBlock, preheader); >> + ? ?int j = P->getBasicBlockIndex(exitingBlock); >> + ? ?assert(j >= 0 && "Can't find exiting block in exit block's phi node!"); >> + ? ?P->setIncomingBlock(j, preheader); > > replaceUsesOfWith() can handle multiple uses of the same value, but > this version only handles a single use. Are you sure there can only be > a single incoming edge from each basic block here? exitingBlock is an arbitrarily chosen member of exitingBlocks[]. The code goes on to say: for (unsigned i = 1; i < exitingBlocks.size(); ++i) P->removeIncomingValue(exitingBlocks[i]); which will only remove one incoming edge for each of the other members of exitingBlocks[]. So yes, I'm fairly sure that either there's only a single incoming edge from each exitingBlock, or the code was already broken. I did consider a completely different fix, which is to implement something like: void PHINode::replaceUsesOfWith(Value *From, Value *To) { if (isa(From)) { assert(isa(To)); for (block_iterator I = block_begin(), E = block_end(); I != E; ++I) if (*I == From) *I = To; } else { assert(!isa(To)); User::replaceUsesOfWith(From, To); } } Would you prefer that? Jay. From baldrick at free.fr Tue Jun 21 06:57:54 2011 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Jun 2011 13:57:54 +0200 Subject: [llvm-commits] [llvm] r133285 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp In-Reply-To: References: <20110617202152.D6B812A6C12C@llvm.org> <4DFDF276.5030703@free.fr> <54E09593-01A1-4936-AFF8-7AF19D2C6919@apple.com> <4DFEF6DA.4030503@free.fr> Message-ID: <4E008742.9030700@free.fr> Hi John, >>> However, there's a second restriction, which is that it's undefined >>> behavior to allocate something too large for the stack. Technically >>> this is target-specific, but if we just assume by fiat that 2^31 is too large, >>> then as long as the arithmetic is being done in some reasonable size >>> then we know that N * sizeof(T) isn't permitted to signed overflow, either. >> >> if you are willing to assume that then you don't need to check for nuw either... > > We can't *assume* it doesn't overflow. I thought *you* were suggesting that we assume no overflow when you said "but if we just assume by fiat that 2^31 is too large, then as long as the arithmetic is being done in some reasonable size then we know that N * sizeof(T) isn't permitted to signed overflow, either." I guess I misunderstood. I'm still not sure what you were trying to say :) That's the whole point of this discussion. > There's an implicit multiply in sizeof(sp) as part of the alloca instruction, and > it's undefined behavior if either > - that multiply causes unsigned overflow or Sure. > - either the input or output to that multiply is negative. Why? Are you saying that an alloca of 2^31 i8's should be considered to result in undefined behaviour? And what about this: alloca i8, i8 128 By the way, on a 64 bit machine I guess it costs nothing to change the type of the alloca numelements parameter to i64, so if Stuart's testcase was on such a platform then it could become: %c = alloca [16 x i8], i64 %N where %N = zext i32 %n to i64. > Going back to Stuart's original test case, we can't apply the transform to this: > %a = mul i32 16, %n > %b = alloca i8, i32 %b > %c = bitcast i8* %x to [16 x i8]* > as that might introduce undefined behavior, because the multiply in %a is > allowed to overflow, and the multiply in this: > %c = alloca [16 x i8], i32 %n > is not. Indeed. Ciao, Duncan. From fvbommel at gmail.com Tue Jun 21 07:10:30 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Tue, 21 Jun 2011 14:10:30 +0200 Subject: [llvm-commits] [llvm] r133512 - /llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp In-Reply-To: References: <20110621100243.C70E02A6C12C@llvm.org> Message-ID: On 21 June 2011 13:57, Jay Foad wrote: > On 21 June 2011 12:41, Frits van Bommel wrote: >> On 21 June 2011 12:02, Jay Foad wrote: >>> Log: >>> Don't use PN->replaceUsesOfWith() to change a PHINode's incoming blocks, >>> because it won't work after my phi operand changes, because the incoming >>> blocks will no longer be Uses. >> >>> ? while (PHINode* P = dyn_cast(BI)) { >>> - ? ?P->replaceUsesOfWith(exitingBlock, preheader); >>> + ? ?int j = P->getBasicBlockIndex(exitingBlock); >>> + ? ?assert(j >= 0 && "Can't find exiting block in exit block's phi node!"); >>> + ? ?P->setIncomingBlock(j, preheader); >> >> replaceUsesOfWith() can handle multiple uses of the same value, but >> this version only handles a single use. Are you sure there can only be >> a single incoming edge from each basic block here? > > exitingBlock is an arbitrarily chosen member of exitingBlocks[]. The > code goes on to say: > > ? ?for (unsigned i = 1; i < exitingBlocks.size(); ++i) > ? ? ?P->removeIncomingValue(exitingBlocks[i]); > > which will only remove one incoming edge for each of the other members > of exitingBlocks[]. So yes, I'm fairly sure that either there's only a > single incoming edge from each exitingBlock, or the code was already > broken. Huh. Don't know how I missed that. It's all right there in the diff, even. From jay.foad at gmail.com Tue Jun 21 07:57:18 2011 From: jay.foad at gmail.com (Jay Foad) Date: Tue, 21 Jun 2011 13:57:18 +0100 Subject: [llvm-commits] [PATCH 0/5] Reduce memory usage for phi operands In-Reply-To: <4737089F-10B2-4D3F-A9C5-B26E2D405674@apple.com> References: <1308222566-2451-1-git-send-email-jay.foad@gmail.com> <4737089F-10B2-4D3F-A9C5-B26E2D405674@apple.com> Message-ID: > If you're interested in another project, PR1324 would be another great memory reduction for apps with lots of strings and tables. This bug is about using a more compact representation of ConstantArrays of ConstantInts. I think it will be easier to do this for integers of a few pre-defined widths (i8. i16, i32, i64, maybe even i1), rather than trying to handle arbitrarily wide integers. Does this seem reasonable? Thanks, Jay. From benny.kra at googlemail.com Tue Jun 21 09:58:30 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 21 Jun 2011 14:58:30 -0000 Subject: [llvm-commits] [llvm] r133514 - /llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Message-ID: <20110621145830.998B52A6C12C@llvm.org> Author: d0k Date: Tue Jun 21 09:58:30 2011 New Revision: 133514 URL: http://llvm.org/viewvc/llvm-project?rev=133514&view=rev Log: Remove unused variables. Modified: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Modified: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp?rev=133514&r1=133513&r2=133514&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Tue Jun 21 09:58:30 2011 @@ -258,7 +258,7 @@ for (succ_iterator SI = succ_begin(*BB), SE = succ_end(*BB); SI != SE; ++SI) if (!L->contains(*SI)) - for (BasicBlock::iterator BBI = (*SI)->begin(), BBE = (*SI)->end(); + for (BasicBlock::iterator BBI = (*SI)->begin(); PHINode *phi = dyn_cast(BBI); ++BBI) { Value *Incoming = phi->getIncomingValueForBlock(*BB); phi->addIncoming(Incoming, New); @@ -297,7 +297,7 @@ BasicBlock *LastIterationBB = cast(LastValueMap[LatchBlock]); for (succ_iterator SI = succ_begin(LatchBlock), SE = succ_end(LatchBlock); SI != SE; ++SI) { - for (BasicBlock::iterator BBI = (*SI)->begin(), BBE = (*SI)->end(); + for (BasicBlock::iterator BBI = (*SI)->begin(); PHINode *PN = dyn_cast(BBI); ++BBI) { Value *InVal = PN->removeIncomingValue(LatchBlock, false); // If this value was defined in the loop, take the value defined by the From jay.foad at gmail.com Tue Jun 21 10:36:24 2011 From: jay.foad at gmail.com (Jay Foad) Date: Tue, 21 Jun 2011 15:36:24 -0000 Subject: [llvm-commits] [llvm] r133516 - /llvm/trunk/tools/lto/LTOModule.cpp Message-ID: <20110621153624.604CB2A6C12C@llvm.org> Author: foad Date: Tue Jun 21 10:36:24 2011 New Revision: 133516 URL: http://llvm.org/viewvc/llvm-project?rev=133516&view=rev Log: Remove some unnecessary uses of c_str(). Modified: llvm/trunk/tools/lto/LTOModule.cpp Modified: llvm/trunk/tools/lto/LTOModule.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOModule.cpp?rev=133516&r1=133515&r2=133516&view=diff ============================================================================== --- llvm/trunk/tools/lto/LTOModule.cpp (original) +++ llvm/trunk/tools/lto/LTOModule.cpp Tue Jun 21 10:36:24 2011 @@ -208,7 +208,7 @@ if (objcClassNameFromExpression(c->getOperand(1), superclassName)) { NameAndAttributes info; StringMap::value_type &entry = - _undefines.GetOrCreateValue(superclassName.c_str()); + _undefines.GetOrCreateValue(superclassName); if (!entry.getValue().name) { const char *symbolName = entry.getKey().data(); info.name = symbolName; @@ -220,7 +220,7 @@ std::string className; if (objcClassNameFromExpression(c->getOperand(2), className)) { StringSet::value_type &entry = - _defines.GetOrCreateValue(className.c_str()); + _defines.GetOrCreateValue(className); entry.setValue(1); NameAndAttributes info; info.name = entry.getKey().data(); @@ -243,7 +243,7 @@ NameAndAttributes info; StringMap::value_type &entry = - _undefines.GetOrCreateValue(targetclassName.c_str()); + _undefines.GetOrCreateValue(targetclassName); if (entry.getValue().name) return; @@ -264,7 +264,7 @@ NameAndAttributes info; StringMap::value_type &entry = - _undefines.GetOrCreateValue(targetclassName.c_str()); + _undefines.GetOrCreateValue(targetclassName); if (entry.getValue().name) return; @@ -375,7 +375,7 @@ // add to table of symbols NameAndAttributes info; - StringSet::value_type &entry = _defines.GetOrCreateValue(Buffer.c_str()); + StringSet::value_type &entry = _defines.GetOrCreateValue(Buffer); entry.setValue(1); StringRef Name = entry.getKey(); @@ -436,7 +436,7 @@ mangler.getNameWithPrefix(name, decl, false); StringMap::value_type &entry = - _undefines.GetOrCreateValue(name.c_str()); + _undefines.GetOrCreateValue(name); // we already have the symbol if (entry.getValue().name) From jay.foad at gmail.com Tue Jun 21 10:37:05 2011 From: jay.foad at gmail.com (Jay Foad) Date: Tue, 21 Jun 2011 15:37:05 -0000 Subject: [llvm-commits] [llvm] r133517 - /llvm/trunk/include/llvm/ADT/StringMap.h Message-ID: <20110621153705.941BF2A6C12C@llvm.org> Author: foad Date: Tue Jun 21 10:37:05 2011 New Revision: 133517 URL: http://llvm.org/viewvc/llvm-project?rev=133517&view=rev Log: Remove deprecated forms of StringMap::GetOrCreateValue(). Modified: llvm/trunk/include/llvm/ADT/StringMap.h Modified: llvm/trunk/include/llvm/ADT/StringMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringMap.h?rev=133517&r1=133516&r2=133517&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringMap.h (original) +++ llvm/trunk/include/llvm/ADT/StringMap.h Tue Jun 21 10:37:05 2011 @@ -381,18 +381,6 @@ return GetOrCreateValue(Key, ValueTy()); } - // FIXME: Remove this method. - template - MapEntryTy &GetOrCreateValue(const char *KeyStart, const char *KeyEnd, - InitTy Val) { - return GetOrCreateValue(StringRef(KeyStart, KeyEnd - KeyStart), Val); - } - - // FIXME: Remove this method. - MapEntryTy &GetOrCreateValue(const char *KeyStart, const char *KeyEnd) { - return GetOrCreateValue(StringRef(KeyStart, KeyEnd - KeyStart)); - } - /// remove - Remove the specified key/value pair from the map, but do not /// erase it. This aborts if the key is not in the map. void remove(MapEntryTy *KeyValue) { From jay.foad at gmail.com Tue Jun 21 10:43:52 2011 From: jay.foad at gmail.com (Jay Foad) Date: Tue, 21 Jun 2011 16:43:52 +0100 Subject: [llvm-commits] [llvm] r133504 - /llvm/trunk/include/llvm/ADT/StringMap.h In-Reply-To: <20110621062234.20F6E2A6C12C@llvm.org> References: <20110621062234.20F6E2A6C12C@llvm.org> Message-ID: On 21 June 2011 07:22, Chris Lattner wrote: > use the MapEntryTy typedef instead of writing it out long form, > add some fixme's about methods that should be removed. Removed in r133517 :) Thanks, Jay. From atrick at apple.com Tue Jun 21 10:43:53 2011 From: atrick at apple.com (Andrew Trick) Date: Tue, 21 Jun 2011 15:43:53 -0000 Subject: [llvm-commits] [llvm] r133518 - in /llvm/trunk: include/llvm/Analysis/IVUsers.h lib/Analysis/IVUsers.cpp lib/Transforms/Scalar/IndVarSimplify.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <20110621154353.295322A6C12C@llvm.org> Author: atrick Date: Tue Jun 21 10:43:52 2011 New Revision: 133518 URL: http://llvm.org/viewvc/llvm-project?rev=133518&view=rev Log: IVUsers no longer needs to record the phis. Modified: llvm/trunk/include/llvm/Analysis/IVUsers.h llvm/trunk/lib/Analysis/IVUsers.cpp llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/include/llvm/Analysis/IVUsers.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/IVUsers.h?rev=133518&r1=133517&r2=133518&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/IVUsers.h (original) +++ llvm/trunk/include/llvm/Analysis/IVUsers.h Tue Jun 21 10:43:52 2011 @@ -37,8 +37,8 @@ class IVStrideUse : public CallbackVH, public ilist_node { friend class IVUsers; public: - IVStrideUse(IVUsers *P, Instruction* U, Value *O, Value *PN) - : CallbackVH(U), Parent(P), OperandValToReplace(O), Phi(PN) { + IVStrideUse(IVUsers *P, Instruction* U, Value *O) + : CallbackVH(U), Parent(P), OperandValToReplace(O) { } /// getUser - Return the user instruction for this use. @@ -51,11 +51,6 @@ setValPtr(NewUser); } - /// getPhi - Return the phi node that represents this IV. - PHINode *getPhi() const { - return cast(Phi); - } - /// getOperandValToReplace - Return the Value of the operand in the user /// instruction that this IVStrideUse is representing. Value *getOperandValToReplace() const { @@ -86,9 +81,6 @@ /// that this IVStrideUse is representing. WeakVH OperandValToReplace; - /// Phi - The loop header phi that represents this IV. - WeakVH Phi; - /// PostIncLoops - The set of loops for which Expr has been adjusted to /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept. PostIncLoopSet PostIncLoops; @@ -151,9 +143,9 @@ /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a /// reducible SCEV, recursively add its users to the IVUsesByStride set and /// return true. Otherwise, return false. - bool AddUsersIfInteresting(Instruction *I, PHINode *Phi); + bool AddUsersIfInteresting(Instruction *I); - IVStrideUse &AddUser(Instruction *User, Value *Operand, PHINode *Phi); + IVStrideUse &AddUser(Instruction *User, Value *Operand); /// getReplacementExpr - Return a SCEV expression which computes the /// value of the OperandValToReplace of the given IVStrideUse. Modified: llvm/trunk/lib/Analysis/IVUsers.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IVUsers.cpp?rev=133518&r1=133517&r2=133518&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IVUsers.cpp (original) +++ llvm/trunk/lib/Analysis/IVUsers.cpp Tue Jun 21 10:43:52 2011 @@ -89,7 +89,7 @@ /// AddUsersIfInteresting - Inspect the specified instruction. If it is a /// reducible SCEV, recursively add its users to the IVUsesByStride set and /// return true. Otherwise, return false. -bool IVUsers::AddUsersIfInteresting(Instruction *I, PHINode *Phi) { +bool IVUsers::AddUsersIfInteresting(Instruction *I) { if (!SE->isSCEVable(I->getType())) return false; // Void and FP expressions cannot be reduced. @@ -136,13 +136,12 @@ bool AddUserToIVUsers = false; if (LI->getLoopFor(User->getParent()) != L) { if (isa(User) || Processed.count(User) || - !AddUsersIfInteresting(User, Phi)) { + !AddUsersIfInteresting(User)) { DEBUG(dbgs() << "FOUND USER in other loop: " << *User << '\n' << " OF SCEV: " << *ISE << '\n'); AddUserToIVUsers = true; } - } else if (Processed.count(User) || - !AddUsersIfInteresting(User, Phi)) { + } else if (Processed.count(User) || !AddUsersIfInteresting(User)) { DEBUG(dbgs() << "FOUND USER: " << *User << '\n' << " OF SCEV: " << *ISE << '\n'); AddUserToIVUsers = true; @@ -150,7 +149,7 @@ if (AddUserToIVUsers) { // Okay, we found a user that we cannot reduce. - IVUses.push_back(new IVStrideUse(this, User, I, Phi)); + IVUses.push_back(new IVStrideUse(this, User, I)); IVStrideUse &NewUse = IVUses.back(); // Autodetect the post-inc loop set, populating NewUse.PostIncLoops. // The regular return value here is discarded; instead of recording @@ -165,8 +164,8 @@ return true; } -IVStrideUse &IVUsers::AddUser(Instruction *User, Value *Operand, PHINode *Phi) { - IVUses.push_back(new IVStrideUse(this, User, Operand, Phi)); +IVStrideUse &IVUsers::AddUser(Instruction *User, Value *Operand) { + IVUses.push_back(new IVStrideUse(this, User, Operand)); return IVUses.back(); } @@ -194,7 +193,7 @@ // them by stride. Start by finding all of the PHI nodes in the header for // this loop. If they are induction variables, inspect their uses. for (BasicBlock::iterator I = L->getHeader()->begin(); isa(I); ++I) - (void)AddUsersIfInteresting(I, cast(I)); + (void)AddUsersIfInteresting(I); return false; } Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=133518&r1=133517&r2=133518&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Tue Jun 21 10:43:52 2011 @@ -131,8 +131,7 @@ void EliminateIVComparison(ICmpInst *ICmp, Value *IVOperand); void EliminateIVRemainder(BinaryOperator *Rem, Value *IVOperand, - bool IsSigned, - PHINode *IVPhi); + bool IsSigned); void pushIVUsers(Instruction *Def); bool isSimpleIVUser(Instruction *I, const Loop *L); void RewriteNonIntegerIVs(Loop *L); @@ -523,7 +522,7 @@ if (BinaryOperator *Rem = dyn_cast(UseInst)) { bool IsSigned = Rem->getOpcode() == Instruction::SRem; if (IsSigned || Rem->getOpcode() == Instruction::URem) { - EliminateIVRemainder(Rem, IVOperand, IsSigned, I->getPhi()); + EliminateIVRemainder(Rem, IVOperand, IsSigned); continue; } } @@ -946,8 +945,7 @@ void IndVarSimplify::EliminateIVRemainder(BinaryOperator *Rem, Value *IVOperand, - bool IsSigned, - PHINode *IVPhi) { + bool IsSigned) { // We're only interested in the case where we know something about // the numerator. if (IVOperand != Rem->getOperand(0)) @@ -992,7 +990,7 @@ // Inform IVUsers about the new users. if (IU) { if (Instruction *I = dyn_cast(Rem->getOperand(0))) - IU->AddUsersIfInteresting(I, IVPhi); + IU->AddUsersIfInteresting(I); } DEBUG(dbgs() << "INDVARS: Simplified rem: " << *Rem << '\n'); ++NumElimRem; @@ -1011,7 +1009,7 @@ if (BinaryOperator *Rem = dyn_cast(UseInst)) { bool IsSigned = Rem->getOpcode() == Instruction::SRem; if (IsSigned || Rem->getOpcode() == Instruction::URem) { - EliminateIVRemainder(Rem, IVOperand, IsSigned, CurrIV); + EliminateIVRemainder(Rem, IVOperand, IsSigned); return true; } } @@ -1283,8 +1281,7 @@ // For completeness, inform IVUsers of the IV use in the newly-created // loop exit test instruction. if (NewICmp && IU) - IU->AddUsersIfInteresting(cast(NewICmp->getOperand(0)), - IndVar); + IU->AddUsersIfInteresting(cast(NewICmp->getOperand(0))); // Clean up dead instructions. Changed |= DeleteDeadPHIs(L->getHeader()); @@ -1716,5 +1713,5 @@ // Add a new IVUsers entry for the newly-created integer PHI. if (IU) - IU->AddUsersIfInteresting(NewPHI, NewPHI); + IU->AddUsersIfInteresting(NewPHI); } Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=133518&r1=133517&r2=133518&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue Jun 21 10:43:52 2011 @@ -1804,8 +1804,7 @@ ExitingBlock->getInstList().insert(TermBr, Cond); // Clone the IVUse, as the old use still exists! - CondUse = &IU.AddUser(Cond, CondUse->getOperandValToReplace(), - CondUse->getPhi()); + CondUse = &IU.AddUser(Cond, CondUse->getOperandValToReplace()); TermBr->replaceUsesOfWith(OldCond, Cond); } } From aggarwa4 at illinois.edu Tue Jun 21 11:05:07 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Jun 2011 16:05:07 -0000 Subject: [llvm-commits] [poolalloc] r133520 - in /poolalloc/trunk: include/assistDS/TypeAnalysis.h include/assistDS/TypeChecks.h include/assistDS/TypeChecksCmpOpt.h include/assistDS/TypeChecksOpt.h lib/AssistDS/TypeAnalysis.cpp lib/AssistDS/TypeChecks.cpp lib/AssistDS/TypeChecksCmpOpt.cpp lib/AssistDS/TypeChecksOpt.cpp Message-ID: <20110621160507.284662A6C12C@llvm.org> Author: aggarwa4 Date: Tue Jun 21 11:05:06 2011 New Revision: 133520 URL: http://llvm.org/viewvc/llvm-project?rev=133520&view=rev Log: Move some optimizations to the instrumentation pass as options. Delete the rest of the files. Instrument the use of a load, instead of the load itself with the check. Removed: poolalloc/trunk/include/assistDS/TypeAnalysis.h poolalloc/trunk/include/assistDS/TypeChecksCmpOpt.h poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp poolalloc/trunk/lib/AssistDS/TypeChecksCmpOpt.cpp Modified: poolalloc/trunk/include/assistDS/TypeChecks.h poolalloc/trunk/include/assistDS/TypeChecksOpt.h poolalloc/trunk/lib/AssistDS/TypeChecks.cpp poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp Removed: poolalloc/trunk/include/assistDS/TypeAnalysis.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/TypeAnalysis.h?rev=133519&view=auto ============================================================================== --- poolalloc/trunk/include/assistDS/TypeAnalysis.h (original) +++ poolalloc/trunk/include/assistDS/TypeAnalysis.h (removed) @@ -1,41 +0,0 @@ -//===-- 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 bool runOnModule(Module& M); - virtual void getAnalysisUsage(AnalysisUsage &Info) const; - - const Type *getType(LoadInst *); - const Type *getType(StoreInst *); - bool isCopyingLoad(LoadInst *); - bool isCopyingStore(StoreInst *); - Value *getStoreSource(StoreInst *SI); - }; -} - Modified: poolalloc/trunk/include/assistDS/TypeChecks.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/TypeChecks.h?rev=133520&r1=133519&r2=133520&view=diff ============================================================================== --- poolalloc/trunk/include/assistDS/TypeChecks.h (original) +++ poolalloc/trunk/include/assistDS/TypeChecks.h Tue Jun 21 11:05:06 2011 @@ -14,7 +14,6 @@ #ifndef TYPE_CHECKS_H #define TYPE_CHECKS_H -#include "assistDS/TypeAnalysis.h" #include "dsa/AddressTakenAnalysis.h" #include "llvm/Instructions.h" @@ -47,7 +46,6 @@ // Analysis from other passes. TargetData *TD; - TypeAnalysis *TA; AddressTakenAnalysis* addrAnalysis; unsigned int getTypeMarker(const Type*); @@ -69,7 +67,6 @@ bool visitLoadInst(Module &M, LoadInst &LI); bool visitStoreInst(Module &M, StoreInst &SI); - bool visitCopyingStoreInst(Module &M, StoreInst &SI, Value *SS); bool visitAllocaInst(Module &M, AllocaInst &AI); bool visitGlobal(Module &M, GlobalVariable &GV, @@ -97,7 +94,6 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); - AU.addRequired(); AU.addRequired(); } Removed: poolalloc/trunk/include/assistDS/TypeChecksCmpOpt.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/TypeChecksCmpOpt.h?rev=133519&view=auto ============================================================================== --- poolalloc/trunk/include/assistDS/TypeChecksCmpOpt.h (original) +++ poolalloc/trunk/include/assistDS/TypeChecksCmpOpt.h (removed) @@ -1,46 +0,0 @@ -//=== TypeChecksCmpOpt.h - Remove runtime type checks for ptrs used in cmp ===// -// -// 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 removes type checks that are on values used in compares -// -//===----------------------------------------------------------------------===// - -#ifndef TYPE_CHECKS_CMP_OPT_H -#define TYPE_CHECKS_CMP_OPT_H - -#include "assistDS/TypeAnalysis.h" - -#include "llvm/Instructions.h" -#include "llvm/Pass.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Support/CallSite.h" - -#include - -namespace llvm { - -class Type; -class Value; - -class TypeChecksCmpOpt : public ModulePass { - -private: - - std::set toDelete; - -public: - static char ID; - TypeChecksCmpOpt() : ModulePass(&ID) {} - virtual bool runOnModule(Module &M); - -}; - -} // End llvm namespace - -#endif Modified: poolalloc/trunk/include/assistDS/TypeChecksOpt.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/TypeChecksOpt.h?rev=133520&r1=133519&r2=133520&view=diff ============================================================================== --- poolalloc/trunk/include/assistDS/TypeChecksOpt.h (original) +++ poolalloc/trunk/include/assistDS/TypeChecksOpt.h Tue Jun 21 11:05:06 2011 @@ -14,7 +14,6 @@ #ifndef TYPE_CHECKS_OPT_H #define TYPE_CHECKS_OPT_H -#include "assistDS/TypeAnalysis.h" #include "dsa/TypeSafety.h" #include "dsa/AddressTakenAnalysis.h" Removed: poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp?rev=133519&view=auto ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp (removed) @@ -1,79 +0,0 @@ -//===-- 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 "llvm/Support/FormattedStream.h" -#include "llvm/Support/Debug.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(); -} - -bool -TypeAnalysis::isCopyingLoad(LoadInst *LI){ - if(LI->getNumUses() == 1) { - if(StoreInst *SI = dyn_cast(LI->use_begin())) { - if(SI->getOperand(0) == LI) { - return true; - } - } - } - // chk if passed through argument, and then stored. - return false; -} - - -bool -TypeAnalysis::isCopyingStore(StoreInst *SI) { - if(SI->getOperand(0)->getNumUses() == 1) { - if(isa(SI->getOperand(0))) { - return true; - } - } - return false; -} - -Value * -TypeAnalysis::getStoreSource(StoreInst *SI) { - if(LoadInst *LI = dyn_cast(SI->getOperand(0))) { - return LI->getOperand(0); - } - return NULL; -} - - -void -TypeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); -} Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=133520&r1=133519&r2=133520&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Tue Jun 21 11:05:06 2011 @@ -44,6 +44,14 @@ cl::desc("DONT Distinguish pointer types"), cl::Hidden, cl::init(false)); + static cl::opt DisablePtrCmpChecks("no-ptr-cmp-checks", + cl::desc("Dont instrument cmp statements"), + cl::Hidden, + cl::init(false)); + static cl::opt TrackAllLoads("track-all-loads", + cl::desc("Check at all loads irrespective of use"), + cl::Hidden, + cl::init(false)); } static int tagCounter = 0; @@ -58,8 +66,9 @@ static Constant *trackInitInst; static Constant *trackUnInitInst; static Constant *trackStoreInst; -static Constant *trackLoadInst; +static Constant *checkTypeInst; static Constant *copyTypeInfo; +static Constant *setTypeInfo; static Constant *RegisterArgv; static Constant *RegisterEnvp; static Constant *compareTypeAndNumber; @@ -105,7 +114,6 @@ bool modified = false; // Flags whether we modified the module. TD = &getAnalysis(); - TA = &getAnalysis(); addrAnalysis = &getAnalysis(); // Create the necessary prototypes @@ -163,7 +171,7 @@ Int64Ty, /*size*/ VoidPtrTy, /*dest for type tag*/ NULL); - trackLoadInst = M.getOrInsertFunction("checkType", + checkTypeInst = M.getOrInsertFunction("checkType", VoidTy, Int8Ty,/*type*/ Int64Ty,/*size*/ @@ -171,6 +179,13 @@ VoidPtrTy,/*ptr*/ Int32Ty,/*tag*/ NULL); + setTypeInfo = M.getOrInsertFunction("setTypeInfo", + VoidTy, + VoidPtrTy,/*dest ptr*/ + VoidPtrTy,/*metadata*/ + Int64Ty,/*size*/ + Int32Ty,/*tag*/ + NULL); copyTypeInfo = M.getOrInsertFunction("copyTypeInfo", VoidTy, VoidPtrTy,/*dest ptr*/ @@ -310,18 +325,10 @@ for (inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE;++II) { Instruction &I = *II; if (StoreInst *SI = dyn_cast(&I)) { - if (TA->isCopyingStore(SI)) { - Value *SS = TA->getStoreSource(SI); - if (SS != NULL) { - modified |= visitCopyingStoreInst(M, *SI, SS); - } - } else { + if(!isa(SI->getOperand(0))) modified |= visitStoreInst(M, *SI); - } } else if (LoadInst *LI = dyn_cast(&I)) { - if (!TA->isCopyingLoad(LI)) { modified |= visitLoadInst(M, *LI); - } } else if (CallInst *CI = dyn_cast(&I)) { modified |= visitCallInst(M, *CI); } else if (InvokeInst *II = dyn_cast(&I)) { @@ -590,11 +597,12 @@ NII++; AllocaInst *Counter = new AllocaInst(Int64Ty, "",&*InsPt); new StoreInst(NII, Counter, &*InsPt); - CounterMap[NII] = Counter; + errs() << F->getNameStr() <<"\n"; NII++; AllocaInst *VAMDLoc = new AllocaInst(VoidPtrTy, "", &*InsPt); new StoreInst(NII, VAMDLoc, &*InsPt); + CounterMap[ValueMap[VAListArg]] = Counter; // Find all va_copy calls for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;I++) { @@ -625,7 +633,9 @@ if(!VI) continue; Constant *One = ConstantInt::get(Int64Ty, 1); + VI->getOperand(0)->stripPointerCasts()->dump(); Value *CounterSrc = CounterMap[VI->getOperand(0)->stripPointerCasts()]; + CounterSrc->dump(); LoadInst *OldValue = new LoadInst(CounterSrc, "count", VI); Instruction *NewValue = BinaryOperator::Create(BinaryOperator::Add, OldValue, @@ -1976,28 +1986,56 @@ Args1.push_back(BCI); Args1.push_back(getSizeConstant(LI.getType())); Args1.push_back(BCI_MD); - CallInst::Create(getTypeTag, Args1.begin(), Args1.end(), "", &LI); - std::vector Args; - Args.push_back(getTypeMarkerConstant(&LI)); - Args.push_back(getSizeConstant(LI.getType())); - Args.push_back(BCI_MD); - Args.push_back(BCI); - Args.push_back(getTagCounter()); - CallInst::Create(trackLoadInst, Args.begin(), Args.end(), "", &LI); - - /*for(Value::use_iterator II = LI.use_begin(); II != LI.use_end(); ++II) { + CallInst *getTypeCall = CallInst::Create(getTypeTag, Args1.begin(), Args1.end(), "", &LI); + if(TrackAllLoads) { + std::vector Args; + Args.push_back(getTypeMarkerConstant(&LI)); + Args.push_back(getSizeConstant(LI.getType())); + Args.push_back(BCI_MD); + Args.push_back(BCI); + Args.push_back(getTagCounter()); + CallInst::Create(checkTypeInst, Args.begin(), Args.end(), "", &LI); + } + for(Value::use_iterator II = LI.use_begin(); II != LI.use_end(); ++II) { + if(DisablePtrCmpChecks) { + if(isa(II)) { + if(LI.getType()->isPointerTy()) + continue; + } + } std::vector Args; Args.push_back(getTypeMarkerConstant(&LI)); Args.push_back(getSizeConstant(LI.getType())); Args.push_back(BCI_MD); Args.push_back(BCI); Args.push_back(getTagCounter()); - CallInst::Create(trackLoadInst, Args.begin(), Args.end(), "", cast(II.getUse().getUser())); - }*/ + if(StoreInst *SI = dyn_cast(II)) { + // Cast the pointer operand to i8* for the runtime function. + CastInst *BCI_Dest = BitCastInst::CreatePointerCast(SI->getPointerOperand(), VoidPtrTy, "", SI); + + std::vector Args; + Args.push_back(BCI_Dest); + Args.push_back(BCI_MD); + Args.push_back(getSizeConstant(SI->getOperand(0)->getType())); + Args.push_back(getTagCounter()); + // Create the call to the runtime check and place it before the copying store instruction. + CallInst::Create(setTypeInfo, Args.begin(), Args.end(), "", SI); + } + else if(PHINode *PH = dyn_cast(II)) { + BasicBlock *BB = PH->getIncomingBlock(II); + CallInst::Create(checkTypeInst, Args.begin(), Args.end(), "", BB->getTerminator()); + } else { + CallInst::Create(checkTypeInst, Args.begin(), Args.end(), "", cast(II.getUse().getUser())); + } + } + if(BCI_MD->getNumUses() == 1) { + // No uses needed checks + getTypeCall->eraseFromParent(); + } + // Create the call to the runtime check and place it before the load instruction. - //CallInst::Create(trackLoadInst, Args.begin(), Args.end(), "", &LI); numLoadChecks++; return true; } @@ -2020,21 +2058,3 @@ return true; } -// Insert runtime checks before copying store instructions. -bool TypeChecks::visitCopyingStoreInst(Module &M, StoreInst &SI, Value *SS) { - // Cast the pointer operand to i8* for the runtime function. - CastInst *BCI_Dest = BitCastInst::CreatePointerCast(SI.getPointerOperand(), VoidPtrTy, "", &SI); - CastInst *BCI_Src = BitCastInst::CreatePointerCast(SS, VoidPtrTy, "", &SI); - - std::vector Args; - Args.push_back(BCI_Dest); - Args.push_back(BCI_Src); - Args.push_back(getSizeConstant(SI.getOperand(0)->getType())); - Args.push_back(getTagCounter()); - - // Create the call to the runtime check and place it before the copying store instruction. - CallInst::Create(copyTypeInfo, Args.begin(), Args.end(), "", &SI); - numStoreChecks++; - - return true; -} Removed: poolalloc/trunk/lib/AssistDS/TypeChecksCmpOpt.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecksCmpOpt.cpp?rev=133519&view=auto ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecksCmpOpt.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecksCmpOpt.cpp (removed) @@ -1,97 +0,0 @@ -//===---------- TypeChecksOpt.h - Remove safe 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 removes type checks that are statically proven safe -// -//===----------------------------------------------------------------------===// - -#include "assistDS/TypeChecksCmpOpt.h" -#include "llvm/Constants.h" -#include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/Assembly/Writer.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/InstIterator.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Intrinsics.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/ADT/Statistic.h" - -#include -#include - -using namespace llvm; - -char TypeChecksCmpOpt::ID = 0; - -static RegisterPass -TC("typechecks-cmp-opt", "Remove runtime type checks", false, true); - -// Pass statistics -STATISTIC(numSafe, "Number of type checks on loads used in Cmp"); - -static const Type *VoidTy = 0; -static const Type *Int8Ty = 0; -static const Type *Int32Ty = 0; -static const Type *Int64Ty = 0; -static const PointerType *VoidPtrTy = 0; -static Constant *trackLoadInst; - -bool TypeChecksCmpOpt::runOnModule(Module &M) { - - // Create the necessary prototypes - VoidTy = IntegerType::getVoidTy(M.getContext()); - Int8Ty = IntegerType::getInt8Ty(M.getContext()); - Int32Ty = IntegerType::getInt32Ty(M.getContext()); - Int64Ty = IntegerType::getInt64Ty(M.getContext()); - VoidPtrTy = PointerType::getUnqual(Int8Ty); - - trackLoadInst = M.getOrInsertFunction("trackLoadInst", - VoidTy, - VoidPtrTy,/*ptr*/ - Int8Ty,/*type*/ - Int64Ty,/*size*/ - Int32Ty,/*tag*/ - NULL); - for(Value::use_iterator User = trackLoadInst->use_begin(); User != trackLoadInst->use_end(); ++User) { - CallInst *CI = dyn_cast(User); - assert(CI); - Value *LPtr = CI->getOperand(1)->stripPointerCasts(); - for(Value::use_iterator II = LPtr->use_begin(); II != LPtr->use_end(); ++II) { - if(LoadInst *LI = dyn_cast(II)) { - if(LI->getOperand(0) == LPtr) { - if(LI->getType()->isPointerTy()) { - bool allIcmpUse = true; - for(Value::use_iterator EE = LI->use_begin(); EE != LI->use_end(); ++EE) { - if(!isa(EE)) { - allIcmpUse = false; - break; - } - } - if(allIcmpUse) { - toDelete.insert(CI); - LI->dump(); - } - } - } - } - } - } - - numSafe += toDelete.size(); - - std::set::iterator II = toDelete.begin(); - for(; II != toDelete.end();) { - Instruction *I = *II++; - I->eraseFromParent(); - } - return (numSafe > 0); -} - Modified: poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp?rev=133520&r1=133519&r2=133520&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp Tue Jun 21 11:05:06 2011 @@ -49,6 +49,8 @@ static Constant *trackStoreInst; static Constant *trackLoadInst; static Constant *copyTypeInfo; +static Constant *setTypeInfo; +static Constant *checkTypeInst; static Constant *MallocFunc; bool TypeChecksOpt::runOnModule(Module &M) { @@ -94,6 +96,14 @@ Int64Ty,/*size*/ Int32Ty,/*tag*/ NULL); + checkTypeInst = M.getOrInsertFunction("checkType", + VoidTy, + Int8Ty,/*type*/ + Int64Ty,/*size*/ + VoidPtrTy, + VoidPtrTy,/*ptr*/ + Int32Ty,/*tag*/ + NULL); trackLoadInst = M.getOrInsertFunction("trackLoadInst", VoidTy, VoidPtrTy,/*ptr*/ @@ -108,6 +118,13 @@ Int64Ty,/*size*/ Int32Ty,/*tag*/ NULL); + setTypeInfo = M.getOrInsertFunction("setTypeInfo", + VoidTy, + VoidPtrTy,/*dest ptr*/ + VoidPtrTy,/*metadata*/ + Int64Ty,/*size*/ + Int32Ty,/*tag*/ + NULL); trackStringInput = M.getOrInsertFunction("trackStringInput", VoidTy, VoidPtrTy, @@ -128,11 +145,11 @@ } } - for(Value::use_iterator User = trackLoadInst->use_begin(); User != trackLoadInst->use_end(); ++User) { + for(Value::use_iterator User = checkTypeInst->use_begin(); User != checkTypeInst->use_end(); ++User) { CallInst *CI = dyn_cast(User); assert(CI); - if(TS->isTypeSafe(CI->getOperand(1)->stripPointerCasts(), CI->getParent()->getParent())) { + if(TS->isTypeSafe(CI->getOperand(4)->stripPointerCasts(), CI->getParent()->getParent())) { toDelete.push_back(CI); } } @@ -195,6 +212,19 @@ toDelete.push_back(CI); } } + for(Value::use_iterator User = setTypeInfo->use_begin(); User != setTypeInfo->use_end(); ++User) { + CallInst *CI = dyn_cast(User); + assert(CI); + + if(TS->isTypeSafe(CI->getOperand(1)->stripPointerCasts(), CI->getParent()->getParent())) { + std::vector Args; + Args.push_back(CI->getOperand(1)); + Args.push_back(CI->getOperand(3)); // size + Args.push_back(CI->getOperand(4)); + CallInst::Create(trackInitInst, Args.begin(), Args.end(), "", CI); + toDelete.push_back(CI); + } + } numSafe += toDelete.size(); From rjmccall at apple.com Tue Jun 21 12:00:06 2011 From: rjmccall at apple.com (John McCall) Date: Tue, 21 Jun 2011 10:00:06 -0700 Subject: [llvm-commits] [llvm] r133285 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp In-Reply-To: <4E008742.9030700@free.fr> References: <20110617202152.D6B812A6C12C@llvm.org> <4DFDF276.5030703@free.fr> <54E09593-01A1-4936-AFF8-7AF19D2C6919@apple.com> <4DFEF6DA.4030503@free.fr> <4E008742.9030700@free.fr> Message-ID: <07078D47-26CC-49FB-B53F-478A74D8A0FB@apple.com> On Jun 21, 2011, at 4:57 AM, Duncan Sands wrote: > I thought *you* were suggesting that we assume no overflow when you said "but > if we just assume by fiat that 2^31 is too large, then as long as the arithmetic > is being done in some reasonable size then we know that N * sizeof(T) isn't > permitted to signed overflow, either." I guess I misunderstood. I'm still not > sure what you were trying to say :) I was suggesting that we could make more aggressive restrictions on the size input to alloca based on a basic assumption that you can't grow your stack to >2GB, even on >32-bit architectures. But if we want to support that, then obviously this needs to be based on the pointer width. > That's the whole point of this discussion. >> There's an implicit multiply in sizeof(sp) as part of the alloca instruction, and >> it's undefined behavior if either >> - that multiply causes unsigned overflow or > > Sure. > >> - either the input or output to that multiply is negative. > > Why? Are you saying that an alloca of 2^31 i8's should be considered to result > in undefined behaviour? On a 32-bit machine, yes. Are you really saying that we need to support any argument to alloca that's smaller than the addressable space of the machine? If so, this transformation is completely dead; feel free to remove it. > And what about this: alloca i8, i8 128 I did say "in sizeof(sp)" above. John. From rjmccall at apple.com Tue Jun 21 12:01:29 2011 From: rjmccall at apple.com (John McCall) Date: Tue, 21 Jun 2011 10:01:29 -0700 Subject: [llvm-commits] [llvm] r133285 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp In-Reply-To: <4E008742.9030700@free.fr> References: <20110617202152.D6B812A6C12C@llvm.org> <4DFDF276.5030703@free.fr> <54E09593-01A1-4936-AFF8-7AF19D2C6919@apple.com> <4DFEF6DA.4030503@free.fr> <4E008742.9030700@free.fr> Message-ID: <44CEB331-FBEC-4A3F-B171-BCEFCED6A3D8@apple.com> On Jun 21, 2011, at 4:57 AM, Duncan Sands wrote: > I thought *you* were suggesting that we assume no overflow when you said "but > if we just assume by fiat that 2^31 is too large, then as long as the arithmetic > is being done in some reasonable size then we know that N * sizeof(T) isn't > permitted to signed overflow, either." I guess I misunderstood. I'm still not > sure what you were trying to say :) I was suggesting that we could make more aggressive restrictions on the size input to alloca based on a basic assumption that you can't grow your stack to >2GB, even on >32-bit architectures. But if we want to support that, then obviously this needs to be based on the pointer width. > That's the whole point of this discussion. >> There's an implicit multiply in sizeof(sp) as part of the alloca instruction, and >> it's undefined behavior if either >> - that multiply causes unsigned overflow or > > Sure. > >> - either the input or output to that multiply is negative. > > Why? Are you saying that an alloca of 2^31 i8's should be considered to result > in undefined behaviour? On a 32-bit machine, yes. Are you really saying that we need to support any argument to alloca that's smaller than the addressable space of the machine? If so, this transformation is completely dead; feel free to remove it. > And what about this: alloca i8, i8 128 I did say "in sizeof(sp)" above. John. From rjmccall at apple.com Tue Jun 21 12:09:18 2011 From: rjmccall at apple.com (John McCall) Date: Tue, 21 Jun 2011 10:09:18 -0700 Subject: [llvm-commits] [llvm] r133412 - in /llvm/trunk: include/llvm/Constants.h lib/Analysis/ConstantFolding.cpp lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/CodeGen/ShadowStackGC.cpp lib/Transforms/IPO/GlobalOpt.cpp lib/Transform In-Reply-To: References: <6ACAF514-D83B-46F3-BBD9-13F295FB1FA2@nondot.org> Message-ID: <31BCDD79-78B7-4F94-AD16-AA8290D140D1@apple.com> On Jun 21, 2011, at 12:22 AM, Jay Foad wrote: >>> Patch 1 extends ConstantUniqueMap with a new template parameter >>> ValRefType, representing a const reference to ValType. Normally this >>> would just be const ValType&, but when ValType is a std::vector, we >>> want to use ArrayRef as the reference type. > >> Wow, looks great to me Jay > > Just to double check, are you OK with me adding the conversion operator > > ArrayRef::operator std::vector() const; This is best avoided if possible. John. From ganna at apple.com Tue Jun 21 12:18:15 2011 From: ganna at apple.com (Anna Zaks) Date: Tue, 21 Jun 2011 17:18:15 -0000 Subject: [llvm-commits] [llvm] r133522 - in /llvm/trunk: lib/Target/CBackend/CBackend.cpp test/CodeGen/CBackend/2011-06-08-addWithOverflow.ll Message-ID: <20110621171815.3E9482A6C12C@llvm.org> Author: zaks Date: Tue Jun 21 12:18:15 2011 New Revision: 133522 URL: http://llvm.org/viewvc/llvm-project?rev=133522&view=rev Log: Add support for sadd.with.overflow and uadd.with.overflow intrinsics to the CBackend by emitting definitions for each intrinsic that occurs in the module. Added: llvm/trunk/test/CodeGen/CBackend/2011-06-08-addWithOverflow.ll Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=133522&r1=133521&r2=133522&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Tue Jun 21 12:18:15 2011 @@ -205,6 +205,9 @@ std::string InterpretASMConstraint(InlineAsm::ConstraintInfo& c); void lowerIntrinsics(Function &F); + /// Prints the definition of the intrinsic function F. Supports the + /// intrinsics which need to be explicitly defined in the CBackend. + void printIntrinsicDefinition(const Function &F, raw_ostream &Out); void printModuleTypes(const TypeSymbolTable &ST); void printContainedStructs(const Type *Ty, std::set &); @@ -1777,6 +1780,7 @@ Out << "/* Provide Declarations */\n"; Out << "#include \n"; // Varargs support Out << "#include \n"; // Unwind support + Out << "#include \n"; // With overflow intrinsics support. generateCompilerSpecificCode(Out, TD); // Provide a definition for `bool' if not compiling with a C++ compiler. @@ -1855,29 +1859,46 @@ Out << "float fmodf(float, float);\n"; Out << "long double fmodl(long double, long double);\n"; + // Store the intrinsics which will be declared/defined below. + SmallVector intrinsicsToDefine; + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { // Don't print declarations for intrinsic functions. - if (!I->isIntrinsic() && I->getName() != "setjmp" && - I->getName() != "longjmp" && I->getName() != "_setjmp") { - if (I->hasExternalWeakLinkage()) - Out << "extern "; - printFunctionSignature(I, true); - if (I->hasWeakLinkage() || I->hasLinkOnceLinkage()) - Out << " __ATTRIBUTE_WEAK__"; - if (I->hasExternalWeakLinkage()) - Out << " __EXTERNAL_WEAK__"; - if (StaticCtors.count(I)) - Out << " __ATTRIBUTE_CTOR__"; - if (StaticDtors.count(I)) - Out << " __ATTRIBUTE_DTOR__"; - if (I->hasHiddenVisibility()) - Out << " __HIDDEN__"; + // Store the used intrinsics, which need to be explicitly defined. + if (I->isIntrinsic()) { + switch (I->getIntrinsicID()) { + default: + break; + case Intrinsic::uadd_with_overflow: + case Intrinsic::sadd_with_overflow: + intrinsicsToDefine.push_back(I); + break; + } + continue; + } - if (I->hasName() && I->getName()[0] == 1) - Out << " LLVM_ASM(\"" << I->getName().substr(1) << "\")"; + if (I->getName() == "setjmp" || + I->getName() == "longjmp" || I->getName() == "_setjmp") + continue; + + if (I->hasExternalWeakLinkage()) + Out << "extern "; + printFunctionSignature(I, true); + if (I->hasWeakLinkage() || I->hasLinkOnceLinkage()) + Out << " __ATTRIBUTE_WEAK__"; + if (I->hasExternalWeakLinkage()) + Out << " __EXTERNAL_WEAK__"; + if (StaticCtors.count(I)) + Out << " __ATTRIBUTE_CTOR__"; + if (StaticDtors.count(I)) + Out << " __ATTRIBUTE_DTOR__"; + if (I->hasHiddenVisibility()) + Out << " __HIDDEN__"; - Out << ";\n"; - } + if (I->hasName() && I->getName()[0] == 1) + Out << " LLVM_ASM(\"" << I->getName().substr(1) << "\")"; + + Out << ";\n"; } // Output the global variable declarations @@ -2012,6 +2033,14 @@ Out << "return X <= Y ; }\n"; Out << "static inline int llvm_fcmp_oge(double X, double Y) { "; Out << "return X >= Y ; }\n"; + + // Emit definitions of the intrinsics. + for (SmallVector::const_iterator + I = intrinsicsToDefine.begin(), + E = intrinsicsToDefine.end(); I != E; ++I) { + printIntrinsicDefinition(**I, Out); + } + return false; } @@ -2786,6 +2815,101 @@ Out << "))"; } +// Returns the macro name or value of the max or min of an integer type +// (as defined in limits.h). +static void printLimitValue(const IntegerType &Ty, bool isSigned, bool isMax, + raw_ostream &Out) { + const char* type; + const char* sprefix = ""; + + unsigned NumBits = Ty.getBitWidth(); + if (NumBits <= 8) { + type = "CHAR"; + sprefix = "S"; + } else if (NumBits <= 16) { + type = "SHRT"; + } else if (NumBits <= 32) { + type = "INT"; + } else if (NumBits <= 64) { + type = "LLONG"; + } else { + llvm_unreachable("Bit widths > 64 not implemented yet"); + } + + if (isSigned) + Out << sprefix << type << (isMax ? "_MAX" : "_MIN"); + else + Out << "U" << type << (isMax ? "_MAX" : "0"); +} + +static bool isSupportedIntegerSize(const IntegerType &T) { + return T.getBitWidth() == 8 || T.getBitWidth() == 16 || + T.getBitWidth() == 32 || T.getBitWidth() == 64; +} + +void CWriter::printIntrinsicDefinition(const Function &F, raw_ostream &Out) { + const FunctionType *funT = F.getFunctionType(); + const Type *retT = F.getReturnType(); + const IntegerType *elemT = cast(funT->getParamType(1)); + + assert(isSupportedIntegerSize(*elemT) && + "CBackend does not support arbitrary size integers."); + assert(cast(retT)->getElementType(0) == elemT && + elemT == funT->getParamType(0) && funT->getNumParams() == 2); + + switch (F.getIntrinsicID()) { + default: + llvm_unreachable("Unsupported Intrinsic."); + case Intrinsic::uadd_with_overflow: + // static inline Rty uadd_ixx(unsigned ixx a, unsigned ixx b) { + // Rty r; + // r.field0 = a + b; + // r.field1 = (r.field0 < a); + // return r; + // } + Out << "static inline "; + printType(Out, retT); + Out << GetValueName(&F); + Out << "("; + printSimpleType(Out, elemT, false); + Out << "a,"; + printSimpleType(Out, elemT, false); + Out << "b) {\n "; + printType(Out, retT); + Out << "r;\n"; + Out << " r.field0 = a + b;\n"; + Out << " r.field1 = (r.field0 < a);\n"; + Out << " return r;\n}\n"; + break; + + case Intrinsic::sadd_with_overflow: + // static inline Rty sadd_ixx(ixx a, ixx b) { + // Rty r; + // r.field1 = (b > 0 && a > XX_MAX - b) || + // (b < 0 && a < XX_MIN - b); + // r.field0 = r.field1 ? 0 : a + b; + // return r; + // } + Out << "static "; + printType(Out, retT); + Out << GetValueName(&F); + Out << "("; + printSimpleType(Out, elemT, true); + Out << "a,"; + printSimpleType(Out, elemT, true); + Out << "b) {\n "; + printType(Out, retT); + Out << "r;\n"; + Out << " r.field1 = (b > 0 && a > "; + printLimitValue(*elemT, true, true, Out); + Out << " - b) || (b < 0 && a < "; + printLimitValue(*elemT, true, false, Out); + Out << " - b);\n"; + Out << " r.field0 = r.field1 ? 0 : a + b;\n"; + Out << " return r;\n}\n"; + break; + } +} void CWriter::lowerIntrinsics(Function &F) { // This is used to keep track of intrinsics that get generated to a lowered @@ -2816,6 +2940,8 @@ case Intrinsic::x86_sse2_cmp_sd: case Intrinsic::x86_sse2_cmp_pd: case Intrinsic::ppc_altivec_lvsl: + case Intrinsic::uadd_with_overflow: + case Intrinsic::sadd_with_overflow: // We directly implement these intrinsics break; default: @@ -3109,6 +3235,14 @@ writeOperand(I.getArgOperand(0)); Out << ")"; return true; + case Intrinsic::uadd_with_overflow: + case Intrinsic::sadd_with_overflow: + Out << GetValueName(I.getCalledFunction()) << "("; + writeOperand(I.getArgOperand(0)); + Out << ", "; + writeOperand(I.getArgOperand(1)); + Out << ")"; + return true; } } Added: llvm/trunk/test/CodeGen/CBackend/2011-06-08-addWithOverflow.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CBackend/2011-06-08-addWithOverflow.ll?rev=133522&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CBackend/2011-06-08-addWithOverflow.ll (added) +++ llvm/trunk/test/CodeGen/CBackend/2011-06-08-addWithOverflow.ll Tue Jun 21 12:18:15 2011 @@ -0,0 +1,35 @@ +; RUN: llc < %s -march=c +; Check that uadd and sadd with overflow are handled by C Backend. + +%0 = type { i32, i1 } ; type %0 + +define i1 @func1(i32 zeroext %v1, i32 zeroext %v2) nounwind { +entry: + %t = call %0 @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) ; <%0> [#uses=1] + %obit = extractvalue %0 %t, 1 ; [#uses=1] + br i1 %obit, label %carry, label %normal + +normal: ; preds = %entry + ret i1 true + +carry: ; preds = %entry + ret i1 false +} + +define i1 @func2(i32 signext %v1, i32 signext %v2) nounwind { +entry: + %t = call %0 @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) ; <%0> [#uses=1] + %obit = extractvalue %0 %t, 1 ; [#uses=1] + br i1 %obit, label %carry, label %normal + +normal: ; preds = %entry + ret i1 true + +carry: ; preds = %entry + ret i1 false +} + +declare %0 @llvm.sadd.with.overflow.i32(i32, i32) nounwind + +declare %0 @llvm.uadd.with.overflow.i32(i32, i32) nounwind + From eli.friedman at gmail.com Tue Jun 21 12:32:12 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Tue, 21 Jun 2011 10:32:12 -0700 Subject: [llvm-commits] [llvm] r133240 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp In-Reply-To: <20110617055451.24CFF2A6C12C@llvm.org> References: <20110617055451.24CFF2A6C12C@llvm.org> Message-ID: On Thu, Jun 16, 2011 at 10:54 PM, Rafael Espindola wrote: > Author: rafael > Date: Fri Jun 17 00:54:50 2011 > New Revision: 133240 > > URL: http://llvm.org/viewvc/llvm-project?rev=133240&view=rev > Log: > Enable early duplication of small blocks. There are still improvements to > be made, but this is already a win. > > Modified: > ? ?llvm/trunk/lib/CodeGen/TailDuplication.cpp This commit appears to be causing a significant performance regression on a couple tests in the test-suite for x86-32; test-suite/SingleSource/Benchmarks/Shootout-C++/matrix.cpp is a good example (3.3s before, 4.1s after). Would you mind taking a look to see if anything unexpected is happening? -Eli From jay.foad at gmail.com Tue Jun 21 12:34:11 2011 From: jay.foad at gmail.com (Jay Foad) Date: Tue, 21 Jun 2011 18:34:11 +0100 Subject: [llvm-commits] [llvm] r133412 - in /llvm/trunk: include/llvm/Constants.h lib/Analysis/ConstantFolding.cpp lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/CodeGen/ShadowStackGC.cpp lib/Transforms/IPO/GlobalOpt.cpp lib/Transform In-Reply-To: <31BCDD79-78B7-4F94-AD16-AA8290D140D1@apple.com> References: <6ACAF514-D83B-46F3-BBD9-13F295FB1FA2@nondot.org> <31BCDD79-78B7-4F94-AD16-AA8290D140D1@apple.com> Message-ID: On 21 June 2011 18:09, John McCall wrote: > On Jun 21, 2011, at 12:22 AM, Jay Foad wrote: >>>> Patch 1 extends ConstantUniqueMap with a new template parameter >>>> ValRefType, representing a const reference to ValType. Normally this >>>> would just be const ValType&, but when ValType is a std::vector, we >>>> want to use ArrayRef as the reference type. >> >>> Wow, looks great to me Jay >> >> Just to double check, are you OK with me adding the conversion operator >> >> ?ArrayRef::operator std::vector() const; > > This is best avoided if possible. Any particular reason? Any alternative suggestions? Thanks, Jay. From bob.wilson at apple.com Tue Jun 21 12:35:14 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 21 Jun 2011 17:35:14 -0000 Subject: [llvm-commits] [llvm] r133524 - in /llvm/trunk: lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/bitcast2.ll test/CodeGen/X86/vec_set-8.ll test/CodeGen/X86/vec_set-9.ll test/CodeGen/X86/vec_set-C.ll test/CodeGen/X86/vec_shuffle-14.ll test/CodeGen/X86/vec_shuffle-17.ll test/MC/X86/x86-64.s test/MC/X86/x86_64-avx-encoding.s Message-ID: <20110621173514.37DDA2A6C12C@llvm.org> Author: bwilson Date: Tue Jun 21 12:35:13 2011 New Revision: 133524 URL: http://llvm.org/viewvc/llvm-project?rev=133524&view=rev Log: Revert r133452: "Emit movq for 64-bit register to XMM register moves..." This is breaking compiler-rt and llvm-gcc builds on MacOSX when not using the integrated assembler. Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/test/CodeGen/X86/bitcast2.ll llvm/trunk/test/CodeGen/X86/vec_set-8.ll llvm/trunk/test/CodeGen/X86/vec_set-9.ll llvm/trunk/test/CodeGen/X86/vec_set-C.ll llvm/trunk/test/CodeGen/X86/vec_shuffle-14.ll llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll llvm/trunk/test/MC/X86/x86-64.s llvm/trunk/test/MC/X86/x86_64-avx-encoding.s Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=133524&r1=133523&r2=133524&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Tue Jun 21 12:35:13 2011 @@ -2850,11 +2850,11 @@ [(set VR128:$dst, (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>; def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src), - "movq\t{$src, $dst|$dst, $src}", + "mov{d|q}\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (v2i64 (scalar_to_vector GR64:$src)))]>; def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src), - "movq\t{$src, $dst|$dst, $src}", + "mov{d|q}\t{$src, $dst|$dst, $src}", [(set FR64:$dst, (bitconvert GR64:$src))]>; @@ -2895,7 +2895,7 @@ (iPTR 0))), addr:$dst)]>; def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src), - "movq\t{$src, $dst|$dst, $src}", + "mov{d|q}\t{$src, $dst|$dst, $src}", [(set GR64:$dst, (vector_extract (v2i64 VR128:$src), (iPTR 0)))]>; def MOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src), @@ -2903,7 +2903,7 @@ [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>; def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src), - "movq\t{$src, $dst|$dst, $src}", + "mov{d|q}\t{$src, $dst|$dst, $src}", [(set GR64:$dst, (bitconvert FR64:$src))]>; def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src), "movq\t{$src, $dst|$dst, $src}", @@ -2931,7 +2931,7 @@ (v4i32 (scalar_to_vector GR32:$src)))))]>, VEX; def VMOVZQI2PQIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src), - "movq\t{$src, $dst|$dst, $src}", // X86-64 only + "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))))]>, VEX, VEX_W; @@ -2942,7 +2942,7 @@ [(set VR128:$dst, (v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))))]>; def MOVZQI2PQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src), - "movq\t{$src, $dst|$dst, $src}", // X86-64 only + "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))))]>; } @@ -2968,21 +2968,6 @@ (MOVZDI2PDIrm addr:$src)>; } -// We used to emit this syntax to work around a bug in the Darwin assembler, -// so we'll continue to assemble it. -def : InstAlias<"movd\t{$src, $dst|$dst, $src}", - (MOV64toPQIrr VR128:$dst, GR64:$src), 0>; -def : InstAlias<"movd\t{$src, $dst|$dst, $src}", - (MOV64toSDrr FR64:$dst, GR64:$src), 0>; -def : InstAlias<"movd\t{$src, $dst|$dst, $src}", - (MOVPQIto64rr GR64:$dst, VR128:$src), 0>; -def : InstAlias<"movd\t{$src, $dst|$dst, $src}", - (MOVSDto64rr GR64:$dst, FR64:$src), 0>; -def : InstAlias<"movd\t{$src, $dst|$dst, $src}", - (VMOVZQI2PQIrr VR128:$dst, GR64:$src), 0>; -def : InstAlias<"movd\t{$src, $dst|$dst, $src}", - (MOVZQI2PQIrr VR128:$dst, GR64:$src), 0>; - //===---------------------------------------------------------------------===// // SSE2 - Move Quadword //===---------------------------------------------------------------------===// Modified: llvm/trunk/test/CodeGen/X86/bitcast2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bitcast2.ll?rev=133524&r1=133523&r2=133524&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/bitcast2.ll (original) +++ llvm/trunk/test/CodeGen/X86/bitcast2.ll Tue Jun 21 12:35:13 2011 @@ -1,31 +1,13 @@ -; RUN: llc < %s -march=x86-64 | FileCheck %s +; RUN: llc < %s -march=x86-64 | grep movd | count 2 ; RUN: llc < %s -march=x86-64 | not grep rsp define i64 @test1(double %A) { -; CHECK: test1 -; CHECK: movq %B = bitcast double %A to i64 ret i64 %B } define double @test2(i64 %A) { -; CHECK: test2 -; CHECK: movq %B = bitcast i64 %A to double ret double %B } -define i32 @test3(float %A) { -; CHECK: test3 -; CHECK: movd - %B = bitcast float %A to i32 - ret i32 %B -} - -define float @test4(i32 %A) { -; CHECK: test4 -; CHECK: movd - %B = bitcast i32 %A to float - ret float %B -} - Modified: llvm/trunk/test/CodeGen/X86/vec_set-8.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_set-8.ll?rev=133524&r1=133523&r2=133524&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_set-8.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_set-8.ll Tue Jun 21 12:35:13 2011 @@ -1,7 +1,7 @@ ; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s ; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s ; CHECK-NOT: movsd -; CHECK: movq {{%rdi|%rcx}}, %xmm0 +; CHECK: movd {{%rdi|%rcx}}, %xmm0 ; CHECK-NOT: movsd define <2 x i64> @test(i64 %i) nounwind { Modified: llvm/trunk/test/CodeGen/X86/vec_set-9.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_set-9.ll?rev=133524&r1=133523&r2=133524&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_set-9.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_set-9.ll Tue Jun 21 12:35:13 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 | grep movq | count 1 +; RUN: llc < %s -march=x86-64 | grep movd | count 1 ; RUN: llc < %s -march=x86-64 | grep {movlhps.*%xmm0, %xmm0} define <2 x i64> @test3(i64 %A) nounwind { Modified: llvm/trunk/test/CodeGen/X86/vec_set-C.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_set-C.ll?rev=133524&r1=133523&r2=133524&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_set-C.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_set-C.ll Tue Jun 21 12:35:13 2011 @@ -1,6 +1,6 @@ ; RUN: llc < %s -march=x86 -mattr=+sse2 | grep movq ; RUN: llc < %s -march=x86 -mattr=+sse2 | grep mov | count 1 -; RUN: llc < %s -march=x86-64 -mattr=+sse2 | grep movq +; RUN: llc < %s -march=x86-64 -mattr=+sse2 | grep movd define <2 x i64> @t1(i64 %x) nounwind { %tmp8 = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0 Modified: llvm/trunk/test/CodeGen/X86/vec_shuffle-14.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_shuffle-14.ll?rev=133524&r1=133523&r2=133524&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_shuffle-14.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_shuffle-14.ll Tue Jun 21 12:35:13 2011 @@ -1,7 +1,7 @@ ; RUN: llc < %s -march=x86 -mattr=+sse2 ; RUN: llc < %s -march=x86 -mattr=+sse2 | grep movd | count 1 -; RUN: llc < %s -march=x86-64 -mattr=+sse2 | grep movd | count 1 -; RUN: llc < %s -march=x86-64 -mattr=+sse2 | grep movq | count 4 +; RUN: llc < %s -march=x86-64 -mattr=+sse2 | grep movd | count 2 +; RUN: llc < %s -march=x86-64 -mattr=+sse2 | grep movq | count 3 ; RUN: llc < %s -march=x86 -mattr=+sse2 | not grep xor define <4 x i32> @t1(i32 %a) nounwind { Modified: llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll?rev=133524&r1=133523&r2=133524&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll Tue Jun 21 12:35:13 2011 @@ -1,7 +1,7 @@ ; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s ; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s ; CHECK-NOT: xor -; CHECK: movq {{%rdi|%rcx}}, %xmm0 +; CHECK: movd {{%rdi|%rcx}}, %xmm0 ; CHECK-NOT: xor ; PR2108 Modified: llvm/trunk/test/MC/X86/x86-64.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-64.s?rev=133524&r1=133523&r2=133524&view=diff ============================================================================== --- llvm/trunk/test/MC/X86/x86-64.s (original) +++ llvm/trunk/test/MC/X86/x86-64.s Tue Jun 21 12:35:13 2011 @@ -1128,11 +1128,3 @@ // CHECK: strq // CHECK: encoding: [0x48,0x0f,0x00,0xc8] str %rax - -// CHECK: movq %rdi, %xmm0 -// CHECK: encoding: [0x66,0x48,0x0f,0x6e,0xc7] - movq %rdi,%xmm0 - -// CHECK: movq %rdi, %xmm0 -// CHECK: encoding: [0x66,0x48,0x0f,0x6e,0xc7] - movd %rdi,%xmm0 Modified: llvm/trunk/test/MC/X86/x86_64-avx-encoding.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86_64-avx-encoding.s?rev=133524&r1=133523&r2=133524&view=diff ============================================================================== --- llvm/trunk/test/MC/X86/x86_64-avx-encoding.s (original) +++ llvm/trunk/test/MC/X86/x86_64-avx-encoding.s Tue Jun 21 12:35:13 2011 @@ -1444,9 +1444,9 @@ // CHECK: encoding: [0xc5,0x79,0x7e,0x30] vmovd %xmm14, (%rax) -// CHECK: vmovd %eax, %xmm14 -// CHECK: encoding: [0xc5,0x79,0x6e,0xf0] - vmovd %eax, %xmm14 +// CHECK: vmovd %rax, %xmm14 +// CHECK: encoding: [0xc4,0x61,0xf9,0x6e,0xf0] + vmovd %rax, %xmm14 // CHECK: vmovq %xmm14, (%rax) // CHECK: encoding: [0xc5,0x79,0xd6,0x30] From bob.wilson at apple.com Tue Jun 21 12:41:28 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 21 Jun 2011 10:41:28 -0700 Subject: [llvm-commits] [llvm] r133452 - in /llvm/trunk: lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/bitcast2.ll test/CodeGen/X86/vec_set-8.ll test/CodeGen/X86/vec_set-9.ll test/CodeGen/X86/vec_set-C.ll test/CodeGen/X86/vec_shuffle-14.ll test/CodeGen/X86/vec_shuffle-17.ll test/MC/X86/x86-64.s test/MC/X86/x86_64-avx-encoding.s In-Reply-To: <4DFFE225.5010807@mymail.mines.edu> References: <20110620183327.3F55D2A6C12C@llvm.org> <4DFFE225.5010807@mymail.mines.edu> Message-ID: <717AC852-C537-4E0D-897A-A5CCD813C011@apple.com> On Jun 20, 2011, at 5:13 PM, Charles Davis wrote: > On 6/20/11 12:33 PM, Nick Lewycky wrote: >> Author: nicholas >> Date: Mon Jun 20 13:33:26 2011 >> New Revision: 133452 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=133452&view=rev >> Log: >> Emit movq for 64-bit register to XMM register moves, but continue to accept >> movd when assembling. > This breaks compiling compiler-rt on Mac OS X like so: > > /tmp/cc-E8HNBz.s:7:suffix or operands invalid for `movq' > clang: error: assembler command failed with exit code 1 (use -v to see > invocation) > make[5]: *** > [.../llvm/build1/tools/clang/runtime/compiler-rt/clang_darwin/cc_kext/x86_64/SubDir.lib/fixdfti.o] > Error 1 > > There are several more errors like that. > > Xcode 4.0's assembler still has the movq bug. We still have to produce > movd on Darwin when not using the integrated assembler. Yes, it's also breaking llvm-gcc building. I've reverted that change for now. From rjmccall at apple.com Tue Jun 21 12:45:38 2011 From: rjmccall at apple.com (John McCall) Date: Tue, 21 Jun 2011 10:45:38 -0700 Subject: [llvm-commits] [llvm] r133412 - in /llvm/trunk: include/llvm/Constants.h lib/Analysis/ConstantFolding.cpp lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/CodeGen/ShadowStackGC.cpp lib/Transforms/IPO/GlobalOpt.cpp lib/Transform In-Reply-To: References: <6ACAF514-D83B-46F3-BBD9-13F295FB1FA2@nondot.org> <31BCDD79-78B7-4F94-AD16-AA8290D140D1@apple.com> Message-ID: <180C211B-0D38-4314-959F-680AAA1A61D9@apple.com> On Jun 21, 2011, at 10:34 AM, Jay Foad wrote: > On 21 June 2011 18:09, John McCall wrote: >> On Jun 21, 2011, at 12:22 AM, Jay Foad wrote: >>>>> Patch 1 extends ConstantUniqueMap with a new template parameter >>>>> ValRefType, representing a const reference to ValType. Normally this >>>>> would just be const ValType&, but when ValType is a std::vector, we >>>>> want to use ArrayRef as the reference type. >>> >>>> Wow, looks great to me Jay >>> >>> Just to double check, are you OK with me adding the conversion operator >>> >>> ArrayRef::operator std::vector() const; >> >> This is best avoided if possible. > > Any particular reason? Mostly I'm just skeptical of having an O(n) implicit conversion, but it also seems odd to privilege std::vector here. Why is this necessary? Template metaprogramming in the constants-map implementation? John. From jay.foad at gmail.com Tue Jun 21 13:35:28 2011 From: jay.foad at gmail.com (Jay Foad) Date: Tue, 21 Jun 2011 19:35:28 +0100 Subject: [llvm-commits] [llvm] r133412 - in /llvm/trunk: include/llvm/Constants.h lib/Analysis/ConstantFolding.cpp lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/CodeGen/ShadowStackGC.cpp lib/Transforms/IPO/GlobalOpt.cpp lib/Transform In-Reply-To: <180C211B-0D38-4314-959F-680AAA1A61D9@apple.com> References: <6ACAF514-D83B-46F3-BBD9-13F295FB1FA2@nondot.org> <31BCDD79-78B7-4F94-AD16-AA8290D140D1@apple.com> <180C211B-0D38-4314-959F-680AAA1A61D9@apple.com> Message-ID: > Mostly I'm just skeptical of having an O(n) implicit conversion, but it also seems > odd to privilege std::vector here. I'm probably biased by what I'm trying to do now, but I'm thinking of ArrayRef as a more flexible replacement for "const vector &". (More flexible since it doesn't have to refer to a *vector*, it could refer to a C array or other things.) Since "const vector &" implicitly converts to vector, I don't see the problem with ArrayRef doing the same. > Why is this necessary? ?Template metaprogramming in the constants-map > implementation? Yes. We have something like: template class ConstantUniqueMap { void doSomething(ValRefType v) { ValType myVal = v; } } The template class is instantiated with things like ConstantUniqueMap ConstantUniqueMap ConstantUniqueMap, ArrayRef> In the last case, I want the flexibility of being able to pass (anything convertible to) an ArrayRef into doSomething(). Thanks, Jay. From rjmccall at apple.com Tue Jun 21 13:38:32 2011 From: rjmccall at apple.com (John McCall) Date: Tue, 21 Jun 2011 11:38:32 -0700 Subject: [llvm-commits] [llvm] r133412 - in /llvm/trunk: include/llvm/Constants.h lib/Analysis/ConstantFolding.cpp lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/CodeGen/ShadowStackGC.cpp lib/Transforms/IPO/GlobalOpt.cpp lib/Transform In-Reply-To: References: <6ACAF514-D83B-46F3-BBD9-13F295FB1FA2@nondot.org> <31BCDD79-78B7-4F94-AD16-AA8290D140D1@apple.com> <180C211B-0D38-4314-959F-680AAA1A61D9@apple.com> Message-ID: On Jun 21, 2011, at 11:35 AM, Jay Foad wrote: >> Mostly I'm just skeptical of having an O(n) implicit conversion, but it also seems >> odd to privilege std::vector here. > > I'm probably biased by what I'm trying to do now, but I'm thinking of > ArrayRef as a more flexible replacement for "const vector &". (More > flexible since it doesn't have to refer to a *vector*, it could refer > to a C array or other things.) Since "const vector &" implicitly > converts to vector, I don't see the problem with ArrayRef doing the > same. Well, I'm worried it'll cause trouble down the road, but I guess it's fine for now. John. From sabre at nondot.org Tue Jun 21 13:40:11 2011 From: sabre at nondot.org (Chris Lattner) Date: Tue, 21 Jun 2011 11:40:11 -0700 Subject: [llvm-commits] [llvm] r133412 - in /llvm/trunk: include/llvm/Constants.h lib/Analysis/ConstantFolding.cpp lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/CodeGen/ShadowStackGC.cpp lib/Transforms/IPO/GlobalOpt.cpp lib/Transform In-Reply-To: References: <6ACAF514-D83B-46F3-BBD9-13F295FB1FA2@nondot.org> Message-ID: <87A7DCD7-1A1E-41F9-83EF-B675446B2830@nondot.org> On Jun 21, 2011, at 12:22 AM, Jay Foad wrote: >>> Patch 1 extends ConstantUniqueMap with a new template parameter >>> ValRefType, representing a const reference to ValType. Normally this >>> would just be const ValType&, but when ValType is a std::vector, we >>> want to use ArrayRef as the reference type. > >> Wow, looks great to me Jay > > Just to double check, are you OK with me adding the conversion operator > > ArrayRef::operator std::vector() const; I'm ok with it if there is no no other way, but.. > And should I remove the now redundant method which just did the same thing: > > std::vector ArrayRef::vec() const; I'd prefer to keep this. -Chris From clattner at apple.com Tue Jun 21 14:03:42 2011 From: clattner at apple.com (Chris Lattner) Date: Tue, 21 Jun 2011 12:03:42 -0700 Subject: [llvm-commits] [PATCH 0/5] Reduce memory usage for phi operands In-Reply-To: References: <1308222566-2451-1-git-send-email-jay.foad@gmail.com> <4737089F-10B2-4D3F-A9C5-B26E2D405674@apple.com> Message-ID: <09AF2EF4-8552-4FB1-8540-12A508008B9C@apple.com> On Jun 21, 2011, at 5:57 AM, Jay Foad wrote: >> If you're interested in another project, PR1324 would be another great memory reduction for apps with lots of strings and tables. > > This bug is about using a more compact representation of > ConstantArrays of ConstantInts. I think it will be easier to do this > for integers of a few pre-defined widths (i8. i16, i32, i64, maybe > even i1), rather than trying to handle arbitrarily wide integers. Does > this seem reasonable? That would be very reasonable. The biggest memory savings come from strings and other simple tables. I think that it would make sense to handle the "common" datatypes: arrays of i8/i16/i32/i64/float/double, which are the most common thing you see in tables. A sketch of the class could be something like: class ConstantDataArray { ? // To be used on arrays of ints. uint64_t getIntElement(uint64_t idx) // To be used on arrays of floats/doubles. APFloat getFloatElement(uint64_t idx) }; The actual data would then just be stored in a normal C array. To get one of these, the ConstantArray::get method would form one when the elements are simple enough, and clients like clang can use ConstantDataArray::get() directly for string constants and other cases. Using ConstantDataArray directly is useful because it avoids creating the Constant*'s for the elements at all. -Chris From evan.cheng at apple.com Tue Jun 21 14:00:54 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 21 Jun 2011 19:00:54 -0000 Subject: [llvm-commits] [llvm] r133533 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Message-ID: <20110621190054.740312A6C12C@llvm.org> Author: evancheng Date: Tue Jun 21 14:00:54 2011 New Revision: 133533 URL: http://llvm.org/viewvc/llvm-project?rev=133533&view=rev Log: Reorg. No functionality change. Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=133533&r1=133532&r2=133533&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Tue Jun 21 14:00:54 2011 @@ -1206,29 +1206,6 @@ } } // end isCodeGenOnly = 1 -// Signed and unsigned division on v7-M -def t2SDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi, - "sdiv", "\t$Rd, $Rn, $Rm", - [(set rGPR:$Rd, (sdiv rGPR:$Rn, rGPR:$Rm))]>, - Requires<[HasDivide, IsThumb2]> { - let Inst{31-27} = 0b11111; - let Inst{26-21} = 0b011100; - let Inst{20} = 0b1; - let Inst{15-12} = 0b1111; - let Inst{7-4} = 0b1111; -} - -def t2UDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi, - "udiv", "\t$Rd, $Rn, $Rm", - [(set rGPR:$Rd, (udiv rGPR:$Rn, rGPR:$Rm))]>, - Requires<[HasDivide, IsThumb2]> { - let Inst{31-27} = 0b11111; - let Inst{26-21} = 0b011101; - let Inst{20} = 0b1; - let Inst{15-12} = 0b1111; - let Inst{7-4} = 0b1111; -} - //===----------------------------------------------------------------------===// // Load / store Instructions. // @@ -2560,6 +2537,32 @@ "\t$Ra, $Rd, $Rm, $Rn", []>; //===----------------------------------------------------------------------===// +// Division Instructions. +// Signed and unsigned division on v7-M +// +def t2SDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi, + "sdiv", "\t$Rd, $Rn, $Rm", + [(set rGPR:$Rd, (sdiv rGPR:$Rn, rGPR:$Rm))]>, + Requires<[HasDivide, IsThumb2]> { + let Inst{31-27} = 0b11111; + let Inst{26-21} = 0b011100; + let Inst{20} = 0b1; + let Inst{15-12} = 0b1111; + let Inst{7-4} = 0b1111; +} + +def t2UDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi, + "udiv", "\t$Rd, $Rn, $Rm", + [(set rGPR:$Rd, (udiv rGPR:$Rn, rGPR:$Rm))]>, + Requires<[HasDivide, IsThumb2]> { + let Inst{31-27} = 0b11111; + let Inst{26-21} = 0b011101; + let Inst{20} = 0b1; + let Inst{15-12} = 0b1111; + let Inst{7-4} = 0b1111; +} + +//===----------------------------------------------------------------------===// // Misc. Arithmetic Instructions. // From clattner at apple.com Tue Jun 21 14:07:15 2011 From: clattner at apple.com (Chris Lattner) Date: Tue, 21 Jun 2011 12:07:15 -0700 Subject: [llvm-commits] [PATCH 0/5] Reduce memory usage for phi operands In-Reply-To: <09AF2EF4-8552-4FB1-8540-12A508008B9C@apple.com> References: <1308222566-2451-1-git-send-email-jay.foad@gmail.com> <4737089F-10B2-4D3F-A9C5-B26E2D405674@apple.com> <09AF2EF4-8552-4FB1-8540-12A508008B9C@apple.com> Message-ID: On Jun 21, 2011, at 12:03 PM, Chris Lattner wrote: > class ConstantDataArray { > ? > > // To be used on arrays of ints. > uint64_t getIntElement(uint64_t idx) > > // To be used on arrays of floats/doubles. > APFloat getFloatElement(uint64_t idx) Actually, since the client needs to handle the various element types specially, it would be better to just do: float getFloatElement(uint64_t idx) double getDoubleElement(uint64_t idx) directly, -Chris From dpatel at apple.com Tue Jun 21 14:46:09 2011 From: dpatel at apple.com (Devang Patel) Date: Tue, 21 Jun 2011 19:46:09 -0000 Subject: [llvm-commits] [llvm] r133536 - /llvm/trunk/lib/VMCore/AsmWriter.cpp Message-ID: <20110621194609.ED9AB2A6C12D@llvm.org> Author: dpatel Date: Tue Jun 21 14:46:09 2011 New Revision: 133536 URL: http://llvm.org/viewvc/llvm-project?rev=133536&view=rev Log: Remove r130409, as requested by Chris. Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=133536&r1=133535&r2=133536&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Tue Jun 21 14:46:09 2011 @@ -32,7 +32,6 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/CFG.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" @@ -42,11 +41,6 @@ #include using namespace llvm; -static cl::opt -EnableDebugInfoComment("enable-debug-info-comment", cl::Hidden, - cl::desc("Enable debug info comments")); - - // Make virtual table appear in this compilation unit. AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {} @@ -1767,18 +1761,6 @@ if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out); } -/// printDebugLoc - Print DebugLoc. -static void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) { - OS << DL.getLine() << ":" << DL.getCol(); - if (MDNode *N = DL.getInlinedAt(getGlobalContext())) { - DebugLoc IDL = DebugLoc::getFromDILocation(N); - if (!IDL.isUnknown()) { - OS << "@"; - printDebugLoc(IDL,OS); - } - } -} - /// printInfoComment - Print a little comment after the instruction indicating /// which slot it occupies. /// @@ -1786,43 +1768,6 @@ if (AnnotationWriter) { AnnotationWriter->printInfoComment(V, Out); return; - } else if (EnableDebugInfoComment) { - bool Padded = false; - if (const Instruction *I = dyn_cast(&V)) { - const DebugLoc &DL = I->getDebugLoc(); - if (!DL.isUnknown()) { - if (!Padded) { - Out.PadToColumn(50); - Padded = true; - Out << ";"; - } - Out << " [debug line = "; - printDebugLoc(DL,Out); - Out << "]"; - } - if (const DbgDeclareInst *DDI = dyn_cast(I)) { - const MDNode *Var = DDI->getVariable(); - if (!Padded) { - Out.PadToColumn(50); - Padded = true; - Out << ";"; - } - if (Var && Var->getNumOperands() >= 2) - if (MDString *MDS = dyn_cast_or_null(Var->getOperand(2))) - Out << " [debug variable = " << MDS->getString() << "]"; - } - else if (const DbgValueInst *DVI = dyn_cast(I)) { - const MDNode *Var = DVI->getVariable(); - if (!Padded) { - Out.PadToColumn(50); - Padded = true; - Out << ";"; - } - if (Var && Var->getNumOperands() >= 2) - if (MDString *MDS = dyn_cast_or_null(Var->getOperand(2))) - Out << " [debug variable = " << MDS->getString() << "]"; - } - } } } From daniel at zuster.org Tue Jun 21 15:05:16 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 21 Jun 2011 13:05:16 -0700 Subject: [llvm-commits] [llvm] r133206 - in /llvm/trunk: Makefile.config.in Makefile.rules autoconf/configure.ac In-Reply-To: <2123779D-92CE-47A4-A2D0-E5D0C1745948@apple.com> References: <20110616223039.2FDCF2A6C12C@llvm.org> <2123779D-92CE-47A4-A2D0-E5D0C1745948@apple.com> Message-ID: On Thu, Jun 16, 2011 at 4:03 PM, Eric Christopher wrote: > > On Jun 16, 2011, at 3:30 PM, Daniel Dunbar wrote: > >> Author: ddunbar >> Date: Thu Jun 16 17:30:38 2011 >> New Revision: 133206 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=133206&view=rev >> Log: >> build/configure: Add support for --with-extra-ld-options flag (to provide extra >> options just to pass to ld). >> > > LDFLAGS doesn't work? Or do we erroneously override it? Didn't work for me. At least, I couldn't find a way to get what I wanted which was add a set of flags that *only* get passed to the link lines. - Daniel > > -eric > >> Modified: >> ? ?llvm/trunk/Makefile.config.in >> ? ?llvm/trunk/Makefile.rules >> ? ?llvm/trunk/autoconf/configure.ac >> >> Modified: llvm/trunk/Makefile.config.in >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.config.in?rev=133206&r1=133205&r2=133206&view=diff >> ============================================================================== >> --- llvm/trunk/Makefile.config.in (original) >> +++ llvm/trunk/Makefile.config.in Thu Jun 16 17:30:38 2011 >> @@ -123,6 +123,9 @@ >> # Extra options to compile LLVM with >> EXTRA_OPTIONS=@EXTRA_OPTIONS@ >> >> +# Extra options to link LLVM with >> +EXTRA_LD_OPTIONS=@EXTRA_LD_OPTIONS@ >> + >> # Endian-ness of the target >> ENDIAN=@ENDIAN@ >> >> >> Modified: llvm/trunk/Makefile.rules >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.rules?rev=133206&r1=133205&r2=133206&view=diff >> ============================================================================== >> --- llvm/trunk/Makefile.rules (original) >> +++ llvm/trunk/Makefile.rules Thu Jun 16 17:30:38 2011 >> @@ -582,6 +582,10 @@ >> # Options To Invoke Tools >> #---------------------------------------------------------- >> >> +ifdef EXTRA_LD_OPTIONS >> +LD.Flags += $(EXTRA_LD_OPTIONS) >> +endif >> + >> ifndef NO_PEDANTIC >> CompileCommonOpts += -pedantic -Wno-long-long >> endif >> >> Modified: llvm/trunk/autoconf/configure.ac >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/configure.ac?rev=133206&r1=133205&r2=133206&view=diff >> ============================================================================== >> --- llvm/trunk/autoconf/configure.ac (original) >> +++ llvm/trunk/autoconf/configure.ac Thu Jun 16 17:30:38 2011 >> @@ -831,6 +831,17 @@ >> esac >> AC_SUBST(EXTRA_OPTIONS,$EXTRA_OPTIONS) >> >> +dnl Specify extra linker build options >> +AC_ARG_WITH(extra-ld-options, >> + ?AS_HELP_STRING([--with-extra-ld-options], >> + ? ? ? ? ? ? ? ? [Specify additional options to link LLVM with]),, >> + ? ? ? ? ? ? ? ? withval=default) >> +case "$withval" in >> + ?default) EXTRA_LD_OPTIONS= ;; >> + ?*) EXTRA_LD_OPTIONS=$withval ;; >> +esac >> +AC_SUBST(EXTRA_LD_OPTIONS,$EXTRA_LD_OPTIONS) >> + >> dnl Allow specific bindings to be specified for building (or not) >> AC_ARG_ENABLE([bindings],AS_HELP_STRING([--enable-bindings], >> ? ? [Build specific language bindings: all,auto,none,{binding-name} (default=auto)]),, >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > From rafael.espindola at gmail.com Tue Jun 21 15:13:50 2011 From: rafael.espindola at gmail.com (=?ISO-8859-1?Q?Rafael_=C1vila_de_Esp=EDndola?=) Date: Tue, 21 Jun 2011 16:13:50 -0400 Subject: [llvm-commits] [llvm] r133240 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp In-Reply-To: References: <20110617055451.24CFF2A6C12C@llvm.org> Message-ID: <4E00FB7E.5090206@gmail.com> > This commit appears to be causing a significant performance regression > on a couple tests in the test-suite for x86-32; > test-suite/SingleSource/Benchmarks/Shootout-C++/matrix.cpp is a good > example (3.3s before, 4.1s after). Would you mind taking a look to > see if anything unexpected is happening? I will take a look. > -Eli Cheers, Rafael From echristo at apple.com Tue Jun 21 15:16:42 2011 From: echristo at apple.com (Eric Christopher) Date: Tue, 21 Jun 2011 13:16:42 -0700 Subject: [llvm-commits] [llvm] r133206 - in /llvm/trunk: Makefile.config.in Makefile.rules autoconf/configure.ac In-Reply-To: References: <20110616223039.2FDCF2A6C12C@llvm.org> <2123779D-92CE-47A4-A2D0-E5D0C1745948@apple.com> Message-ID: On Jun 21, 2011, at 1:05 PM, Daniel Dunbar wrote: > On Thu, Jun 16, 2011 at 4:03 PM, Eric Christopher wrote: >> >> On Jun 16, 2011, at 3:30 PM, Daniel Dunbar wrote: >> >>> Author: ddunbar >>> Date: Thu Jun 16 17:30:38 2011 >>> New Revision: 133206 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=133206&view=rev >>> Log: >>> build/configure: Add support for --with-extra-ld-options flag (to provide extra >>> options just to pass to ld). >>> >> >> LDFLAGS doesn't work? Or do we erroneously override it? > > Didn't work for me. At least, I couldn't find a way to get what I > wanted which was add a set of flags that *only* get passed to the link > lines. Yeah, I'll take a look at it when I get a chance. Something weird is probably going on or something. It _should_ be possible. I think. -eric From baldrick at free.fr Tue Jun 21 15:35:41 2011 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Jun 2011 22:35:41 +0200 Subject: [llvm-commits] [llvm] r133285 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp In-Reply-To: <07078D47-26CC-49FB-B53F-478A74D8A0FB@apple.com> References: <20110617202152.D6B812A6C12C@llvm.org> <4DFDF276.5030703@free.fr> <54E09593-01A1-4936-AFF8-7AF19D2C6919@apple.com> <4DFEF6DA.4030503@free.fr> <4E008742.9030700@free.fr> <07078D47-26CC-49FB-B53F-478A74D8A0FB@apple.com> Message-ID: <4E01009D.3040401@free.fr> Hi John, > I was suggesting that we could make more aggressive restrictions on the > size input to alloca based on a basic assumption that you can't grow your stack > to>2GB, even on>32-bit architectures. But if we want to support that, then > obviously this needs to be based on the pointer width. I agree. >> Why? Are you saying that an alloca of 2^31 i8's should be considered to result >> in undefined behaviour? > > On a 32-bit machine, yes. Are you really saying that we need to > support any argument to alloca that's smaller than the addressable > space of the machine? > > If so, this transformation is completely dead; feel free to remove it. > >> And what about this: alloca i8, i8 128 > > I did say "in sizeof(sp)" above. I didn't know what you meant by sizeof(sp), so I just ignored that bit :) For what it's worth I agree it should be fine to assume that the stack always consumes less than half of the address space. Ciao, Duncan. From echristo at apple.com Tue Jun 21 17:10:57 2011 From: echristo at apple.com (Eric Christopher) Date: Tue, 21 Jun 2011 22:10:57 -0000 Subject: [llvm-commits] [llvm] r133553 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <20110621221057.EFFD02A6C12C@llvm.org> Author: echristo Date: Tue Jun 21 17:10:57 2011 New Revision: 133553 URL: http://llvm.org/viewvc/llvm-project?rev=133553&view=rev Log: Handle the memory-ness of all U+ ARM constraints. Noticed on inspection. 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=133553&r1=133552&r2=133553&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Jun 21 17:10:57 2011 @@ -7379,9 +7379,12 @@ case 'l': return C_RegisterClass; case 'w': return C_RegisterClass; } - } else { - if (Constraint == "Uv") - return C_Memory; + } else if (Constraint.size() == 2) { + switch (Constraint[0]) { + default: break; + // All 'U+' constraints are addresses. + case 'U': return C_Memory; + } } return TargetLowering::getConstraintType(Constraint); } From mttjwl at gmail.com Tue Jun 21 17:12:50 2011 From: mttjwl at gmail.com (Matthew Wala) Date: Tue, 21 Jun 2011 22:12:50 -0000 Subject: [llvm-commits] [poolalloc] r133555 - in /poolalloc/trunk/lib: DSA/StdLibPass.cpp PoolAllocate/PASimple.cpp PoolAllocate/TransformFunctionBody.cpp Message-ID: <20110621221250.B3A282A6C12D@llvm.org> Author: wala1 Date: Tue Jun 21 17:12:50 2011 New Revision: 133555 URL: http://llvm.org/viewvc/llvm-project?rev=133555&view=rev Log: Add support for SAFECode runtime format string functions and intrinsics. Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp poolalloc/trunk/lib/PoolAllocate/PASimple.cpp poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/StdLibPass.cpp?rev=133555&r1=133554&r2=133555&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original) +++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Tue Jun 21 17:12:50 2011 @@ -297,6 +297,11 @@ {"pool_strncasecmp",{NRET_NNYARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, {"pool_bcopy", {NRET_NNYARGS, NRET_NNNYARGS, NRET_NARGS, NRET_NNYARGS, true}}, {"pool_bcmp", {NRET_NNYARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, true}}, + + // format string intrinsics and functions + {"sc.fsparameter", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, + {"sc.fscallinfo", {NRET_YARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, + {"pool_printf", {NRET_YARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, // Type Checks {"trackGlobal", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, Modified: poolalloc/trunk/lib/PoolAllocate/PASimple.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PASimple.cpp?rev=133555&r1=133554&r2=133555&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/PASimple.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/PASimple.cpp Tue Jun 21 17:12:50 2011 @@ -101,7 +101,8 @@ (funcname == "sc.pool_unregister") || (funcname == "sc.get_actual_val") || (funcname == "__if_pool_get_label") || - (funcname == "__if_pool_set_label")) { + (funcname == "__if_pool_set_label") || + (funcname == "sc.fsparameter")) { return 1; } Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp?rev=133555&r1=133554&r2=133555&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Tue Jun 21 17:12:50 2011 @@ -874,7 +874,8 @@ (CF->getName() == "sc.pool_unregister") || (CF->getName() == "sc.get_actual_val") || (CF->getName() == "__if_pool_get_label") || - (CF->getName() == "__if_pool_set_label")) { + (CF->getName() == "__if_pool_set_label") || + (CF->getName() == "sc.fsparameter")) { visitRuntimeCheck (CS); } else if ((argc = PAInfo.getCStdLibPoolArguments(CF->getName())) > 0) { visitCStdLibCheck(CS, argc); From isanbard at gmail.com Tue Jun 21 17:30:20 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 21 Jun 2011 22:30:20 -0000 Subject: [llvm-commits] [llvm] r133559 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Message-ID: <20110621223020.CE29B2A6C12C@llvm.org> Author: void Date: Tue Jun 21 17:30:20 2011 New Revision: 133559 URL: http://llvm.org/viewvc/llvm-project?rev=133559&view=rev Log: Improve the comment printing for the EH table. This gives a much more detailed explanation of what the EH table describes. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp?rev=133559&r1=133558&r2=133559&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Tue Jun 21 17:30:20 2011 @@ -512,6 +512,8 @@ SizeAlign = 0; } + bool VerboseAsm = Asm->OutStreamer.isVerboseAsm(); + // SjLj Exception handling if (IsSJLJ) { Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); @@ -527,7 +529,7 @@ // Offset of the landing pad, counted in 16-byte bundles relative to the // @LPStart address. - Asm->EmitULEB128(idx, "Landing pad"); + Asm->EmitULEB128(idx, "Call Site"); // Offset of the first associated action record, relative to the start of // the action table. This value is biased by 1 (1 indicates the start of @@ -562,6 +564,7 @@ // Add extra padding if it wasn't added to the TType base offset. Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); + unsigned Entry = 0; for (SmallVectorImpl::const_iterator I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { const CallSiteEntry &S = *I; @@ -576,19 +579,37 @@ if (EndLabel == 0) EndLabel = Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber()); + if (VerboseAsm) { + // Emit comments that decode the call site. + Asm->OutStreamer.AddComment(Twine(">> Call Site ") + + llvm::utostr(++Entry) + " <<"); + Asm->OutStreamer.AddComment(Twine(" Call between ") + + BeginLabel->getName() + " and " + + EndLabel->getName()); + if (!S.PadLabel) { + Asm->OutStreamer.AddComment(" has no landing pad"); + } else { + Asm->OutStreamer.AddComment(Twine(" jumps to ") + + S.PadLabel->getName()); + + if (S.Action == 0) + Asm->OutStreamer.AddComment(" On action: cleanup"); + else + Asm->OutStreamer.AddComment(Twine(" On action: ") + + llvm::utostr((S.Action - 1) / 2 + 1)); + } + + Asm->OutStreamer.AddBlankLine(); + } + // Offset of the call site relative to the previous call site, counted in // number of 16-byte bundles. The first call site is counted relative to // the start of the procedure fragment. - Asm->OutStreamer.AddComment("Region start"); Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4); - - Asm->OutStreamer.AddComment("Region length"); Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); - // Offset of the landing pad, counted in 16-byte bundles relative to the // @LPStart address. - Asm->OutStreamer.AddComment("Landing pad"); if (!S.PadLabel) Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); else @@ -597,45 +618,63 @@ // Offset of the first associated action record, relative to the start of // the action table. This value is biased by 1 (1 indicates the start of // the action table), and 0 indicates that there are no actions. - Asm->EmitULEB128(S.Action, "Action"); + Asm->EmitULEB128(S.Action); } } // Emit the Action Table. - if (Actions.size() != 0) { - Asm->OutStreamer.AddComment("-- Action Record Table --"); - Asm->OutStreamer.AddBlankLine(); - } - + int Entry = 0; for (SmallVectorImpl::const_iterator I = Actions.begin(), E = Actions.end(); I != E; ++I) { const ActionEntry &Action = *I; - Asm->OutStreamer.AddComment("Action Record"); - Asm->OutStreamer.AddBlankLine(); + + if (VerboseAsm) { + // Emit comments that decode the action table. + Asm->OutStreamer.AddComment(Twine(">> Action Record ") + + llvm::utostr(++Entry) + " <<"); + if (Action.ValueForTypeID >= 0) + Asm->OutStreamer.AddComment(Twine(" Catch TypeInfo ") + + llvm::itostr(Action.ValueForTypeID)); + else + Asm->OutStreamer.AddComment(Twine(" Filter TypeInfo ") + + llvm::itostr(Action.ValueForTypeID)); + + if (Action.NextAction == 0) { + Asm->OutStreamer.AddComment(" No further actions"); + } else { + unsigned NextAction = Entry + (Action.NextAction + 1) / 2; + Asm->OutStreamer.AddComment(Twine(" Continue to action ") + + llvm::utostr(NextAction)); + } + + Asm->OutStreamer.AddBlankLine(); + } // Type Filter // // Used by the runtime to match the type of the thrown exception to the // type of the catch clauses or the types in the exception specification. - Asm->EmitSLEB128(Action.ValueForTypeID, " TypeInfo index"); + Asm->EmitSLEB128(Action.ValueForTypeID); // Action Record // // Self-relative signed displacement in bytes of the next action record, // or 0 if there is no next action record. - Asm->EmitSLEB128(Action.NextAction, " Next action"); + Asm->EmitSLEB128(Action.NextAction); } // Emit the Catch TypeInfos. - if (!TypeInfos.empty()) { - Asm->OutStreamer.AddComment("-- Catch TypeInfos --"); + if (VerboseAsm && !TypeInfos.empty()) { + Asm->OutStreamer.AddComment(">> Catch TypeInfos <<"); Asm->OutStreamer.AddBlankLine(); + Entry = TypeInfos.size(); } + for (std::vector::const_reverse_iterator I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { const GlobalVariable *GV = *I; - - Asm->OutStreamer.AddComment("TypeInfo"); + if (VerboseAsm) + Asm->OutStreamer.AddComment(Twine("TypeInfo ") + llvm::utostr(Entry--)); if (GV) Asm->EmitReference(GV, TTypeEncoding); else @@ -644,14 +683,21 @@ } // Emit the Exception Specifications. - if (!FilterIds.empty()) { - Asm->OutStreamer.AddComment("-- Filter IDs --"); + if (VerboseAsm && !FilterIds.empty()) { + Asm->OutStreamer.AddComment(">> Filter TypeInfos <<"); Asm->OutStreamer.AddBlankLine(); + Entry = 0; } for (std::vector::const_iterator I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { unsigned TypeID = *I; - Asm->EmitULEB128(TypeID, TypeID != 0 ? "Exception specification" : 0); + if (VerboseAsm) { + --Entry; + if (TypeID != 0) + Asm->OutStreamer.AddComment(Twine("FilterInfo ") + llvm::itostr(Entry)); + } + + Asm->EmitULEB128(TypeID); } Asm->EmitAlignment(2); From dpatel at apple.com Tue Jun 21 17:36:03 2011 From: dpatel at apple.com (Devang Patel) Date: Tue, 21 Jun 2011 22:36:03 -0000 Subject: [llvm-commits] [llvm] r133560 - /llvm/trunk/lib/CodeGen/RegAllocFast.cpp Message-ID: <20110621223603.68CB22A6C12C@llvm.org> Author: dpatel Date: Tue Jun 21 17:36:03 2011 New Revision: 133560 URL: http://llvm.org/viewvc/llvm-project?rev=133560&view=rev Log: There could be more than one DBG_VALUE instructions for variables where all of them have offset based on one register. Modified: llvm/trunk/lib/CodeGen/RegAllocFast.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocFast.cpp?rev=133560&r1=133559&r2=133560&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocFast.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocFast.cpp Tue Jun 21 17:36:03 2011 @@ -86,7 +86,7 @@ // that is currently available in a physical register. LiveRegMap LiveVirtRegs; - DenseMap LiveDbgValueMap; + DenseMap > LiveDbgValueMap; // RegState - Track the state of a physical register. enum RegState { @@ -272,7 +272,9 @@ // If this register is used by DBG_VALUE then insert new DBG_VALUE to // identify spilled location as the place to find corresponding variable's // value. - if (MachineInstr *DBG = LiveDbgValueMap.lookup(LRI->first)) { + SmallVector &LRIDbgValues = LiveDbgValueMap[LRI->first]; + for (unsigned li = 0, le = LRIDbgValues.size(); li != le; ++li) { + MachineInstr *DBG = LRIDbgValues[li]; const MDNode *MDPtr = DBG->getOperand(DBG->getNumOperands()-1).getMetadata(); int64_t Offset = 0; @@ -291,7 +293,7 @@ MachineBasicBlock *MBB = DBG->getParent(); MBB->insert(MI, NewDV); DEBUG(dbgs() << "Inserting debug info due to spill:" << "\n" << *NewDV); - LiveDbgValueMap[LRI->first] = NewDV; + LRIDbgValues[li] = NewDV; } } if (SpillKill) @@ -816,7 +818,7 @@ if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; - LiveDbgValueMap[Reg] = MI; + LiveDbgValueMap[Reg].push_back(MI); LiveRegMap::iterator LRI = LiveVirtRegs.find(Reg); if (LRI != LiveVirtRegs.end()) setPhysReg(MI, i, LRI->second.PhysReg); From isanbard at gmail.com Tue Jun 21 17:40:24 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 21 Jun 2011 22:40:24 -0000 Subject: [llvm-commits] [llvm] r133561 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Message-ID: <20110621224024.9A6412A6C12C@llvm.org> Author: void Date: Tue Jun 21 17:40:24 2011 New Revision: 133561 URL: http://llvm.org/viewvc/llvm-project?rev=133561&view=rev Log: Add verbose EH table printing to SjLj exception tables. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp?rev=133561&r1=133560&r2=133561&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Tue Jun 21 17:40:24 2011 @@ -527,14 +527,30 @@ I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) { const CallSiteEntry &S = *I; + if (VerboseAsm) { + // Emit comments that decode the call site. + Asm->OutStreamer.AddComment(Twine(">> Call Site ") + + llvm::utostr(idx) + " <<"); + Asm->OutStreamer.AddComment(Twine(" On exception at call site ") + + llvm::utostr(idx)); + + if (S.Action == 0) + Asm->OutStreamer.AddComment(" Action: cleanup"); + else + Asm->OutStreamer.AddComment(Twine(" Action: ") + + llvm::utostr((S.Action - 1) / 2 + 1)); + + Asm->OutStreamer.AddBlankLine(); + } + // Offset of the landing pad, counted in 16-byte bundles relative to the // @LPStart address. - Asm->EmitULEB128(idx, "Call Site"); + Asm->EmitULEB128(idx); // Offset of the first associated action record, relative to the start of // the action table. This value is biased by 1 (1 indicates the start of // the action table), and 0 indicates that there are no actions. - Asm->EmitULEB128(S.Action, "Action"); + Asm->EmitULEB128(S.Action); } } else { // DWARF Exception handling @@ -586,6 +602,7 @@ Asm->OutStreamer.AddComment(Twine(" Call between ") + BeginLabel->getName() + " and " + EndLabel->getName()); + if (!S.PadLabel) { Asm->OutStreamer.AddComment(" has no landing pad"); } else { From aggarwa4 at illinois.edu Tue Jun 21 17:43:09 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Jun 2011 22:43:09 -0000 Subject: [llvm-commits] [poolalloc] r133563 - /poolalloc/trunk/lib/DSA/StdLibPass.cpp Message-ID: <20110621224309.D7DD82A6C12C@llvm.org> Author: aggarwa4 Date: Tue Jun 21 17:43:09 2011 New Revision: 133563 URL: http://llvm.org/viewvc/llvm-project?rev=133563&view=rev Log: Add entries for the new type check functions. 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=133563&r1=133562&r2=133563&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original) +++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Tue Jun 21 17:43:09 2011 @@ -306,8 +306,11 @@ // Type Checks {"trackGlobal", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, {"trackLoadInst", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, + {"checkType", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, + {"getTypeTag", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, {"trackStoreInst", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, {"copyTypeInfo", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, + {"setTypeInfo", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, {"trackInitInst", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, {"trackUnInitInst", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, {"trackArray", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, From aggarwa4 at illinois.edu Tue Jun 21 17:44:02 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Jun 2011 22:44:02 -0000 Subject: [llvm-commits] [poolalloc] r133564 - /poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c Message-ID: <20110621224402.B7FE72A6C12C@llvm.org> Author: aggarwa4 Date: Tue Jun 21 17:44:02 2011 New Revision: 133564 URL: http://llvm.org/viewvc/llvm-project?rev=133564&view=rev Log: Add tracking for some more library functions. Modified: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c Modified: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c?rev=133564&r1=133563&r2=133564&view=diff ============================================================================== --- poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c (original) +++ poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c Tue Jun 21 17:44:02 2011 @@ -4,6 +4,10 @@ #include #include #include +#include +#include +#include +#include #include #define DEBUG (0) @@ -115,9 +119,7 @@ uintptr_t p = maskAddress(ptr); shadow_begin[p] = typeNumber; memset(&shadow_begin[p + 1], 0, size - 1); -#if DEBUG printf("Store(%d): %p, %p = %u | %lu bytes | \n", tag, ptr, (void *)p, typeNumber, size); -#endif } @@ -186,22 +188,6 @@ } } -/** - * Check the loaded type against the type recorded in the shadow memory. - */ -void trackLoadInst(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) { - uint8_t *metadata = malloc(size); - - getTypeTag(ptr, size, metadata); - - checkType(typeNumber, size ,metadata, ptr, tag); -#if DEBUG - printf("Load(%d): %p, %p = actual: %u, expect: %u | %lu bytes\n", tag, ptr, (void *)p, typeNumber, shadow_begin[p], size); -#endif - - free(metadata); -} - /** * For memset type instructions, that set values. @@ -237,6 +223,10 @@ printf("Copy(%d): %p, %p = %u | %lu bytes \n", tag, dstptr, srcptr, shadow_begin[s], size); #endif } +void setTypeInfo(void *dstptr, void *metadata, uint64_t size, uint32_t tag) { + uintptr_t d = maskAddress(dstptr); + memcpy(&shadow_begin[d], metadata, size); +} /** * Initialize metadata for the pointer returned by __ctype_b_loc @@ -287,3 +277,27 @@ void trackgethostname(void *ptr, uint32_t tag) { trackInitInst(ptr, strlen(ptr) + 1, tag); } + +void trackgetaddrinfo(void *ptr, uint32_t tag) { + struct addrinfo *res; + struct addrinfo ** result = (struct addrinfo **)ptr; + for(res = *result; res != NULL; res = res->ai_next) { + trackInitInst(res->ai_addr, sizeof(struct sockaddr), tag); + trackInitInst(res, sizeof(struct addrinfo), tag); + } + + trackInitInst(result, sizeof(struct addrinfo*), tag); +} + +void trackaccept(void *ptr, uint32_t tag) { + trackInitInst(ptr, sizeof(struct sockaddr), tag); +} + +void trackpoll(void *ptr, uint64_t nfds, uint32_t tag) { + struct pollfd *fds = (struct pollfd *)ptr; + unsigned i = 0; + while (i < nfds) { + trackInitInst(&fds[i], sizeof(struct pollfd), tag); + i++; + } +} From grosbach at apple.com Tue Jun 21 17:50:09 2011 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 21 Jun 2011 15:50:09 -0700 Subject: [llvm-commits] [llvm] r133561 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp In-Reply-To: <20110621224024.9A6412A6C12C@llvm.org> References: <20110621224024.9A6412A6C12C@llvm.org> Message-ID: <8BD87ACA-1476-436B-8F59-06A45877992E@apple.com> Yay! Thanks, Bill. This, together with your other annotation patches, is a huge help reading these things. -j On Jun 21, 2011, at 3:40 PM, Bill Wendling wrote: > Author: void > Date: Tue Jun 21 17:40:24 2011 > New Revision: 133561 > > URL: http://llvm.org/viewvc/llvm-project?rev=133561&view=rev > Log: > Add verbose EH table printing to SjLj exception tables. > > Modified: > llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp > > Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp?rev=133561&r1=133560&r2=133561&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp (original) > +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Tue Jun 21 17:40:24 2011 > @@ -527,14 +527,30 @@ > I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) { > const CallSiteEntry &S = *I; > > + if (VerboseAsm) { > + // Emit comments that decode the call site. > + Asm->OutStreamer.AddComment(Twine(">> Call Site ") + > + llvm::utostr(idx) + " <<"); > + Asm->OutStreamer.AddComment(Twine(" On exception at call site ") + > + llvm::utostr(idx)); > + > + if (S.Action == 0) > + Asm->OutStreamer.AddComment(" Action: cleanup"); > + else > + Asm->OutStreamer.AddComment(Twine(" Action: ") + > + llvm::utostr((S.Action - 1) / 2 + 1)); > + > + Asm->OutStreamer.AddBlankLine(); > + } > + > // Offset of the landing pad, counted in 16-byte bundles relative to the > // @LPStart address. > - Asm->EmitULEB128(idx, "Call Site"); > + Asm->EmitULEB128(idx); > > // Offset of the first associated action record, relative to the start of > // the action table. This value is biased by 1 (1 indicates the start of > // the action table), and 0 indicates that there are no actions. > - Asm->EmitULEB128(S.Action, "Action"); > + Asm->EmitULEB128(S.Action); > } > } else { > // DWARF Exception handling > @@ -586,6 +602,7 @@ > Asm->OutStreamer.AddComment(Twine(" Call between ") + > BeginLabel->getName() + " and " + > EndLabel->getName()); > + > if (!S.PadLabel) { > Asm->OutStreamer.AddComment(" has no landing pad"); > } else { > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From nicholas at mxc.ca Tue Jun 21 17:45:42 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 21 Jun 2011 22:45:42 -0000 Subject: [llvm-commits] [llvm] r133565 - in /llvm/trunk: lib/Target/X86/X86InstrSSE.td test/MC/X86/x86-64.s Message-ID: <20110621224542.29C4C2A6C12C@llvm.org> Author: nicholas Date: Tue Jun 21 17:45:41 2011 New Revision: 133565 URL: http://llvm.org/viewvc/llvm-project?rev=133565&view=rev Log: Add support for assembling "movq" when it's correct to do so, while continuing to emit "movd" across the board to continue supporting a Darwin assembler bug. This is the reincarnation of r133452. Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/test/MC/X86/x86-64.s Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=133565&r1=133564&r2=133565&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Tue Jun 21 17:45:41 2011 @@ -2968,6 +2968,22 @@ (MOVZDI2PDIrm addr:$src)>; } +// These are the correct encodings of the instructions so that we know how to +// read correct assembly, even though we continue to emit the wrong ones for +// compatibility with Darwin's buggy assembler. +def : InstAlias<"movq\t{$src, $dst|$dst, $src}", + (MOV64toPQIrr VR128:$dst, GR64:$src), 0>; +def : InstAlias<"movq\t{$src, $dst|$dst, $src}", + (MOV64toSDrr FR64:$dst, GR64:$src), 0>; +def : InstAlias<"movq\t{$src, $dst|$dst, $src}", + (MOVPQIto64rr GR64:$dst, VR128:$src), 0>; +def : InstAlias<"movq\t{$src, $dst|$dst, $src}", + (MOVSDto64rr GR64:$dst, FR64:$src), 0>; +def : InstAlias<"movq\t{$src, $dst|$dst, $src}", + (VMOVZQI2PQIrr VR128:$dst, GR64:$src), 0>; +def : InstAlias<"movq\t{$src, $dst|$dst, $src}", + (MOVZQI2PQIrr VR128:$dst, GR64:$src), 0>; + //===---------------------------------------------------------------------===// // SSE2 - Move Quadword //===---------------------------------------------------------------------===// Modified: llvm/trunk/test/MC/X86/x86-64.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-64.s?rev=133565&r1=133564&r2=133565&view=diff ============================================================================== --- llvm/trunk/test/MC/X86/x86-64.s (original) +++ llvm/trunk/test/MC/X86/x86-64.s Tue Jun 21 17:45:41 2011 @@ -1128,3 +1128,11 @@ // CHECK: strq // CHECK: encoding: [0x48,0x0f,0x00,0xc8] str %rax + +// CHECK: movd %rdi, %xmm0 +// CHECK: encoding: [0x66,0x48,0x0f,0x6e,0xc7] + movq %rdi,%xmm0 + +// CHECK: movd %rdi, %xmm0 +// CHECK: encoding: [0x66,0x48,0x0f,0x6e,0xc7] + movd %rdi,%xmm0 From aggarwa4 at illinois.edu Tue Jun 21 17:50:28 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Jun 2011 22:50:28 -0000 Subject: [llvm-commits] [poolalloc] r133566 - in /poolalloc/trunk/lib/AssistDS: TypeChecks.cpp TypeChecksOpt.cpp Message-ID: <20110621225028.5C41C2A6C12C@llvm.org> Author: aggarwa4 Date: Tue Jun 21 17:50:28 2011 New Revision: 133566 URL: http://llvm.org/viewvc/llvm-project?rev=133566&view=rev Log: Remove references to trackLoadInst, which is now redundant Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=133566&r1=133565&r2=133566&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Tue Jun 21 17:50:28 2011 @@ -1602,6 +1602,34 @@ CallInst::Create(trackInitInst, Args.begin(), Args.end(), "", I); return true; } + } else if (F->getNameStr() == std::string("accept")) { + CastInst *BCI = BitCastInst::CreatePointerCast(I->getOperand(2), VoidPtrTy); + BCI->insertAfter(I); + std::vectorArgs; + Args.push_back(BCI); + Args.push_back(getTagCounter()); + Constant *F = M.getOrInsertFunction("trackaccept", VoidTy, VoidPtrTy, Int32Ty, NULL); + CallInst *CI = CallInst::Create(F, Args.begin(), Args.end()); + CI->insertAfter(BCI); + } else if (F->getNameStr() == std::string("poll")) { + CastInst *BCI = BitCastInst::CreatePointerCast(I->getOperand(1), VoidPtrTy); + BCI->insertAfter(I); + std::vectorArgs; + Args.push_back(BCI); + Args.push_back(I->getOperand(2)); + Args.push_back(getTagCounter()); + Constant *F = M.getOrInsertFunction("trackpoll", VoidTy, VoidPtrTy, Int64Ty, Int32Ty, NULL); + CallInst *CI = CallInst::Create(F, Args.begin(), Args.end()); + CI->insertAfter(BCI); + } else if (F->getNameStr() == std::string("getaddrinfo")) { + CastInst *BCI = BitCastInst::CreatePointerCast(I->getOperand(4), VoidPtrTy); + BCI->insertAfter(I); + std::vectorArgs; + Args.push_back(BCI); + Args.push_back(getTagCounter()); + Constant *F = M.getOrInsertFunction("trackgetaddrinfo", VoidTy, VoidPtrTy, Int32Ty, NULL); + CallInst *CI = CallInst::Create(F, Args.begin(), Args.end()); + CI->insertAfter(BCI); } else if (F->getNameStr() == std::string("__strdup")) { CastInst *BCI_Dest = BitCastInst::CreatePointerCast(I, VoidPtrTy); BCI_Dest->insertAfter(I); @@ -1743,7 +1771,8 @@ Args.push_back(getTagCounter()); Constant *F = M.getOrInsertFunction("trackStrncpyInst", VoidTy, VoidPtrTy, VoidPtrTy, I->getOperand(3)->getType(), Int32Ty, NULL); CallInst::Create(F, Args.begin(), Args.end(), "", I); - } else if(F->getNameStr() == std::string("ftime")) { + } else if(F->getNameStr() == std::string("ftime") || + F->getNameStr() == std::string("gettimeofday")) { CastInst *BCI = BitCastInst::CreatePointerCast(I->getOperand(1), VoidPtrTy, "", I); const PointerType *PTy = cast(I->getOperand(1)->getType()); const Type * ElementType = PTy->getElementType(); Modified: poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp?rev=133566&r1=133565&r2=133566&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp Tue Jun 21 17:50:28 2011 @@ -47,11 +47,11 @@ static Constant *trackInitInst; static Constant *trackUnInitInst; static Constant *trackStoreInst; -static Constant *trackLoadInst; static Constant *copyTypeInfo; static Constant *setTypeInfo; static Constant *checkTypeInst; static Constant *MallocFunc; +static Constant *getTypeTag; bool TypeChecksOpt::runOnModule(Module &M) { TS = &getAnalysis >(); @@ -63,6 +63,12 @@ Int64Ty = IntegerType::getInt64Ty(M.getContext()); VoidPtrTy = PointerType::getUnqual(Int8Ty); + getTypeTag = M.getOrInsertFunction("getTypeTag", + VoidTy, + VoidPtrTy, /*ptr*/ + Int64Ty, /*size*/ + VoidPtrTy, /*dest for type tag*/ + NULL); trackGlobal = M.getOrInsertFunction("trackGlobal", VoidTy, VoidPtrTy,/*ptr*/ @@ -104,13 +110,6 @@ VoidPtrTy,/*ptr*/ Int32Ty,/*tag*/ NULL); - trackLoadInst = M.getOrInsertFunction("trackLoadInst", - VoidTy, - VoidPtrTy,/*ptr*/ - Int8Ty,/*type*/ - Int64Ty,/*size*/ - Int32Ty,/*tag*/ - NULL); copyTypeInfo = M.getOrInsertFunction("copyTypeInfo", VoidTy, VoidPtrTy,/*dest ptr*/ From resistor at mac.com Tue Jun 21 17:54:23 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 21 Jun 2011 22:54:23 -0000 Subject: [llvm-commits] [llvm] r133567 - in /llvm/trunk/lib: CodeGen/SelectionDAG/ScheduleDAGRRList.cpp VMCore/ValueTypes.cpp Message-ID: <20110621225423.9A2DE2A6C12C@llvm.org> Author: resistor Date: Tue Jun 21 17:54:23 2011 New Revision: 133567 URL: http://llvm.org/viewvc/llvm-project?rev=133567&view=rev Log: Fix some trailing issues from my introduction of MVT::untyped and its use for REGISTER_SEQUENCE. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/trunk/lib/VMCore/ValueTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=133567&r1=133566&r2=133567&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Tue Jun 21 17:54:23 2011 @@ -290,7 +290,17 @@ // Special handling for untyped values. These values can only come from // the expansion of custom DAG-to-DAG patterns. if (VT == MVT::untyped) { - unsigned Opcode = RegDefPos.GetNode()->getMachineOpcode(); + const SDNode *Node = RegDefPos.GetNode(); + unsigned Opcode = Node->getMachineOpcode(); + + if (Opcode == TargetOpcode::REG_SEQUENCE) { + unsigned DstRCIdx = cast(Node->getOperand(0))->getZExtValue(); + const TargetRegisterClass *RC = TRI->getRegClass(DstRCIdx); + RegClass = RC->getID(); + Cost = 1; + return; + } + unsigned Idx = RegDefPos.GetIdx(); const TargetInstrDesc Desc = TII->get(Opcode); const TargetRegisterClass *RC = Desc.getRegClass(Idx, TRI); Modified: llvm/trunk/lib/VMCore/ValueTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ValueTypes.cpp?rev=133567&r1=133566&r2=133567&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ValueTypes.cpp (original) +++ llvm/trunk/lib/VMCore/ValueTypes.cpp Tue Jun 21 17:54:23 2011 @@ -133,6 +133,7 @@ case MVT::v2f64: return "v2f64"; case MVT::v4f64: return "v4f64"; case MVT::Metadata:return "Metadata"; + case MVT::untyped: return "untyped"; } } From grosbach at apple.com Tue Jun 21 17:55:51 2011 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 21 Jun 2011 22:55:51 -0000 Subject: [llvm-commits] [llvm] r133568 - in /llvm/trunk/utils/TableGen: AsmMatcherEmitter.cpp AsmWriterEmitter.cpp CodeGenDAGPatterns.cpp CodeGenInstruction.cpp CodeGenRegisters.cpp DisassemblerEmitter.cpp Error.cpp Error.h FastISelEmitter.cpp NeonEmitter.cpp Record.cpp Record.h SetTheory.cpp TGLexer.cpp TGLexer.h TGParser.h TableGen.cpp Message-ID: <20110621225551.3FD522A6C12C@llvm.org> Author: grosbach Date: Tue Jun 21 17:55:50 2011 New Revision: 133568 URL: http://llvm.org/viewvc/llvm-project?rev=133568&view=rev Log: Consolidate some TableGen diagnostic helper functions. TableGen had diagnostic printers sprinkled about in a few places. Pull them together into a single location in Error.cpp. Added: llvm/trunk/utils/TableGen/Error.cpp llvm/trunk/utils/TableGen/Error.h Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp llvm/trunk/utils/TableGen/CodeGenInstruction.cpp llvm/trunk/utils/TableGen/CodeGenRegisters.cpp llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp llvm/trunk/utils/TableGen/FastISelEmitter.cpp llvm/trunk/utils/TableGen/NeonEmitter.cpp llvm/trunk/utils/TableGen/Record.cpp llvm/trunk/utils/TableGen/Record.h llvm/trunk/utils/TableGen/SetTheory.cpp llvm/trunk/utils/TableGen/TGLexer.cpp llvm/trunk/utils/TableGen/TGLexer.h llvm/trunk/utils/TableGen/TGParser.h llvm/trunk/utils/TableGen/TableGen.cpp Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Tue Jun 21 17:55:50 2011 @@ -98,6 +98,7 @@ #include "AsmMatcherEmitter.h" #include "CodeGenTarget.h" +#include "Error.h" #include "Record.h" #include "StringMatcher.h" #include "llvm/ADT/OwningPtr.h" Modified: llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp Tue Jun 21 17:55:50 2011 @@ -14,6 +14,7 @@ #include "AsmWriterEmitter.h" #include "AsmWriterInst.h" +#include "Error.h" #include "CodeGenTarget.h" #include "Record.h" #include "StringToOffsetTable.h" Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Tue Jun 21 17:55:50 2011 @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "CodeGenDAGPatterns.h" +#include "Error.h" #include "Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp Tue Jun 21 17:55:50 2011 @@ -13,6 +13,7 @@ #include "CodeGenInstruction.h" #include "CodeGenTarget.h" +#include "Error.h" #include "Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.cpp?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenRegisters.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenRegisters.cpp Tue Jun 21 17:55:50 2011 @@ -14,6 +14,7 @@ #include "CodeGenRegisters.h" #include "CodeGenTarget.h" +#include "Error.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" Modified: llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/DisassemblerEmitter.cpp Tue Jun 21 17:55:50 2011 @@ -9,6 +9,7 @@ #include "DisassemblerEmitter.h" #include "CodeGenTarget.h" +#include "Error.h" #include "Record.h" #include "X86DisassemblerTables.h" #include "X86RecognizableInstr.h" Added: llvm/trunk/utils/TableGen/Error.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Error.cpp?rev=133568&view=auto ============================================================================== --- llvm/trunk/utils/TableGen/Error.cpp (added) +++ llvm/trunk/utils/TableGen/Error.cpp Tue Jun 21 17:55:50 2011 @@ -0,0 +1,39 @@ +//===- Error.cpp - tblgen error handling helper routines --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains error handling helper routines to pretty-print diagnostic +// messages from tblgen. +// +//===----------------------------------------------------------------------===// + +#include "Error.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +SourceMgr SrcMgr; + +void PrintError(SMLoc ErrorLoc, const Twine &Msg) { + SrcMgr.PrintMessage(ErrorLoc, Msg, "error"); +} + +void PrintError(const char *Loc, const Twine &Msg) { + SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), Msg, "error"); +} + +void PrintError(const Twine &Msg) { + errs() << "error:" << Msg << "\n"; +} + +void PrintError(const TGError &Error) { + PrintError(Error.getLoc(), Error.getMessage()); +} + +} // end namespace llvm Added: llvm/trunk/utils/TableGen/Error.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Error.h?rev=133568&view=auto ============================================================================== --- llvm/trunk/utils/TableGen/Error.h (added) +++ llvm/trunk/utils/TableGen/Error.h Tue Jun 21 17:55:50 2011 @@ -0,0 +1,43 @@ +//===- Error.h - tblgen error handling helper routines ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains error handling helper routines to pretty-print diagnostic +// messages from tblgen. +// +//===----------------------------------------------------------------------===// + +#ifndef ERROR_H +#define ERROR_H + +#include "llvm/Support/SourceMgr.h" + +namespace llvm { + +class TGError { + SMLoc Loc; + std::string Message; +public: + TGError(SMLoc loc, const std::string &message) : Loc(loc), Message(message) {} + + SMLoc getLoc() const { return Loc; } + const std::string &getMessage() const { return Message; } +}; + +void PrintError(SMLoc ErrorLoc, const Twine &Msg); +void PrintError(const char *Loc, const Twine &Msg); +void PrintError(const Twine &Msg); +void PrintError(const TGError &Error); + + +extern SourceMgr SrcMgr; + + +} // end namespace "llvm" + +#endif Modified: llvm/trunk/utils/TableGen/FastISelEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FastISelEmitter.cpp?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/FastISelEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/FastISelEmitter.cpp Tue Jun 21 17:55:50 2011 @@ -18,6 +18,7 @@ //===----------------------------------------------------------------------===// #include "FastISelEmitter.h" +#include "Error.h" #include "Record.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/VectorExtras.h" Modified: llvm/trunk/utils/TableGen/NeonEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/NeonEmitter.cpp?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/NeonEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/NeonEmitter.cpp Tue Jun 21 17:55:50 2011 @@ -24,6 +24,7 @@ //===----------------------------------------------------------------------===// #include "NeonEmitter.h" +#include "Error.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" Modified: llvm/trunk/utils/TableGen/Record.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.cpp?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/Record.cpp (original) +++ llvm/trunk/utils/TableGen/Record.cpp Tue Jun 21 17:55:50 2011 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "Record.h" +#include "Error.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Format.h" #include "llvm/ADT/StringExtras.h" Modified: llvm/trunk/utils/TableGen/Record.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.h?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/Record.h (original) +++ llvm/trunk/utils/TableGen/Record.h Tue Jun 21 17:55:50 2011 @@ -1486,22 +1486,8 @@ } }; - -class TGError { - SMLoc Loc; - std::string Message; -public: - TGError(SMLoc loc, const std::string &message) : Loc(loc), Message(message) {} - - SMLoc getLoc() const { return Loc; } - const std::string &getMessage() const { return Message; } -}; - - raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK); -void PrintError(SMLoc ErrorLoc, const Twine &Msg); - } // End llvm namespace #endif Modified: llvm/trunk/utils/TableGen/SetTheory.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SetTheory.cpp?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/SetTheory.cpp (original) +++ llvm/trunk/utils/TableGen/SetTheory.cpp Tue Jun 21 17:55:50 2011 @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "SetTheory.h" +#include "Error.h" #include "Record.h" #include "llvm/Support/Format.h" Modified: llvm/trunk/utils/TableGen/TGLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGLexer.cpp (original) +++ llvm/trunk/utils/TableGen/TGLexer.cpp Tue Jun 21 17:55:50 2011 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "TGLexer.h" +#include "Error.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Config/config.h" @@ -35,7 +36,6 @@ return SMLoc::getFromPointer(TokStart); } - /// ReturnError - Set the error to the specified string at the specified /// location. This is defined to always return tgtok::Error. tgtok::TokKind TGLexer::ReturnError(const char *Loc, const Twine &Msg) { @@ -43,16 +43,6 @@ return tgtok::Error; } - -void TGLexer::PrintError(const char *Loc, const Twine &Msg) const { - SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), Msg, "error"); -} - -void TGLexer::PrintError(SMLoc Loc, const Twine &Msg) const { - SrcMgr.PrintMessage(Loc, Msg, "error"); -} - - int TGLexer::getNextChar() { char CurChar = *CurPtr++; switch (CurChar) { Modified: llvm/trunk/utils/TableGen/TGLexer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.h?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGLexer.h (original) +++ llvm/trunk/utils/TableGen/TGLexer.h Tue Jun 21 17:55:50 2011 @@ -101,9 +101,6 @@ } SMLoc getLoc() const; - - void PrintError(const char *Loc, const Twine &Msg) const; - void PrintError(SMLoc Loc, const Twine &Msg) const; private: /// LexToken - Read the next token and return its code. Modified: llvm/trunk/utils/TableGen/TGParser.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.h?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGParser.h (original) +++ llvm/trunk/utils/TableGen/TGParser.h Tue Jun 21 17:55:50 2011 @@ -15,6 +15,7 @@ #define TGPARSER_H #include "TGLexer.h" +#include "Error.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/SourceMgr.h" #include @@ -60,7 +61,7 @@ bool ParseFile(); bool Error(SMLoc L, const Twine &Msg) const { - Lex.PrintError(L, Msg); + PrintError(L, Msg); return true; } bool TokError(const Twine &Msg) const { Modified: llvm/trunk/utils/TableGen/TableGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TableGen.cpp?rev=133568&r1=133567&r2=133568&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TableGen.cpp (original) +++ llvm/trunk/utils/TableGen/TableGen.cpp Tue Jun 21 17:55:50 2011 @@ -26,6 +26,7 @@ #include "DAGISelEmitter.h" #include "DisassemblerEmitter.h" #include "EDEmitter.h" +#include "Error.h" #include "FastISelEmitter.h" #include "InstrEnumEmitter.h" #include "InstrInfoEmitter.h" @@ -194,12 +195,6 @@ } -static SourceMgr SrcMgr; - -void llvm::PrintError(SMLoc ErrorLoc, const Twine &Msg) { - SrcMgr.PrintMessage(ErrorLoc, Msg, "error"); -} - int main(int argc, char **argv) { RecordKeeper Records; @@ -403,13 +398,11 @@ return 0; } catch (const TGError &Error) { - errs() << argv[0] << ": error:\n"; - PrintError(Error.getLoc(), Error.getMessage()); - + PrintError(Error); } catch (const std::string &Error) { - errs() << argv[0] << ": " << Error << "\n"; + PrintError(Error); } catch (const char *Error) { - errs() << argv[0] << ": " << Error << "\n"; + PrintError(Error); } catch (...) { errs() << argv[0] << ": Unknown unexpected exception occurred.\n"; } From isanbard at gmail.com Tue Jun 21 18:02:38 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 21 Jun 2011 16:02:38 -0700 Subject: [llvm-commits] [llvm] r133561 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp In-Reply-To: <8BD87ACA-1476-436B-8F59-06A45877992E@apple.com> References: <20110621224024.9A6412A6C12C@llvm.org> <8BD87ACA-1476-436B-8F59-06A45877992E@apple.com> Message-ID: <62AE249D-146C-4F65-82B4-45BED4BCC0BF@gmail.com> On Jun 21, 2011, at 3:50 PM, Jim Grosbach wrote: > Yay! Thanks, Bill. This, together with your other annotation patches, is a huge help reading these things. Thanks! Though unfortunately the annotation patch didn't survive. Not only was it buggy, but as Chris pointed out having it in the AsmPrinter instead of the MC stuff made more sense. We lose the ability to annotate a .s file. But we should be analyzing only those .s files coming from clang, so ... :-) -bw From dpatel at apple.com Tue Jun 21 18:02:36 2011 From: dpatel at apple.com (Devang Patel) Date: Tue, 21 Jun 2011 23:02:36 -0000 Subject: [llvm-commits] [llvm] r133569 - /llvm/trunk/lib/CodeGen/RegAllocFast.cpp Message-ID: <20110621230236.B4B2E2A6C12C@llvm.org> Author: dpatel Date: Tue Jun 21 18:02:36 2011 New Revision: 133569 URL: http://llvm.org/viewvc/llvm-project?rev=133569&view=rev Log: After register is spilled there should not be any DBG_VALUE referring the same register. Modified: llvm/trunk/lib/CodeGen/RegAllocFast.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocFast.cpp?rev=133569&r1=133568&r2=133569&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocFast.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocFast.cpp Tue Jun 21 18:02:36 2011 @@ -293,9 +293,11 @@ MachineBasicBlock *MBB = DBG->getParent(); MBB->insert(MI, NewDV); DEBUG(dbgs() << "Inserting debug info due to spill:" << "\n" << *NewDV); - LRIDbgValues[li] = NewDV; } } + // Now this register is spilled there is should not be any DBG_VALUE pointing + // to this register because they are all pointing to spilled value now. + LRIDbgValues.clear(); if (SpillKill) LR.LastUse = 0; // Don't kill register again } From nlewycky at google.com Tue Jun 21 18:19:01 2011 From: nlewycky at google.com (Nick Lewycky) Date: Tue, 21 Jun 2011 16:19:01 -0700 Subject: [llvm-commits] patch: fix emission of npot vectors which need trailing padding In-Reply-To: References: Message-ID: Hi Renato! Sorry, but I don't understand your reply at all. The correctness of this patch is dependent on whether an LLVM vector should ever have trailing padding (not element padding). If the answer is no regardless of platform, then we should add an assertion in this spot instead of code to write out padding. There's nothing ARM-specific about this change, which is why it belongs in generic CodeGen and shouldn't be in the ARMAsmPrinter. It just so happens that <3 x float> on ARM provides a counter-example that would require this padding or trigger this assertion. If we agree that they should never be padded, then the backend would be responsible for either expanding the <3 x float> into a <4 x float>, or else breaking it into <2 x float> + float. Is that what you're arguing for? Alternatively, if you want <3 x float> to be 12 bytes and densely packed, that'd be an independent change. You'd want to modify what TargetData says about the <3 x float>, so that the computation performed by GEP, etc., all line up. Currently I'm just fixing EmitGlobalConstantVector to emit n-bytes when target data says the vector is n-bytes long. Nick On 21 June 2011 01:45, Renato Golin wrote: > On 21 June 2011 06:52, Nick Lewycky wrote: > > This lowers to a struct with <3 x float>, which TargetData says is 16 > bytes > > on ARM. > > Hi Nick, > > This only makes sense for ARM with NEON/VFP, unless selection-DAG > identifies it and remove the padding to avoid extra instructions being > generated for the CPU when NEON/VFP is not present. > > Anyone knows if that's the case? > > > > In LLVM IR, the first element becomes a constant aggregate zero, > > which is emitted by looking at how many bytes it is (sixteen) and writing > > out a zero-fill. The second element is emitted as three contiguous > elements, > > resulting in a total of 12 bytes. > > I agree, we should have consistency here. > > > > The StructLayout object claims that each of those should be 16 bytes, so > I > > changed the AsmPrinter in CodeGen to apply padding to the end of an array > to > > match what TargetData thinks the length of the array is. Patch attached, > > please review! > > Not sure you changed the right place. I agree that alignment is > important for all platforms but I wouldn't make such an assumption > without a set of tests for each one of them. > > If everyone is happy that such padding needs to be dealt with by the > generic CodeGen, I won't oppose, but would be good to have at least > one test for each major architecture. > > Otherwise, if you move it to ARMAsmPrinter, I still suggest you to > write a simple IR-to-ASM test and check data sizes. > > cheers, > --renato > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110621/cd2ddf05/attachment.html From pichet2000 at gmail.com Tue Jun 21 18:19:23 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Tue, 21 Jun 2011 23:19:23 -0000 Subject: [llvm-commits] [llvm] r133574 - /llvm/trunk/utils/TableGen/CMakeLists.txt Message-ID: <20110621231923.7B3E22A6C12C@llvm.org> Author: fpichet Date: Tue Jun 21 18:19:23 2011 New Revision: 133574 URL: http://llvm.org/viewvc/llvm-project?rev=133574&view=rev Log: Unbreak the CMake build Modified: llvm/trunk/utils/TableGen/CMakeLists.txt Modified: llvm/trunk/utils/TableGen/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CMakeLists.txt?rev=133574&r1=133573&r2=133574&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CMakeLists.txt (original) +++ llvm/trunk/utils/TableGen/CMakeLists.txt Tue Jun 21 18:19:23 2011 @@ -25,6 +25,7 @@ DAGISelMatcher.cpp DisassemblerEmitter.cpp EDEmitter.cpp + Error.cpp FastISelEmitter.cpp FixedLenDecoderEmitter.cpp InstrEnumEmitter.cpp From eli.friedman at gmail.com Tue Jun 21 18:31:02 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Tue, 21 Jun 2011 16:31:02 -0700 Subject: [llvm-commits] patch: fix emission of npot vectors which need trailing padding In-Reply-To: References: Message-ID: On Tue, Jun 21, 2011 at 4:19 PM, Nick Lewycky wrote: > Hi Renato! Sorry, but I don't understand your reply at all. > The correctness of this patch is dependent on whether an LLVM vector should > ever have trailing padding (not element padding). If the answer is no > regardless of platform, then we should add an assertion in this spot instead > of code to write out padding. > There's nothing ARM-specific about this change, which is why it belongs in > generic CodeGen and shouldn't be in the ARMAsmPrinter.?It just so happens > that <3 x float> on ARM provides a counter-example that would require this > padding or trigger this assertion. Take the following on x86: typedef float float3 __attribute__((ext_vector_type(3))); int printf(const char*,...); struct Foo { float3 x, y; }; struct Foo foo = { {1,2,3}, {1, 2, 3} }; int main() { float3 y = foo.y; printf("%f\n", y[2]); return 0; } It currently gets miscomputed because of this issue... so definitely not ARM-specific. -Eli From tobias at grosser.es Tue Jun 21 18:37:56 2011 From: tobias at grosser.es (Tobias Grosser) Date: Tue, 21 Jun 2011 20:37:56 -0300 Subject: [llvm-commits] [polly] r133354 - /polly/trunk/www/documentation/memaccess.html In-Reply-To: <20110618171716.444342A6C12C@llvm.org> References: <20110618171716.444342A6C12C@llvm.org> Message-ID: <4E012B54.3090403@grosser.es> On 06/18/2011 02:17 PM, Raghesh Aloor wrote: > Author: raghesh > Date: Sat Jun 18 12:17:16 2011 > New Revision: 133354 > > URL: http://llvm.org/viewvc/llvm-project?rev=133354&view=rev > Log: > www: Adding webpage to track memory access transformation Hi Raghesh, thanks for your work. I still have some comments: You forgot to add the disclaimer that this is a work in progress project. Furthermore, the HTML you used is pretty noisy (details inline). The next time we should review it before committing. > Added: > polly/trunk/www/documentation/memaccess.html > > Added: polly/trunk/www/documentation/memaccess.html > URL: http://llvm.org/viewvc/llvm-project/polly/trunk/www/documentation/memaccess.html?rev=133354&view=auto > ============================================================================== > --- polly/trunk/www/documentation/memaccess.html (added) > +++ polly/trunk/www/documentation/memaccess.html Sat Jun 18 12:17:16 2011 > @@ -0,0 +1,143 @@ > + > + > + > + + http-equiv="Content-Type"> > +memaccess.html Can you use a title like 'Polly - Memory access optimizations' You should include menu.css and content.css I propose to just use the header from documention/passes.html as a template. (This is true for most of the comments I give) Polly - The available LLVM passes > + > + You miss the line to include the menu. > +

Support Just create a large div with id="content" that includes the whole content of this page. > +for > +memory access > +transformations in Polly + style="font-weight: bold;">
Use

for the header. All the other tags are just noise and disallow a consistent design. > +
Useless noise. > +
This does not seem to be needed. > + Useless noise. > +This project adds > +memory access transformations to Polly. In many cases

Not needed. > +changing the memory access pattern yields to better data > +locality or removes

not needed. > +dependences that would otherwise block > +transformations. They may also
. Memory access transformations may also ...
not needed > +allow LLVM to use registers to store > +certain values.

not needed > +
> +

not needed. > +An examples which uses this feature is given below
This seems to be a new paragraph. Put it in a

to get the newlines. > +

> +

I do not see a reason for this
> +Consider the following loop > +
    > +
      > +
    > +
Useless noise. > +
Just use
 to format the code.

> + for
> +(i = 0; i< 8; i++)
> +sum += A[i];
+ style="font-style: italic;"> All this formatting and
not needed. > +
> +
> +With support for memory access transformation this loop can be executed
> +in parallel. It can be > +transformed to > +
> +
> +
Useless noise. > +
not needed. > +<create > +and > +initialize an array 'tmp' > +with size 4>
> +for (i = 0; i< 8; i++) {
> +tmp[i % 4] += A[i];
> +} + style="font-style: italic;">
> +sum = tmp[0] + tmp[1] + tmp[2] > ++ tmp[3];
All formatting not needed. Just use a big
 block.

> +
> +
> +With the help of some optimizer (like > +PluTo) the following code can be

not needed. "With the help of optimizers like PluTo the following > +generated, where the outer loop is > +parallel. > +

parfor (ii = > +0; ii< 4; ii++) {
> +   tmp[ii] = 0;
> +    for (i = ii * 2; i< (ii+1) * 2; i++)
> +      tmp[ii] += A[i];

> +

+ style="font-weight: normal;">}
> +sum = tmp[0] + tmp[1] + tmp[2] + > +tmp[3];
> +

Useless style noise. Just use

> +

TODO
> +

Do not use

here. Just use

> +

Step 1
> +

Just use

> +Polly exports its polyhedral description in a JSCoP file. Define how > +memory > +
> +
Useless noise.
not needed. > +layout transformations are going to be expressed in Polly and > +in > +the JSCOP file.
> +A simple example is given below.
> +
> +Consider the following loop.
> +

not needed. Use

to mark a paragraph. > +

for > +(i > += 0; i< 12; i++)
> +     A[i] = 0;
+ style="font-style: italic;"> > +
Useless style noise. Just use
.

> +
> +In the JSCOP file the memory is represented as follows.
> +
> +
   > +"accesses": > +[{
> +           > +"kind": > +"write",
> +           > +"relation": > +"{ > +Stmt[i] -> + style="font-style: italic; font-weight: bold;">A + style="font-style: italic;">[i] > +}"
> +    }]
+ style="font-style: italic;"> > +
Useless style noise and  . Just use

> +
> +Suppose > +we want to perform a transformation such that the following
> +code is generated
> +
Get rid of
and use a single

. > +

for > +(i > += 0; i< 12; i++)
> + > +     A[0] = i;
> +
Style noise. Use
.

> +
> +The corresponding JSCOP file represenation would be
> +
> +
    > +"accesses": > +[{
> +           > +"kind": > +"read",
> +           Style and   noise. Just use
.

> +"relation":
> +"{
> +Stmt[i] -> + style="font-style: italic; font-weight: bold;">A or . For anything else define a new style in the 
.css files after verifying something similar is not available.

> + style="font-style: italic;">[0]
> +}"
> +    }]
+ style="font-style: italic;"> > +
Style noise. > +
> +We need to detect this access function change.
> +

> + Is this needed for anything? > + > + Again, thanks for your work Tobi From dpatel at apple.com Tue Jun 21 19:03:42 2011 From: dpatel at apple.com (Devang Patel) Date: Wed, 22 Jun 2011 00:03:42 -0000 Subject: [llvm-commits] [llvm] r133585 - /llvm/trunk/test/CodeGen/ARM/debug-info-blocks.ll Message-ID: <20110622000343.08D202A6C12C@llvm.org> Author: dpatel Date: Tue Jun 21 19:03:42 2011 New Revision: 133585 URL: http://llvm.org/viewvc/llvm-project?rev=133585&view=rev Log: Test case for r133560. Added: llvm/trunk/test/CodeGen/ARM/debug-info-blocks.ll Added: llvm/trunk/test/CodeGen/ARM/debug-info-blocks.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/debug-info-blocks.ll?rev=133585&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/debug-info-blocks.ll (added) +++ llvm/trunk/test/CodeGen/ARM/debug-info-blocks.ll Tue Jun 21 19:03:42 2011 @@ -0,0 +1,245 @@ +; RUN: llc -O0 < %s | FileCheck %s +; CHECK: @DEBUG_VALUE: mydata <- [sp+#8]+#0 +; Radar 9331779 +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:32:64-v128:32:128-a0:0:32-n32" +target triple = "thumbv7-apple-macosx10.7.0" + +%0 = type opaque +%1 = type { [4 x i32] } +%2 = type <{ i8*, i32, i32, i8*, %struct.Re*, i8*, %3*, %struct.my_struct* }> +%3 = type opaque +%struct.CP = type { float, float } +%struct.CR = type { %struct.CP, %struct.CP } +%struct.Re = type { i32, i32 } +%struct.__block_byref_mydata = type { i8*, %struct.__block_byref_mydata*, i32, i32, i8*, i8*, %0* } +%struct.my_struct = type opaque + +@"\01L_OBJC_SELECTOR_REFERENCES_13" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" +@"OBJC_IVAR_$_MyWork._bounds" = external hidden global i32, section "__DATA, __objc_const", align 4 +@"OBJC_IVAR_$_MyWork._data" = external hidden global i32, section "__DATA, __objc_const", align 4 +@"\01L_OBJC_SELECTOR_REFERENCES_222" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" + +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +declare i8* @objc_msgSend(i8*, i8*, ...) + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind + +define hidden void @foobar_func_block_invoke_0(i8* %.block_descriptor, %0* %loadedMydata, [4 x i32] %bounds.coerce0, [4 x i32] %data.coerce0) ssp { + %1 = alloca %0*, align 4 + %bounds = alloca %struct.CR, align 4 + %data = alloca %struct.CR, align 4 + call void @llvm.dbg.value(metadata !{i8* %.block_descriptor}, i64 0, metadata !27), !dbg !129 + store %0* %loadedMydata, %0** %1, align 4 + call void @llvm.dbg.declare(metadata !{%0** %1}, metadata !130), !dbg !131 + %2 = bitcast %struct.CR* %bounds to %1* + %3 = getelementptr %1* %2, i32 0, i32 0 + store [4 x i32] %bounds.coerce0, [4 x i32]* %3 + call void @llvm.dbg.declare(metadata !{%struct.CR* %bounds}, metadata !132), !dbg !133 + %4 = bitcast %struct.CR* %data to %1* + %5 = getelementptr %1* %4, i32 0, i32 0 + store [4 x i32] %data.coerce0, [4 x i32]* %5 + call void @llvm.dbg.declare(metadata !{%struct.CR* %data}, metadata !134), !dbg !135 + %6 = bitcast i8* %.block_descriptor to %2* + %7 = getelementptr inbounds %2* %6, i32 0, i32 6 + call void @llvm.dbg.declare(metadata !{%2* %6}, metadata !136), !dbg !137 + call void @llvm.dbg.declare(metadata !{%2* %6}, metadata !138), !dbg !137 + call void @llvm.dbg.declare(metadata !{%2* %6}, metadata !139), !dbg !140 + %8 = load %0** %1, align 4, !dbg !141 + %9 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_13", !dbg !141 + %10 = bitcast %0* %8 to i8*, !dbg !141 + %11 = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %10, i8* %9), !dbg !141 + %12 = bitcast i8* %11 to %0*, !dbg !141 + %13 = getelementptr inbounds %2* %6, i32 0, i32 5, !dbg !141 + %14 = load i8** %13, !dbg !141 + %15 = bitcast i8* %14 to %struct.__block_byref_mydata*, !dbg !141 + %16 = getelementptr inbounds %struct.__block_byref_mydata* %15, i32 0, i32 1, !dbg !141 + %17 = load %struct.__block_byref_mydata** %16, !dbg !141 + %18 = getelementptr inbounds %struct.__block_byref_mydata* %17, i32 0, i32 6, !dbg !141 + store %0* %12, %0** %18, align 4, !dbg !141 + %19 = getelementptr inbounds %2* %6, i32 0, i32 6, !dbg !143 + %20 = load %3** %19, align 4, !dbg !143 + %21 = load i32* @"OBJC_IVAR_$_MyWork._data", !dbg !143 + %22 = bitcast %3* %20 to i8*, !dbg !143 + %23 = getelementptr inbounds i8* %22, i32 %21, !dbg !143 + %24 = bitcast i8* %23 to %struct.CR*, !dbg !143 + %25 = bitcast %struct.CR* %24 to i8*, !dbg !143 + %26 = bitcast %struct.CR* %data to i8*, !dbg !143 + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %25, i8* %26, i32 16, i32 4, i1 false), !dbg !143 + %27 = getelementptr inbounds %2* %6, i32 0, i32 6, !dbg !144 + %28 = load %3** %27, align 4, !dbg !144 + %29 = load i32* @"OBJC_IVAR_$_MyWork._bounds", !dbg !144 + %30 = bitcast %3* %28 to i8*, !dbg !144 + %31 = getelementptr inbounds i8* %30, i32 %29, !dbg !144 + %32 = bitcast i8* %31 to %struct.CR*, !dbg !144 + %33 = bitcast %struct.CR* %32 to i8*, !dbg !144 + %34 = bitcast %struct.CR* %bounds to i8*, !dbg !144 + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %33, i8* %34, i32 16, i32 4, i1 false), !dbg !144 + %35 = getelementptr inbounds %2* %6, i32 0, i32 6, !dbg !145 + %36 = load %3** %35, align 4, !dbg !145 + %37 = getelementptr inbounds %2* %6, i32 0, i32 5, !dbg !145 + %38 = load i8** %37, !dbg !145 + %39 = bitcast i8* %38 to %struct.__block_byref_mydata*, !dbg !145 + %40 = getelementptr inbounds %struct.__block_byref_mydata* %39, i32 0, i32 1, !dbg !145 + %41 = load %struct.__block_byref_mydata** %40, !dbg !145 + %42 = getelementptr inbounds %struct.__block_byref_mydata* %41, i32 0, i32 6, !dbg !145 + %43 = load %0** %42, align 4, !dbg !145 + %44 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_222", !dbg !145 + %45 = bitcast %3* %36 to i8*, !dbg !145 + call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %0*)*)(i8* %45, i8* %44, %0* %43), !dbg !145 + ret void, !dbg !146 +} + +!llvm.dbg.cu = !{!0} +!llvm.dbg.enum = !{!1, !1, !5, !5, !9, !14, !19, !19, !14, !14, !14, !19, !19, !19} +!llvm.dbg.sp = !{!23} + +!0 = metadata !{i32 589841, i32 0, i32 16, metadata !"MyLibrary.i", metadata !"/Volumes/Sandbox/llvm", metadata !"Apple clang version 2.1", i1 true, i1 false, metadata !"", i32 2} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 589828, metadata !0, metadata !"", metadata !2, i32 248, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !3, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] +!2 = metadata !{i32 589865, metadata !"header.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!3 = metadata !{metadata !4} +!4 = metadata !{i32 589864, metadata !"Ver1", i64 0} ; [ DW_TAG_enumerator ] +!5 = metadata !{i32 589828, metadata !0, metadata !"Mode", metadata !6, i32 79, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !7, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] +!6 = metadata !{i32 589865, metadata !"header2.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!7 = metadata !{metadata !8} +!8 = metadata !{i32 589864, metadata !"One", i64 0} ; [ DW_TAG_enumerator ] +!9 = metadata !{i32 589828, metadata !0, metadata !"", metadata !10, i32 15, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !11, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] +!10 = metadata !{i32 589865, metadata !"header3.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!11 = metadata !{metadata !12, metadata !13} +!12 = metadata !{i32 589864, metadata !"Unknown", i64 0} ; [ DW_TAG_enumerator ] +!13 = metadata !{i32 589864, metadata !"Known", i64 1} ; [ DW_TAG_enumerator ] +!14 = metadata !{i32 589828, metadata !0, metadata !"", metadata !15, i32 20, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !16, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] +!15 = metadata !{i32 589865, metadata !"Private.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!16 = metadata !{metadata !17, metadata !18} +!17 = metadata !{i32 589864, metadata !"Single", i64 0} ; [ DW_TAG_enumerator ] +!18 = metadata !{i32 589864, metadata !"Double", i64 1} ; [ DW_TAG_enumerator ] +!19 = metadata !{i32 589828, metadata !0, metadata !"", metadata !20, i32 14, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !21, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] +!20 = metadata !{i32 589865, metadata !"header4.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!21 = metadata !{metadata !22} +!22 = metadata !{i32 589864, metadata !"Eleven", i64 0} ; [ DW_TAG_enumerator ] +!23 = metadata !{i32 589870, i32 0, metadata !24, metadata !"foobar_func_block_invoke_0", metadata !"foobar_func_block_invoke_0", metadata !"", metadata !24, i32 609, metadata !25, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void (i8*, %0*, [4 x i32], [4 x i32])* @foobar_func_block_invoke_0, null, null} ; [ DW_TAG_subprogram ] +!24 = metadata !{i32 589865, metadata !"MyLibrary.m", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!25 = metadata !{i32 589845, metadata !24, metadata !"", metadata !24, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !26, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!26 = metadata !{null} +!27 = metadata !{i32 590081, metadata !23, metadata !".block_descriptor", metadata !24, i32 16777825, metadata !28, i32 64} ; [ DW_TAG_arg_variable ] +!28 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 0, i64 0, i32 0, metadata !29} ; [ DW_TAG_pointer_type ] +!29 = metadata !{i32 589843, metadata !24, metadata !"__block_literal_14", metadata !24, i32 609, i64 256, i64 32, i32 0, i32 0, i32 0, metadata !30, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!30 = metadata !{metadata !31, metadata !33, metadata !35, metadata !36, metadata !37, metadata !48, metadata !89, metadata !124} +!31 = metadata !{i32 589837, metadata !24, metadata !"__isa", metadata !24, i32 609, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_member ] +!32 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] +!33 = metadata !{i32 589837, metadata !24, metadata !"__flags", metadata !24, i32 609, i64 32, i64 32, i64 32, i32 0, metadata !34} ; [ DW_TAG_member ] +!34 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!35 = metadata !{i32 589837, metadata !24, metadata !"__reserved", metadata !24, i32 609, i64 32, i64 32, i64 64, i32 0, metadata !34} ; [ DW_TAG_member ] +!36 = metadata !{i32 589837, metadata !24, metadata !"__FuncPtr", metadata !24, i32 609, i64 32, i64 32, i64 96, i32 0, metadata !32} ; [ DW_TAG_member ] +!37 = metadata !{i32 589837, metadata !24, metadata !"__descriptor", metadata !24, i32 609, i64 32, i64 32, i64 128, i32 0, metadata !38} ; [ DW_TAG_member ] +!38 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !39} ; [ DW_TAG_pointer_type ] +!39 = metadata !{i32 589843, metadata !0, metadata !"__block_descriptor_withcopydispose", metadata !40, i32 307, i64 128, i64 32, i32 0, i32 0, i32 0, metadata !41, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!40 = metadata !{i32 589865, metadata !"MyLibrary.i", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!41 = metadata !{metadata !42, metadata !44, metadata !45, metadata !47} +!42 = metadata !{i32 589837, metadata !40, metadata !"reserved", metadata !40, i32 307, i64 32, i64 32, i64 0, i32 0, metadata !43} ; [ DW_TAG_member ] +!43 = metadata !{i32 589860, metadata !0, metadata !"long unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!44 = metadata !{i32 589837, metadata !40, metadata !"Size", metadata !40, i32 307, i64 32, i64 32, i64 32, i32 0, metadata !43} ; [ DW_TAG_member ] +!45 = metadata !{i32 589837, metadata !40, metadata !"CopyFuncPtr", metadata !40, i32 307, i64 32, i64 32, i64 64, i32 0, metadata !46} ; [ DW_TAG_member ] +!46 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_pointer_type ] +!47 = metadata !{i32 589837, metadata !40, metadata !"DestroyFuncPtr", metadata !40, i32 307, i64 32, i64 32, i64 96, i32 0, metadata !46} ; [ DW_TAG_member ] +!48 = metadata !{i32 589837, metadata !24, metadata !"mydata", metadata !24, i32 609, i64 32, i64 32, i64 160, i32 0, metadata !49} ; [ DW_TAG_member ] +!49 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 0, i64 0, i32 0, metadata !50} ; [ DW_TAG_pointer_type ] +!50 = metadata !{i32 589843, metadata !24, metadata !"", metadata !24, i32 0, i64 224, i64 0, i32 0, i32 16, i32 0, metadata !51, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!51 = metadata !{metadata !52, metadata !53, metadata !54, metadata !55, metadata !56, metadata !57, metadata !58} +!52 = metadata !{i32 589837, metadata !24, metadata !"__isa", metadata !24, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_member ] +!53 = metadata !{i32 589837, metadata !24, metadata !"__forwarding", metadata !24, i32 0, i64 32, i64 32, i64 32, i32 0, metadata !32} ; [ DW_TAG_member ] +!54 = metadata !{i32 589837, metadata !24, metadata !"__flags", metadata !24, i32 0, i64 32, i64 32, i64 64, i32 0, metadata !34} ; [ DW_TAG_member ] +!55 = metadata !{i32 589837, metadata !24, metadata !"__size", metadata !24, i32 0, i64 32, i64 32, i64 96, i32 0, metadata !34} ; [ DW_TAG_member ] +!56 = metadata !{i32 589837, metadata !24, metadata !"__copy_helper", metadata !24, i32 0, i64 32, i64 32, i64 128, i32 0, metadata !32} ; [ DW_TAG_member ] +!57 = metadata !{i32 589837, metadata !24, metadata !"__destroy_helper", metadata !24, i32 0, i64 32, i64 32, i64 160, i32 0, metadata !32} ; [ DW_TAG_member ] +!58 = metadata !{i32 589837, metadata !24, metadata !"mydata", metadata !24, i32 0, i64 32, i64 32, i64 192, i32 0, metadata !59} ; [ DW_TAG_member ] +!59 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !60} ; [ DW_TAG_pointer_type ] +!60 = metadata !{i32 589843, metadata !24, metadata !"UIMydata", metadata !61, i32 26, i64 128, i64 32, i32 0, i32 0, i32 0, metadata !62, i32 16, i32 0} ; [ DW_TAG_structure_type ] +!61 = metadata !{i32 589865, metadata !"header11.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!62 = metadata !{metadata !63, metadata !71, metadata !75, metadata !79} +!63 = metadata !{i32 589852, metadata !60, null, metadata !61, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !64} ; [ DW_TAG_inheritance ] +!64 = metadata !{i32 589843, metadata !40, metadata !"NSO", metadata !65, i32 66, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !66, i32 16, i32 0} ; [ DW_TAG_structure_type ] +!65 = metadata !{i32 589865, metadata !"NSO.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!66 = metadata !{metadata !67} +!67 = metadata !{i32 589837, metadata !65, metadata !"isa", metadata !65, i32 67, i64 32, i64 32, i64 0, i32 2, metadata !68, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!68 = metadata !{i32 589846, metadata !0, metadata !"Class", metadata !40, i32 197, i64 0, i64 0, i64 0, i32 0, metadata !69} ; [ DW_TAG_typedef ] +!69 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !70} ; [ DW_TAG_pointer_type ] +!70 = metadata !{i32 589843, metadata !0, metadata !"objc_class", metadata !40, i32 0, i64 0, i64 0, i32 0, i32 4, i32 0, null, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!71 = metadata !{i32 589837, metadata !61, metadata !"_mydataRef", metadata !61, i32 28, i64 32, i64 32, i64 32, i32 0, metadata !72, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!72 = metadata !{i32 589846, metadata !0, metadata !"CFTypeRef", metadata !24, i32 313, i64 0, i64 0, i64 0, i32 0, metadata !73} ; [ DW_TAG_typedef ] +!73 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !74} ; [ DW_TAG_pointer_type ] +!74 = metadata !{i32 589862, metadata !0, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, null} ; [ DW_TAG_const_type ] +!75 = metadata !{i32 589837, metadata !61, metadata !"_scale", metadata !61, i32 29, i64 32, i64 32, i64 64, i32 0, metadata !76, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!76 = metadata !{i32 589846, metadata !0, metadata !"Float", metadata !77, i32 89, i64 0, i64 0, i64 0, i32 0, metadata !78} ; [ DW_TAG_typedef ] +!77 = metadata !{i32 589865, metadata !"header12.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!78 = metadata !{i32 589860, metadata !0, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!79 = metadata !{i32 589837, metadata !61, metadata !"_mydataFlags", metadata !61, i32 37, i64 8, i64 8, i64 96, i32 0, metadata !80, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!80 = metadata !{i32 589843, metadata !0, metadata !"", metadata !61, i32 30, i64 8, i64 8, i32 0, i32 0, i32 0, metadata !81, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!81 = metadata !{metadata !82, metadata !84, metadata !85, metadata !86, metadata !87, metadata !88} +!82 = metadata !{i32 589837, metadata !61, metadata !"named", metadata !61, i32 31, i64 1, i64 32, i64 0, i32 0, metadata !83} ; [ DW_TAG_member ] +!83 = metadata !{i32 589860, metadata !0, metadata !"unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!84 = metadata !{i32 589837, metadata !61, metadata !"mydataO", metadata !61, i32 32, i64 3, i64 32, i64 1, i32 0, metadata !83} ; [ DW_TAG_member ] +!85 = metadata !{i32 589837, metadata !61, metadata !"cached", metadata !61, i32 33, i64 1, i64 32, i64 4, i32 0, metadata !83} ; [ DW_TAG_member ] +!86 = metadata !{i32 589837, metadata !61, metadata !"hasBeenCached", metadata !61, i32 34, i64 1, i64 32, i64 5, i32 0, metadata !83} ; [ DW_TAG_member ] +!87 = metadata !{i32 589837, metadata !61, metadata !"hasPattern", metadata !61, i32 35, i64 1, i64 32, i64 6, i32 0, metadata !83} ; [ DW_TAG_member ] +!88 = metadata !{i32 589837, metadata !61, metadata !"isCIMydata", metadata !61, i32 36, i64 1, i64 32, i64 7, i32 0, metadata !83} ; [ DW_TAG_member ] +!89 = metadata !{i32 589837, metadata !24, metadata !"self", metadata !24, i32 609, i64 32, i64 32, i64 192, i32 0, metadata !90} ; [ DW_TAG_member ] +!90 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !91} ; [ DW_TAG_pointer_type ] +!91 = metadata !{i32 589843, metadata !40, metadata !"MyWork", metadata !24, i32 36, i64 384, i64 32, i32 0, i32 0, i32 0, metadata !92, i32 16, i32 0} ; [ DW_TAG_structure_type ] +!92 = metadata !{metadata !93, metadata !98, metadata !101, metadata !107, metadata !123} +!93 = metadata !{i32 589852, metadata !91, null, metadata !24, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !94} ; [ DW_TAG_inheritance ] +!94 = metadata !{i32 589843, metadata !40, metadata !"twork", metadata !95, i32 43, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !96, i32 16, i32 0} ; [ DW_TAG_structure_type ] +!95 = metadata !{i32 589865, metadata !"header13.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!96 = metadata !{metadata !97} +!97 = metadata !{i32 589852, metadata !94, null, metadata !95, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !64} ; [ DW_TAG_inheritance ] +!98 = metadata !{i32 589837, metadata !24, metadata !"_itemID", metadata !24, i32 38, i64 64, i64 32, i64 32, i32 1, metadata !99, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!99 = metadata !{i32 589846, metadata !0, metadata !"uint64_t", metadata !40, i32 55, i64 0, i64 0, i64 0, i32 0, metadata !100} ; [ DW_TAG_typedef ] +!100 = metadata !{i32 589860, metadata !0, metadata !"long long unsigned int", null, i32 0, i64 64, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!101 = metadata !{i32 589837, metadata !24, metadata !"_library", metadata !24, i32 39, i64 32, i64 32, i64 96, i32 1, metadata !102, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!102 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !103} ; [ DW_TAG_pointer_type ] +!103 = metadata !{i32 589843, metadata !40, metadata !"MyLibrary2", metadata !104, i32 22, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !105, i32 16, i32 0} ; [ DW_TAG_structure_type ] +!104 = metadata !{i32 589865, metadata !"header14.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!105 = metadata !{metadata !106} +!106 = metadata !{i32 589852, metadata !103, null, metadata !104, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !64} ; [ DW_TAG_inheritance ] +!107 = metadata !{i32 589837, metadata !24, metadata !"_bounds", metadata !24, i32 40, i64 128, i64 32, i64 128, i32 1, metadata !108, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!108 = metadata !{i32 589846, metadata !0, metadata !"CR", metadata !40, i32 33, i64 0, i64 0, i64 0, i32 0, metadata !109} ; [ DW_TAG_typedef ] +!109 = metadata !{i32 589843, metadata !0, metadata !"CR", metadata !77, i32 29, i64 128, i64 32, i32 0, i32 0, i32 0, metadata !110, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!110 = metadata !{metadata !111, metadata !117} +!111 = metadata !{i32 589837, metadata !77, metadata !"origin", metadata !77, i32 30, i64 64, i64 32, i64 0, i32 0, metadata !112} ; [ DW_TAG_member ] +!112 = metadata !{i32 589846, metadata !0, metadata !"CP", metadata !77, i32 17, i64 0, i64 0, i64 0, i32 0, metadata !113} ; [ DW_TAG_typedef ] +!113 = metadata !{i32 589843, metadata !0, metadata !"CP", metadata !77, i32 13, i64 64, i64 32, i32 0, i32 0, i32 0, metadata !114, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!114 = metadata !{metadata !115, metadata !116} +!115 = metadata !{i32 589837, metadata !77, metadata !"x", metadata !77, i32 14, i64 32, i64 32, i64 0, i32 0, metadata !76} ; [ DW_TAG_member ] +!116 = metadata !{i32 589837, metadata !77, metadata !"y", metadata !77, i32 15, i64 32, i64 32, i64 32, i32 0, metadata !76} ; [ DW_TAG_member ] +!117 = metadata !{i32 589837, metadata !77, metadata !"size", metadata !77, i32 31, i64 64, i64 32, i64 64, i32 0, metadata !118} ; [ DW_TAG_member ] +!118 = metadata !{i32 589846, metadata !0, metadata !"Size", metadata !77, i32 25, i64 0, i64 0, i64 0, i32 0, metadata !119} ; [ DW_TAG_typedef ] +!119 = metadata !{i32 589843, metadata !0, metadata !"Size", metadata !77, i32 21, i64 64, i64 32, i32 0, i32 0, i32 0, metadata !120, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!120 = metadata !{metadata !121, metadata !122} +!121 = metadata !{i32 589837, metadata !77, metadata !"width", metadata !77, i32 22, i64 32, i64 32, i64 0, i32 0, metadata !76} ; [ DW_TAG_member ] +!122 = metadata !{i32 589837, metadata !77, metadata !"height", metadata !77, i32 23, i64 32, i64 32, i64 32, i32 0, metadata !76} ; [ DW_TAG_member ] +!123 = metadata !{i32 589837, metadata !24, metadata !"_data", metadata !24, i32 40, i64 128, i64 32, i64 256, i32 1, metadata !108, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!124 = metadata !{i32 589837, metadata !24, metadata !"semi", metadata !24, i32 609, i64 32, i64 32, i64 224, i32 0, metadata !125} ; [ DW_TAG_member ] +!125 = metadata !{i32 589846, metadata !0, metadata !"d_t", metadata !24, i32 35, i64 0, i64 0, i64 0, i32 0, metadata !126} ; [ DW_TAG_typedef ] +!126 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !127} ; [ DW_TAG_pointer_type ] +!127 = metadata !{i32 589843, metadata !0, metadata !"my_struct", metadata !128, i32 49, i64 0, i64 0, i32 0, i32 4, i32 0, null, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!128 = metadata !{i32 589865, metadata !"header15.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!129 = metadata !{i32 609, i32 144, metadata !23, null} +!130 = metadata !{i32 590081, metadata !23, metadata !"loadedMydata", metadata !24, i32 33555041, metadata !59, i32 0} ; [ DW_TAG_arg_variable ] +!131 = metadata !{i32 609, i32 155, metadata !23, null} +!132 = metadata !{i32 590081, metadata !23, metadata !"bounds", metadata !24, i32 50332257, metadata !108, i32 0} ; [ DW_TAG_arg_variable ] +!133 = metadata !{i32 609, i32 175, metadata !23, null} +!134 = metadata !{i32 590081, metadata !23, metadata !"data", metadata !24, i32 67109473, metadata !108, i32 0} ; [ DW_TAG_arg_variable ] +!135 = metadata !{i32 609, i32 190, metadata !23, null} +!136 = metadata !{i32 590080, metadata !23, metadata !"mydata", metadata !24, i32 604, metadata !50, i32 0, i64 1, i64 20, i64 2, i64 1, i64 4, i64 2, i64 1, i64 24} ; [ DW_TAG_auto_variable ] +!137 = metadata !{i32 604, i32 49, metadata !23, null} +!138 = metadata !{i32 590080, metadata !23, metadata !"self", metadata !40, i32 604, metadata !90, i32 0, i64 1, i64 24} ; [ DW_TAG_auto_variable ] +!139 = metadata !{i32 590080, metadata !23, metadata !"semi", metadata !24, i32 607, metadata !125, i32 0, i64 1, i64 28} ; [ DW_TAG_auto_variable ] +!140 = metadata !{i32 607, i32 30, metadata !23, null} +!141 = metadata !{i32 610, i32 17, metadata !142, null} +!142 = metadata !{i32 589835, metadata !23, i32 609, i32 200, metadata !24, i32 94} ; [ DW_TAG_lexical_block ] +!143 = metadata !{i32 611, i32 17, metadata !142, null} +!144 = metadata !{i32 612, i32 17, metadata !142, null} +!145 = metadata !{i32 613, i32 17, metadata !142, null} +!146 = metadata !{i32 615, i32 13, metadata !142, null} From justin.holewinski at gmail.com Tue Jun 21 19:43:56 2011 From: justin.holewinski at gmail.com (Justin Holewinski) Date: Wed, 22 Jun 2011 00:43:56 -0000 Subject: [llvm-commits] [llvm] r133589 - in /llvm/trunk: lib/Target/PTX/PTXAsmPrinter.cpp test/CodeGen/PTX/options.ll Message-ID: <20110622004356.D0DE82A6C12C@llvm.org> Author: jholewinski Date: Tue Jun 21 19:43:56 2011 New Revision: 133589 URL: http://llvm.org/viewvc/llvm-project?rev=133589&view=rev Log: PTX: Add .address_size directive if PTX version >= 2.3 Patch by Wei-Ren Chen Modified: llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp llvm/trunk/test/CodeGen/PTX/options.ll Modified: llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp?rev=133589&r1=133588&r2=133589&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp Tue Jun 21 19:43:56 2011 @@ -163,6 +163,13 @@ OutStreamer.EmitRawText(Twine("\t.target " + ST.getTargetString() + (ST.supportsDouble() ? "" : ", map_f64_to_f32"))); + // .address_size directive is optional, but it must immediately follow + // the .target directive if present within a module + if (ST.supportsPTX23()) { + std::string addrSize = ST.is64Bit() ? "64" : "32"; + OutStreamer.EmitRawText(Twine("\t.address_size " + addrSize)); + } + OutStreamer.AddBlankLine(); // declare global variables Modified: llvm/trunk/test/CodeGen/PTX/options.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/options.ll?rev=133589&r1=133588&r2=133589&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PTX/options.ll (original) +++ llvm/trunk/test/CodeGen/PTX/options.ll Tue Jun 21 19:43:56 2011 @@ -5,6 +5,8 @@ ; RUN: llc < %s -march=ptx32 -mattr=sm10 | grep ".target sm_10" ; RUN: llc < %s -march=ptx32 -mattr=sm13 | grep ".target sm_13" ; RUN: llc < %s -march=ptx32 -mattr=sm20 | grep ".target sm_20" +; RUN: llc < %s -march=ptx32 -mattr=ptx23 | grep ".address_size 32" +; RUN: llc < %s -march=ptx64 -mattr=ptx23 | grep ".address_size 64" define ptx_device void @t1() { ret void From justin.holewinski at gmail.com Tue Jun 21 19:53:57 2011 From: justin.holewinski at gmail.com (Justin Holewinski) Date: Tue, 21 Jun 2011 20:53:57 -0400 Subject: [llvm-commits] [PATCH][Target/PTX] Add address_size directive to PTX backend In-Reply-To: <20110621013634.GA86556@cs.nctu.edu.tw> References: <20110617073109.GA93378@cs.nctu.edu.tw> <20110618065617.GA25444@cs.nctu.edu.tw> <20110619121258.GA50677@cs.nctu.edu.tw> <347A9771-6ADD-4454-86D6-2842AEA82D44@gmail.com> <20110620015129.GA56262@cs.nctu.edu.tw> <20110621013634.GA86556@cs.nctu.edu.tw> Message-ID: <6005FDC7-17E5-4E89-8561-5EC94F14DF34@gmail.com> On Jun 20, 2011, at 9:36 PM, ??? wrote: >> I hate to nit-pick, but do we really need the address size field and associated enumeration? It's always tied to the 64-bit flag, and we do not need to create any TableGen predicates from the value. >> >> I think this patch can be as simple as: >> >> if (ST.supportsPTX23()) { >> std::string addrSize = is64Bit() ? "64" : "32"; >> OutStreamer.EmitRawText(Twine("\t.address_size " + addrSize)); >> } > > Done. Looks good! Committed in r133589. > > Regards, > chenwj > > -- > Wei-Ren Chen (???) > Computer Systems Lab, Institute of Information Science, > Academia Sinica, Taiwan (R.O.C.) > Tel:886-2-2788-3799 #1667 > Thanks, Justin Holewinski -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110621/a1105dbf/attachment.html From aggarwa4 at illinois.edu Tue Jun 21 20:03:49 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Wed, 22 Jun 2011 01:03:49 -0000 Subject: [llvm-commits] [poolalloc] r133592 - /poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Message-ID: <20110622010349.63B022A6C12C@llvm.org> Author: aggarwa4 Date: Tue Jun 21 20:03:49 2011 New Revision: 133592 URL: http://llvm.org/viewvc/llvm-project?rev=133592&view=rev Log: If we do not know where a va_list came from, do not insert checks. Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=133592&r1=133591&r2=133592&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Tue Jun 21 20:03:49 2011 @@ -495,6 +495,13 @@ } } + if(CounterMap.find(CI->getOperand(VAListArgNum)->stripPointerCasts()) == CounterMap.end()) { + // If this is a va_list we do not know about, + // do not insert checks. + + // FIXME: Handle cases where va_list is stored in memory + continue; + } Function::arg_iterator NII = F->arg_begin(); std::vectorArgs; Args.push_back(NII++); // total count @@ -517,150 +524,162 @@ } } - bool TypeChecks::visitVAListFunction(Module &M, Function &F_orig) { - if(!F_orig.hasInternalLinkage()) - return false; +bool TypeChecks::visitVAListFunction(Module &M, Function &F_orig) { + if(!F_orig.hasInternalLinkage()) + return false; - int VAListArgNum = 0; - // Check if one of the arguments is a va_list - const Type *ListType = M.getTypeByName("struct.__va_list_tag"); - if(!ListType) - return false; - const Type *ListPtrType = ListType->getPointerTo(); - Argument *VAListArg = NULL; - for (Function::arg_iterator I = F_orig.arg_begin(); - I != F_orig.arg_end(); ++I) { - VAListArgNum ++; - if(I->getType() == ListPtrType) { - VAListArg = I; - break; - } - } - - // Clone the function to add arguments for count, MD - - // 1. Create the new argument types vector - std::vectorTP; - TP.push_back(Int64Ty); // for count - TP.push_back(Int64Ty); // for count - TP.push_back(VoidPtrTy); // for MD - for (Function::arg_iterator I = F_orig.arg_begin(); - I != F_orig.arg_end(); ++I) { - TP.push_back(I->getType()); - } - // 2. Create the new function prototype - const FunctionType *NewFTy = FunctionType::get(F_orig.getReturnType(), - TP,/*argument types*/ - false);/*vararg*/ - Function *F = Function::Create(NewFTy, - GlobalValue::InternalLinkage, - F_orig.getNameStr() + ".INT", - &M); - - // 3. Set the mapping for args - Function::arg_iterator NI = F->arg_begin(); - DenseMap ValueMap; - NI->setName("TotalCount"); - NI++; - NI->setName("CurrentCount"); - NI++; - NI->setName("MD"); - NI++; - for (Function::arg_iterator II = F_orig.arg_begin(); - NI != F->arg_end(); ++II, ++NI) { - // Each new argument maps to the argument in the old function - // For these arguments, also copy over the attributes - ValueMap[II] = NI; - NI->setName(II->getName()); - NI->addAttr(F_orig.getAttributes() - .getParamAttributes(II->getArgNo() + 1)); - } - - // 4. Copy over the attributes for the function. - F->setAttributes(F->getAttributes() - .addAttr(0, F_orig.getAttributes().getRetAttributes())); - F->setAttributes(F->getAttributes() - .addAttr(~0, F_orig.getAttributes().getFnAttributes())); - - // 5. Perform the cloning. - SmallVector Returns; - CloneFunctionInto(F, &F_orig, ValueMap, Returns); - - VAListFunctionsMap[&F_orig] = F; - inst_iterator InsPt = inst_begin(F); - - - // Store the information - Function::arg_iterator NII = F->arg_begin(); - AllocaInst *VASizeLoc = new AllocaInst(Int64Ty, "", &*InsPt); - new StoreInst(NII, VASizeLoc, &*InsPt); - NII++; - AllocaInst *Counter = new AllocaInst(Int64Ty, "",&*InsPt); - new StoreInst(NII, Counter, &*InsPt); - errs() << F->getNameStr() <<"\n"; - NII++; - AllocaInst *VAMDLoc = new AllocaInst(VoidPtrTy, "", &*InsPt); - new StoreInst(NII, VAMDLoc, &*InsPt); - - CounterMap[ValueMap[VAListArg]] = Counter; - // Find all va_copy calls - for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { - for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;I++) { - CallInst *CI = dyn_cast(I); - if(!CI) - continue; - Function *CalledF = dyn_cast(CI->getCalledFunction()); - if(!CalledF) - continue; - if(!CalledF->isIntrinsic()) - continue; - if(CalledF->getIntrinsicID() != Intrinsic::vacopy) - continue; - // Reinitialize the counter - AllocaInst *CounterDest = new AllocaInst(Int64Ty, "",&*InsPt); - Value *CounterSource = CounterMap[CI->getOperand(2)->stripPointerCasts()]; - LoadInst *CurrentValue = new LoadInst(CounterSource, "count", CI); - new StoreInst(CurrentValue, CounterDest, CI); - CounterMap[CI->getOperand(1)->stripPointerCasts()] = CounterDest; - } + int VAListArgNum = 0; + // Check if one of the arguments is a va_list + const Type *ListType = M.getTypeByName("struct.__va_list_tag"); + if(!ListType) + return false; + const Type *ListPtrType = ListType->getPointerTo(); + Argument *VAListArg = NULL; + for (Function::arg_iterator I = F_orig.arg_begin(); + I != F_orig.arg_end(); ++I) { + VAListArgNum ++; + if(I->getType() == ListPtrType) { + VAListArg = I; + break; } + } + // Clone the function to add arguments for count, MD - // instrument va_arg to increment the counter - for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { - for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { - VAArgInst *VI = dyn_cast(I++); - if(!VI) - continue; - Constant *One = ConstantInt::get(Int64Ty, 1); - VI->getOperand(0)->stripPointerCasts()->dump(); - Value *CounterSrc = CounterMap[VI->getOperand(0)->stripPointerCasts()]; - CounterSrc->dump(); - LoadInst *OldValue = new LoadInst(CounterSrc, "count", VI); - Instruction *NewValue = BinaryOperator::Create(BinaryOperator::Add, - OldValue, - One, - "count", - VI); - new StoreInst(NewValue, CounterSrc, VI); - std::vector Args; - Instruction *VASize = new LoadInst(VASizeLoc, "", VI); - Instruction *VAMetaData = new LoadInst(VAMDLoc, "", VI); - Args.push_back(VASize); - Args.push_back(OldValue); - Args.push_back(getTypeMarkerConstant(VI)); - Args.push_back(VAMetaData); - Args.push_back(getTagCounter()); - CallInst::Create(compareTypeAndNumber, - Args.begin(), - Args.end(), - "", VI); + // 1. Create the new argument types vector + std::vectorTP; + TP.push_back(Int64Ty); // for count + TP.push_back(Int64Ty); // for count + TP.push_back(VoidPtrTy); // for MD + for (Function::arg_iterator I = F_orig.arg_begin(); + I != F_orig.arg_end(); ++I) { + TP.push_back(I->getType()); + } + // 2. Create the new function prototype + const FunctionType *NewFTy = FunctionType::get(F_orig.getReturnType(), + TP,/*argument types*/ + false);/*vararg*/ + Function *F = Function::Create(NewFTy, + GlobalValue::InternalLinkage, + F_orig.getNameStr() + ".INT", + &M); + + // 3. Set the mapping for args + Function::arg_iterator NI = F->arg_begin(); + DenseMap ValueMap; + NI->setName("TotalCount"); + NI++; + NI->setName("CurrentCount"); + NI++; + NI->setName("MD"); + NI++; + for (Function::arg_iterator II = F_orig.arg_begin(); + NI != F->arg_end(); ++II, ++NI) { + // Each new argument maps to the argument in the old function + // For these arguments, also copy over the attributes + ValueMap[II] = NI; + NI->setName(II->getName()); + NI->addAttr(F_orig.getAttributes() + .getParamAttributes(II->getArgNo() + 1)); + } + + // 4. Copy over the attributes for the function. + F->setAttributes(F->getAttributes() + .addAttr(0, F_orig.getAttributes().getRetAttributes())); + F->setAttributes(F->getAttributes() + .addAttr(~0, F_orig.getAttributes().getFnAttributes())); + + // 5. Perform the cloning. + SmallVector Returns; + CloneFunctionInto(F, &F_orig, ValueMap, Returns); + + VAListFunctionsMap[&F_orig] = F; + inst_iterator InsPt = inst_begin(F); + + + // Store the information + Function::arg_iterator NII = F->arg_begin(); + AllocaInst *VASizeLoc = new AllocaInst(Int64Ty, "", &*InsPt); + new StoreInst(NII, VASizeLoc, &*InsPt); + NII++; + AllocaInst *Counter = new AllocaInst(Int64Ty, "",&*InsPt); + new StoreInst(NII, Counter, &*InsPt); + errs() << F->getNameStr() <<"\n"; + NII++; + AllocaInst *VAMDLoc = new AllocaInst(VoidPtrTy, "", &*InsPt); + new StoreInst(NII, VAMDLoc, &*InsPt); + + CounterMap[ValueMap[VAListArg]] = Counter; + // Find all va_copy calls + for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { + for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;I++) { + CallInst *CI = dyn_cast(I); + if(!CI) + continue; + Function *CalledF = dyn_cast(CI->getCalledFunction()); + if(!CalledF) + continue; + if(!CalledF->isIntrinsic()) + continue; + if(CalledF->getIntrinsicID() != Intrinsic::vacopy) + continue; + if(CounterMap.find(CI->getOperand(2)->stripPointerCasts()) == CounterMap.end()) { + // If this is a va_list we do not know about, + // do not insert checks. + + // FIXME: Handle cases where va_list is stored in memory + continue; } + // Reinitialize the counter + AllocaInst *CounterDest = new AllocaInst(Int64Ty, "",&*InsPt); + Value *CounterSource = CounterMap[CI->getOperand(2)->stripPointerCasts()]; + LoadInst *CurrentValue = new LoadInst(CounterSource, "count", CI); + new StoreInst(CurrentValue, CounterDest, CI); + CounterMap[CI->getOperand(1)->stripPointerCasts()] = CounterDest; } + } - return true; + + // instrument va_arg to increment the counter + for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { + for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { + VAArgInst *VI = dyn_cast(I++); + if(!VI) + continue; + if(CounterMap.find(VI->getOperand(0)->stripPointerCasts()) == CounterMap.end()) { + // If this is a va_list we do not know about, + // do not insert checks. + + // FIXME: Handle cases where va_list is stored in memory + continue; + } + Constant *One = ConstantInt::get(Int64Ty, 1); + Value *CounterSrc = CounterMap[VI->getOperand(0)->stripPointerCasts()]; + LoadInst *OldValue = new LoadInst(CounterSrc, "count", VI); + Instruction *NewValue = BinaryOperator::Create(BinaryOperator::Add, + OldValue, + One, + "count", + VI); + new StoreInst(NewValue, CounterSrc, VI); + std::vector Args; + Instruction *VASize = new LoadInst(VASizeLoc, "", VI); + Instruction *VAMetaData = new LoadInst(VAMDLoc, "", VI); + Args.push_back(VASize); + Args.push_back(OldValue); + Args.push_back(getTypeMarkerConstant(VI)); + Args.push_back(VAMetaData); + Args.push_back(getTagCounter()); + CallInst::Create(compareTypeAndNumber, + Args.begin(), + Args.end(), + "", VI); + } } + return true; +} + bool TypeChecks::visitAddressTakenFunction(Module &M, Function &F) { // Clone function // 1. Create the new argument types vector @@ -915,6 +934,13 @@ VAArgInst *VI = dyn_cast(I++); if(!VI) continue; + if(CounterMap.find(VI->getOperand(0)->stripPointerCasts()) == CounterMap.end()) { + // If this is a va_list we do not know about, + // do not insert checks. + + // FIXME: Handle cases where va_list is stored in memory + continue; + } Constant *One = ConstantInt::get(Int64Ty, 1); Value *CounterSrc = CounterMap[VI->getOperand(0)->stripPointerCasts()]; LoadInst *OldValue = new LoadInst(CounterSrc, "count", VI); From jstaszak at apple.com Tue Jun 21 20:10:59 2011 From: jstaszak at apple.com (Jakub Staszak) Date: Tue, 21 Jun 2011 18:10:59 -0700 Subject: [llvm-commits] BlockFrequency for BasicBlocks In-Reply-To: References: <1E9CE6F5-A2AC-4A81-A001-D19DAB65255B@apple.com> Message-ID: <98818310-FEB0-4E4D-8B38-E14698BFD9BE@apple.com> The new version attached. OK to commit now? On Jun 17, 2011, at 4:10 PM, Andrew Trick wrote: > Hi Kuba, > > If you define the constructor and destructor in the .cpp, then do you still need to include InitializePasses.h from BlockFrequency.h. Done, i also removed "LoopInfo.h" > And do you really need a "deinit" method? Yes, if I try to delete BFI in destructor I get a warning ("note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined."). > The block frequency pass should only require a *single* CFG graph traversal. I'm not sure how to do that with LLVM's current rpot/pot iterators. Ideally, LLVM would have a DFSOrder analysis to order the blocks. That ordering will remain valid until some CFG transform. I removed PO vector, so we have one RPO and one PO traversal now. > For, now I think you can at least limit it to two traversals (one reverse postorder and one postorder) and add a FIXME so we remember to fold it into one traversal later. Subsequently whenever you need to visit blocks in RPO/PO order, just use the RPO/PO vectors directly. > > Can you also comment that LoopSimplify can make the algorithm converge faster. Done. > Can frequency reach zero in divBlockFreq? Don't you want to saturate at 1? I think it can, so i jest set it to 1/START_FREQ. - Kuba -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110621/c2ae0f2c/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: bf4bb.4.patch Type: application/octet-stream Size: 17891 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110621/c2ae0f2c/attachment.obj -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110621/c2ae0f2c/attachment-0001.html From justin.holewinski at gmail.com Tue Jun 21 21:09:50 2011 From: justin.holewinski at gmail.com (Justin Holewinski) Date: Wed, 22 Jun 2011 02:09:50 -0000 Subject: [llvm-commits] [llvm] r133599 - in /llvm/trunk: lib/Target/PTX/PTXInstrInfo.td test/CodeGen/PTX/setp.ll Message-ID: <20110622020950.91E432A6C12C@llvm.org> Author: jholewinski Date: Tue Jun 21 21:09:50 2011 New Revision: 133599 URL: http://llvm.org/viewvc/llvm-project?rev=133599&view=rev Log: PTX: Add signed integer comparisons Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td llvm/trunk/test/CodeGen/PTX/setp.ll Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.td?rev=133599&r1=133598&r2=133599&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Tue Jun 21 21:09:50 2011 @@ -696,6 +696,10 @@ defm SETPLEu16 : PTX_SETP_I; defm SETPGTu16 : PTX_SETP_I; defm SETPGEu16 : PTX_SETP_I; +defm SETPLTs16 : PTX_SETP_I; +defm SETPLEs16 : PTX_SETP_I; +defm SETPGTs16 : PTX_SETP_I; +defm SETPGEs16 : PTX_SETP_I; // Compare u32 @@ -705,6 +709,10 @@ defm SETPLEu32 : PTX_SETP_I; defm SETPGTu32 : PTX_SETP_I; defm SETPGEu32 : PTX_SETP_I; +defm SETPLTs32 : PTX_SETP_I; +defm SETPLEs32 : PTX_SETP_I; +defm SETPGTs32 : PTX_SETP_I; +defm SETPGEs32 : PTX_SETP_I; // Compare u64 @@ -714,6 +722,10 @@ defm SETPLEu64 : PTX_SETP_I; defm SETPGTu64 : PTX_SETP_I; defm SETPGEu64 : PTX_SETP_I; +defm SETPLTs64 : PTX_SETP_I; +defm SETPLEs64 : PTX_SETP_I; +defm SETPGTs64 : PTX_SETP_I; +defm SETPGEs64 : PTX_SETP_I; // Compare f32 Modified: llvm/trunk/test/CodeGen/PTX/setp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/setp.ll?rev=133599&r1=133598&r2=133599&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PTX/setp.ll (original) +++ llvm/trunk/test/CodeGen/PTX/setp.ll Tue Jun 21 21:09:50 2011 @@ -54,6 +54,42 @@ ret i32 %z } +define ptx_device i32 @test_setp_lt_s32_rr(i32 %x, i32 %y) { +; CHECK: setp.lt.s32 p0, r1, r2; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; + %p = icmp slt i32 %x, %y + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_le_s32_rr(i32 %x, i32 %y) { +; CHECK: setp.le.s32 p0, r1, r2; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; + %p = icmp sle i32 %x, %y + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_gt_s32_rr(i32 %x, i32 %y) { +; CHECK: setp.gt.s32 p0, r1, r2; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; + %p = icmp sgt i32 %x, %y + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_ge_s32_rr(i32 %x, i32 %y) { +; CHECK: setp.ge.s32 p0, r1, r2; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; + %p = icmp sge i32 %x, %y + %z = zext i1 %p to i32 + ret i32 %z +} + define ptx_device i32 @test_setp_eq_u32_ri(i32 %x) { ; CHECK: setp.eq.u32 p0, r1, 1; ; CHECK-NEXT: selp.u32 r0, 1, 0, p0; @@ -108,6 +144,42 @@ ret i32 %z } +define ptx_device i32 @test_setp_lt_s32_ri(i32 %x) { +; CHECK: setp.lt.s32 p0, r1, 1; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; + %p = icmp slt i32 %x, 1 + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_le_s32_ri(i32 %x) { +; CHECK: setp.lt.s32 p0, r1, 2; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; + %p = icmp sle i32 %x, 1 + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_gt_s32_ri(i32 %x) { +; CHECK: setp.gt.s32 p0, r1, 1; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; + %p = icmp sgt i32 %x, 1 + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_ge_s32_ri(i32 %x) { +; CHECK: setp.gt.s32 p0, r1, 0; +; CHECK-NEXT: selp.u32 r0, 1, 0, p0; +; CHECK-NEXT: ret; + %p = icmp sge i32 %x, 1 + %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; From atrick at apple.com Tue Jun 21 22:21:08 2011 From: atrick at apple.com (Andrew Trick) Date: Tue, 21 Jun 2011 20:21:08 -0700 Subject: [llvm-commits] BlockFrequency for BasicBlocks In-Reply-To: <98818310-FEB0-4E4D-8B38-E14698BFD9BE@apple.com> References: <1E9CE6F5-A2AC-4A81-A001-D19DAB65255B@apple.com> <98818310-FEB0-4E4D-8B38-E14698BFD9BE@apple.com> Message-ID: On Jun 21, 2011, at 6:10 PM, Jakub Staszak wrote: > The new version attached. OK to commit now? > > On Jun 17, 2011, at 4:10 PM, Andrew Trick wrote: > >> Hi Kuba, >> >> If you define the constructor and destructor in the .cpp, then do you still need to include InitializePasses.h from BlockFrequency.h. > Done, i also removed "LoopInfo.h" > >> And do you really need a "deinit" method? > Yes, if I try to delete BFI in destructor I get a warning ("note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined."). I'm unclear why you have the ctor/dtor defined in the header. Try moving them to the .cpp. > >> The block frequency pass should only require a *single* CFG graph traversal. I'm not sure how to do that with LLVM's current rpot/pot iterators. Ideally, LLVM would have a DFSOrder analysis to order the blocks. That ordering will remain valid until some CFG transform. > I removed PO vector, so we have one RPO and one PO traversal now. > >> For, now I think you can at least limit it to two traversals (one reverse postorder and one postorder) and add a FIXME so we remember to fold it into one traversal later. Subsequently whenever you need to visit blocks in RPO/PO order, just use the RPO/PO vectors directly. >> >> Can you also comment that LoopSimplify can make the algorithm converge faster. > Done. > >> Can frequency reach zero in divBlockFreq? Don't you want to saturate at 1? > I think it can, so i jest set it to 1/START_FREQ. Yes, by "1" I meant literal 1, not scaled 1. I think this could happen inside getEdgeFreq() when (N * getBlockFreq(Src)) < D. You should probably check for that case and return the smallest nonzero frequency. You actually shouldn't have a problem in divBlockFreq, but somewhere you should assert that the input BranchProbability is well-formed (N < D). -Andy -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110621/4fe317aa/attachment.html From rafael.espindola at gmail.com Tue Jun 21 23:01:59 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 22 Jun 2011 04:01:59 -0000 Subject: [llvm-commits] [llvm] r133607 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp Message-ID: <20110622040159.1F7682A6C12C@llvm.org> Author: rafael Date: Tue Jun 21 23:01:58 2011 New Revision: 133607 URL: http://llvm.org/viewvc/llvm-project?rev=133607&view=rev Log: Reenable the optimization added in 133415, but change the definition of a "simple" bb to be one with only one unconditional branch and no phis. Duplicating the phis in this case is possible, but requeres liveness analysis or breaking edges. Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=133607&r1=133606&r2=133607&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Tue Jun 21 23:01:58 2011 @@ -568,9 +568,9 @@ TailDuplicatePass::isSimpleBB(MachineBasicBlock *TailBB) { if (TailBB->succ_size() != 1) return false; - MachineBasicBlock::iterator I = TailBB->getFirstNonPHI(); + MachineBasicBlock::iterator I = TailBB->begin(); MachineBasicBlock::iterator E = TailBB->end(); - while (I->isDebugValue() && I != E) + while (I != E && I->isDebugValue()) ++I; if (I == E) return true; @@ -712,7 +712,7 @@ DenseSet UsedByPhi; getRegsUsedByPHIs(*TailBB, &UsedByPhi); - if (0 && isSimpleBB(TailBB)) + if (isSimpleBB(TailBB)) return duplicateSimpleBB(TailBB, TDBBs, UsedByPhi, Copies); // Iterate through all the unique predecessors and tail-duplicate this From atrick at apple.com Wed Jun 22 00:43:36 2011 From: atrick at apple.com (Andrew Trick) Date: Wed, 22 Jun 2011 05:43:36 -0000 Subject: [llvm-commits] [llvm] r133608 - /llvm/trunk/test/CMakeLists.txt Message-ID: <20110622054336.66E7B2A6C12C@llvm.org> Author: atrick Date: Wed Jun 22 00:43:36 2011 New Revision: 133608 URL: http://llvm.org/viewvc/llvm-project?rev=133608&view=rev Log: Only do config-time substitution of LLVM_BUILD_MODE in test/lit.site.cfg, not Unit/test/lit.site.cfg. Modified: llvm/trunk/test/CMakeLists.txt Modified: llvm/trunk/test/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CMakeLists.txt?rev=133608&r1=133607&r2=133608&view=diff ============================================================================== --- llvm/trunk/test/CMakeLists.txt (original) +++ llvm/trunk/test/CMakeLists.txt Wed Jun 22 00:43:36 2011 @@ -71,8 +71,6 @@ MAKE_DIRECTORY(${CMAKE_CURRENT_BINARY_DIR}/Unit) # Configuration-time: See Unit/lit.site.cfg.in - set(LLVM_BUILD_MODE "${LLVM_BUILD_MODE}") - set(LLVM_SOURCE_DIR ${LLVM_MAIN_SRC_DIR}) set(LLVM_BINARY_DIR ${LLVM_BINARY_DIR}) set(LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}/%(build_config)s") @@ -81,10 +79,17 @@ set(ENABLE_SHARED ${LLVM_SHARED_LIBS_ENABLED}) set(SHLIBPATH_VAR ${SHLIBPATH_VAR}) + # lit.site.cfg uses the config-time build mode + set(LLVM_BUILD_MODE "${LLVM_BUILD_MODE}") + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg @ONLY) + + # Unit/lit.site.cfg substitutes the runtime build_mode + set(LLVM_BUILD_MODE "%(build_mode)s") + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg From raghesh.a at gmail.com Wed Jun 22 02:25:12 2011 From: raghesh.a at gmail.com (raghesh) Date: Wed, 22 Jun 2011 12:55:12 +0530 Subject: [llvm-commits] [polly] r133354 - /polly/trunk/www/documentation/memaccess.html In-Reply-To: <4E012B54.3090403@grosser.es> References: <20110618171716.444342A6C12C@llvm.org> <4E012B54.3090403@grosser.es> Message-ID: Thanks a lot for the comments. In fact I didn't even look inside the html source. That was a big mistake. I created it using iceape composer. I will address these comments soon. Regards, On Wed, Jun 22, 2011 at 5:07 AM, Tobias Grosser wrote: > On 06/18/2011 02:17 PM, Raghesh Aloor wrote: >> >> Author: raghesh >> Date: Sat Jun 18 12:17:16 2011 >> New Revision: 133354 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=133354&view=rev >> Log: >> www: Adding webpage to track memory access transformation > > Hi Raghesh, > > thanks for your work. I still have some comments: > > You forgot to add the disclaimer that this is a work in progress project. > Furthermore, the HTML you used is pretty noisy (details inline). The next > time we should review it before committing. > >> Added: >> ? ? polly/trunk/www/documentation/memaccess.html >> >> Added: polly/trunk/www/documentation/memaccess.html >> URL: >> http://llvm.org/viewvc/llvm-project/polly/trunk/www/documentation/memaccess.html?rev=133354&view=auto >> >> ============================================================================== >> --- polly/trunk/www/documentation/memaccess.html (added) >> +++ polly/trunk/www/documentation/memaccess.html Sat Jun 18 12:17:16 2011 >> @@ -0,0 +1,143 @@ >> + >> + >> + >> +> + http-equiv="Content-Type"> >> +memaccess.html > > Can you use a title like 'Polly - Memory access optimizations' > You should include menu.css and content.css > > I propose to just use the header from documention/passes.html as a template. > (This is true for most of the comments I give) > > > ? ? ? ? ?"http://www.w3.org/TR/html4/strict.dtd"> > > > > ? > ?Polly - The available LLVM passes > ? > ? > > >> + >> + > > You miss the line to include the menu. > > >> +
Support > > Just create a large div with id="content" that includes the whole content of > this page. > >> +for >> +memory access >> +transformations in Polly> + style="font-weight: bold;">
> > Use

for the header. All the other tags are just noise and disallow a > consistent design. > >> +
> > Useless noise. > >> +
> > This does not seem to be needed. > >> + > > Useless noise. > > >> +This project adds >> +memory access transformations to Polly. In many cases
> >
Not needed. > >> +changing the memory access pattern yields to better data >> +locality or removes
> >
not needed. > >> +dependences that would otherwise block >> +transformations. They may also
> > ? ? ? ? ? ? ? ? ?. Memory access transformations may also ... > >
not needed > >> +allow LLVM to use registers to store >> +certain values.
> >
not needed > >> +
>> +
> >
not needed. > >> +An examples which uses this feature is given below
> > This seems to be a new paragraph. Put it in a

to get the newlines. > >> +

>> +

> > I do not see a reason for this
> >> +Consider the following loop >> +
    >> +
      >> +
    >> +
> > Useless noise. > >> +
> > Just use
 to format the code.
>
>> + for
>> +(i = 0; i< 8; i++)
>> +sum += A[i];
> + style="font-style: italic;"> > > All this formatting and
not needed. > >> +
>> +
>> +With support for memory access transformation this loop can be >> executed
>> +in parallel. It can be >> +transformed to > >> +
>> >> +
>> +
> > Useless noise. > >> +
> >
not needed. > >> +<create >> >> +and >> +initialize an array 'tmp' >> +with size 4>
>> +for (i = 0; i< 8; i++) >> {
>> +tmp[i % 4] += A[i];
>> +}> + style="font-style: italic;">
>> +sum = tmp[0] + tmp[1] + tmp[2] >> ++ tmp[3];
> > All formatting not needed. Just use a big
 block.
>
>> +
>> +
>> +With the help of some optimizer (like >> +PluTo) the following code can be
> >
not needed. > > "With the help of optimizers like PluTo the following > >> +generated, where the outer loop is >> +parallel. >> +

parfor (ii = >> +0; ii< 4; ii++) {
>> +   tmp[ii] = 0;
>> +    for (i = ii * 2; i< (ii+1) * 2; i++)
>> +      tmp[ii] += A[i];

>> +

> + style="font-weight: normal;">}
>> +sum = tmp[0] + tmp[1] + tmp[2] + >> +tmp[3];
>> +

> > Useless style noise. Just use
>
>> +

TODO
>> +

> > Do not use

here. Just use

> >> +

Step >> 1
>> +

> > Just use

> >> +Polly exports its polyhedral description in a JSCoP file. Define how >> +memory > >> +
>> >> +
> > Useless noise.
not needed. > >> +layout transformations are going to be expressed in Polly and >> +in >> +the JSCOP file.
> >> +A simple example is given below.
>> +
>> +Consider the following loop.
>> +
> >
not needed. Use

to mark a paragraph. > >> +

for >> +(i >> += 0; i< 12; i++)
>> +     A[i] = >> 0;
> + style="font-style: italic;"> >> +
> > Useless style noise. Just use
.
>
>> +
>> +In the JSCOP file the memory is represented as follows.
>> +
>> +
   >> +"accesses": >> +[{
>> +           >> +"kind": >> +"write",
>> +           >> +"relation": >> +"{ >> +Stmt[i] ->> + style="font-style: italic; font-weight: bold;">A> + style="font-style: italic;">[i] >> +}"
>> +    >> }]
> + style="font-style: italic;"> >> +
> > Useless style noise and  . Just use
>
>> +
>> +Suppose >> +we want to perform a transformation such that the following
>> +code is generated
>> +
> > Get rid of
and use a single

. > >> +

for >> +(i >> += 0; i< 12; i++)
>> + >> +     A[0] = i;
>> +
> > Style noise. Use
.
>
>> +
>> +The corresponding JSCOP file represenation would be
>> +
>> +
    >> +"accesses": >> +[{
>> +           >> +"kind": >> +"read",
>> +           > > Style and   noise. Just use
.
>
>> +"relation":
>> +"{
>> +Stmt[i] ->> + style="font-style: italic; font-weight: bold;">A
> Please don't use any inline style specifiers. If you want to highlight
> something use  or . For anything else define a new style in the .css
> files after verifying something similar is not available.
>
>> + style="font-style: italic;">[0]
>> +}"
>> +    }]
> + style="font-style: italic;"> >> +
> > Style noise. > >> +
>> +We need to detect this access function change.
>> +

>> + > > Is this needed for anything? > >> + >> + > > Again, thanks for your work > Tobi > -- Raghesh From renato.golin at arm.com Wed Jun 22 03:26:34 2011 From: renato.golin at arm.com (Renato Golin) Date: Wed, 22 Jun 2011 09:26:34 +0100 Subject: [llvm-commits] patch: fix emission of npot vectors which need trailing padding In-Reply-To: References: Message-ID: On 22 June 2011 00:19, Nick Lewycky wrote: > Hi Renato! Sorry, but I don't understand your reply at all. I think you did, and answered my question at the same time. ;) > There's nothing ARM-specific about this change, which is why it belongs in > generic CodeGen and shouldn't be in the ARMAsmPrinter.?It just so happens > that <3 x float> on ARM provides a counter-example that would require this > padding or trigger this assertion. I was fooled by your comment on ARM's vector size and thought your patch was in the wrong place. As you say (and Eli has shown), this is not platform specific, so the patch is good. Sorry about the confusion. cheers, --renato From jay.foad at gmail.com Wed Jun 22 03:50:07 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 22 Jun 2011 08:50:07 -0000 Subject: [llvm-commits] [llvm] r133611 - in /llvm/trunk: include/llvm/ADT/ArrayRef.h include/llvm/InlineAsm.h lib/VMCore/ConstantsContext.h lib/VMCore/LLVMContextImpl.h Message-ID: <20110622085007.1A4BD2A6C12C@llvm.org> Author: foad Date: Wed Jun 22 03:50:06 2011 New Revision: 133611 URL: http://llvm.org/viewvc/llvm-project?rev=133611&view=rev Log: Extend ConstantUniqueMap with a new template parameter ValRefType, representing a constant reference to ValType. Normally this is just "const ValType &", but when ValType is a std::vector we want to use ArrayRef as the reference type. Modified: llvm/trunk/include/llvm/ADT/ArrayRef.h llvm/trunk/include/llvm/InlineAsm.h llvm/trunk/lib/VMCore/ConstantsContext.h llvm/trunk/lib/VMCore/LLVMContextImpl.h Modified: llvm/trunk/include/llvm/ADT/ArrayRef.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ArrayRef.h?rev=133611&r1=133610&r2=133611&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ArrayRef.h (original) +++ llvm/trunk/include/llvm/ADT/ArrayRef.h Wed Jun 22 03:50:06 2011 @@ -125,6 +125,13 @@ } /// @} + /// @name Conversion operators + /// @{ + operator std::vector() const { + return std::vector(Data, Data+Length); + } + + /// @} }; // ArrayRefs can be treated like a POD type. Modified: llvm/trunk/include/llvm/InlineAsm.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InlineAsm.h?rev=133611&r1=133610&r2=133611&view=diff ============================================================================== --- llvm/trunk/include/llvm/InlineAsm.h (original) +++ llvm/trunk/include/llvm/InlineAsm.h Wed Jun 22 03:50:06 2011 @@ -25,15 +25,16 @@ class FunctionType; class Module; struct InlineAsmKeyType; -template +template class ConstantUniqueMap; template struct ConstantCreator; class InlineAsm : public Value { friend struct ConstantCreator; - friend class ConstantUniqueMap; + friend class ConstantUniqueMap; InlineAsm(const InlineAsm &); // do not implement void operator=(const InlineAsm&); // do not implement Modified: llvm/trunk/lib/VMCore/ConstantsContext.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantsContext.h?rev=133611&r1=133610&r2=133611&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantsContext.h (original) +++ llvm/trunk/lib/VMCore/ConstantsContext.h Wed Jun 22 03:50:06 2011 @@ -568,7 +568,7 @@ } }; -template class ConstantUniqueMap : public AbstractTypeUser { public: @@ -656,7 +656,7 @@ } } - ConstantClass* Create(const TypeClass *Ty, const ValType &V, + ConstantClass* Create(const TypeClass *Ty, ValRefType V, typename MapTy::iterator I) { ConstantClass* Result = ConstantCreator::create(Ty, V); @@ -675,7 +675,7 @@ /// getOrCreate - Return the specified constant from the map, creating it if /// necessary. - ConstantClass *getOrCreate(const TypeClass *Ty, const ValType &V) { + ConstantClass *getOrCreate(const TypeClass *Ty, ValRefType V) { MapKey Lookup(Ty, V); ConstantClass* Result = 0; Modified: llvm/trunk/lib/VMCore/LLVMContextImpl.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/LLVMContextImpl.h?rev=133611&r1=133610&r2=133611&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/LLVMContextImpl.h (original) +++ llvm/trunk/lib/VMCore/LLVMContextImpl.h Wed Jun 22 03:50:06 2011 @@ -25,6 +25,7 @@ #include "llvm/Support/ValueHandle.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallPtrSet.h" @@ -138,27 +139,30 @@ // on Context destruction. SmallPtrSet NonUniquedMDNodes; - ConstantUniqueMap AggZeroConstants; + ConstantUniqueMap AggZeroConstants; - typedef ConstantUniqueMap, ArrayType, - ConstantArray, true /*largekey*/> ArrayConstantsTy; + typedef ConstantUniqueMap, ArrayRef, + ArrayType, ConstantArray, true /*largekey*/> ArrayConstantsTy; ArrayConstantsTy ArrayConstants; - typedef ConstantUniqueMap, StructType, - ConstantStruct, true /*largekey*/> StructConstantsTy; + typedef ConstantUniqueMap, ArrayRef, + StructType, ConstantStruct, true /*largekey*/> StructConstantsTy; StructConstantsTy StructConstants; - typedef ConstantUniqueMap, VectorType, - ConstantVector> VectorConstantsTy; + typedef ConstantUniqueMap, ArrayRef, + VectorType, ConstantVector> VectorConstantsTy; VectorConstantsTy VectorConstants; - ConstantUniqueMap NullPtrConstants; - ConstantUniqueMap UndefValueConstants; + ConstantUniqueMap + NullPtrConstants; + ConstantUniqueMap UndefValueConstants; DenseMap , BlockAddress*> BlockAddresses; - ConstantUniqueMap ExprConstants; + ConstantUniqueMap + ExprConstants; - ConstantUniqueMap InlineAsms; + ConstantUniqueMap InlineAsms; ConstantInt *TheTrueVal; ConstantInt *TheFalseVal; From jay.foad at gmail.com Wed Jun 22 03:56:57 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 22 Jun 2011 09:56:57 +0100 Subject: [llvm-commits] [llvm] r133412 - in /llvm/trunk: include/llvm/Constants.h lib/Analysis/ConstantFolding.cpp lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/CodeGen/ShadowStackGC.cpp lib/Transforms/IPO/GlobalOpt.cpp lib/Transform In-Reply-To: <87A7DCD7-1A1E-41F9-83EF-B675446B2830@nondot.org> References: <6ACAF514-D83B-46F3-BBD9-13F295FB1FA2@nondot.org> <87A7DCD7-1A1E-41F9-83EF-B675446B2830@nondot.org> Message-ID: On 21 June 2011 19:40, Chris Lattner wrote: > > On Jun 21, 2011, at 12:22 AM, Jay Foad wrote: > >>>> Patch 1 extends ConstantUniqueMap with a new template parameter >>>> ValRefType, representing a const reference to ValType. Normally this >>>> would just be const ValType&, but when ValType is a std::vector, we >>>> want to use ArrayRef as the reference type. >> >>> Wow, looks great to me Jay >> >> Just to double check, are you OK with me adding the conversion operator >> >> ?ArrayRef::operator std::vector() const; > > I'm ok with it if there is no no other way There's always another way; but I don't know what it is, so I've committed my patch as-is. Thanks, Jay. From jay.foad at gmail.com Wed Jun 22 03:55:11 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 22 Jun 2011 08:55:11 -0000 Subject: [llvm-commits] [llvm] r133612 - /llvm/trunk/lib/VMCore/Constants.cpp Message-ID: <20110622085512.0ABBE2A6C12C@llvm.org> Author: foad Date: Wed Jun 22 03:55:11 2011 New Revision: 133612 URL: http://llvm.org/viewvc/llvm-project?rev=133612&view=rev Log: Eliminate a temporary std::vector in ConstantStruct::get(). Modified: llvm/trunk/lib/VMCore/Constants.cpp Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=133612&r1=133611&r2=133612&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Wed Jun 22 03:55:11 2011 @@ -666,10 +666,8 @@ // Create a ConstantAggregateZero value if all elements are zeros. for (unsigned i = 0, e = V.size(); i != e; ++i) - if (!V[i]->isNullValue()) { - // FIXME: Eliminate temporary std::vector here! - return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V.vec()); - } + if (!V[i]->isNullValue()) + return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V); return ConstantAggregateZero::get(ST); } From jay.foad at gmail.com Wed Jun 22 04:10:20 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 22 Jun 2011 09:10:20 -0000 Subject: [llvm-commits] [llvm] r133614 - in /llvm/trunk: include/llvm/Constants.h lib/VMCore/ConstantFold.cpp lib/VMCore/Constants.cpp Message-ID: <20110622091020.1BDAE2A6C12C@llvm.org> Author: foad Date: Wed Jun 22 04:10:19 2011 New Revision: 133614 URL: http://llvm.org/viewvc/llvm-project?rev=133614&view=rev Log: Make ConstantVector::get() always take an ArrayRef, never a std::vector. Modified: llvm/trunk/include/llvm/Constants.h llvm/trunk/lib/VMCore/ConstantFold.cpp llvm/trunk/lib/VMCore/Constants.cpp Modified: llvm/trunk/include/llvm/Constants.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=133614&r1=133613&r2=133614&view=diff ============================================================================== --- llvm/trunk/include/llvm/Constants.h (original) +++ llvm/trunk/include/llvm/Constants.h Wed Jun 22 04:10:19 2011 @@ -491,8 +491,6 @@ public: // ConstantVector accessors static Constant *get(ArrayRef V); - // FIXME: Eliminate this constructor form. - static Constant *get(const VectorType *T, const std::vector &V); /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=133614&r1=133613&r2=133614&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantFold.cpp (original) +++ llvm/trunk/lib/VMCore/ConstantFold.cpp Wed Jun 22 04:10:19 2011 @@ -559,7 +559,7 @@ for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) res.push_back(ConstantExpr::getCast(opc, CV->getOperand(i), DstEltTy)); - return ConstantVector::get(DestVecTy, res); + return ConstantVector::get(res); } // We actually have to do a cast now. Perform the cast according to the Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=133614&r1=133613&r2=133614&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Wed Jun 22 04:10:19 2011 @@ -698,9 +698,9 @@ } // ConstantVector accessors. -Constant *ConstantVector::get(const VectorType *T, - const std::vector &V) { +Constant *ConstantVector::get(ArrayRef V) { assert(!V.empty() && "Vectors can't be empty"); + const VectorType *T = VectorType::get(V.front()->getType(), V.size()); LLVMContextImpl *pImpl = T->getContext().pImpl; // If this is an all-undef or all-zero vector, return a @@ -725,12 +725,6 @@ return pImpl->VectorConstants.getOrCreate(T, V); } -Constant *ConstantVector::get(ArrayRef V) { - // FIXME: make this the primary ctor method. - assert(!V.empty() && "Vectors cannot be empty"); - return get(VectorType::get(V.front()->getType(), V.size()), V.vec()); -} - // Utility function for determining if a ConstantExpr is a CastOp or not. This // can't be inline because we don't want to #include Instruction.h into // Constant.h @@ -2118,7 +2112,7 @@ Values.push_back(Val); } - Constant *Replacement = get(cast(getRawType()), Values); + Constant *Replacement = get(Values); assert(Replacement != this && "I didn't contain From!"); // Everyone using this now uses the replacement. From jay.foad at gmail.com Wed Jun 22 04:24:39 2011 From: jay.foad at gmail.com (Jay Foad) Date: Wed, 22 Jun 2011 09:24:39 -0000 Subject: [llvm-commits] [llvm] r133615 - in /llvm/trunk: include/llvm/Constants.h lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/ShadowStackGC.cpp lib/Transforms/Instrumentation/GCOVProfiling.cpp lib/VMCore/Constants.cpp lib/VMCore/Core.cpp Message-ID: <20110622092439.EE2DD2A6C124@llvm.org> Author: foad Date: Wed Jun 22 04:24:39 2011 New Revision: 133615 URL: http://llvm.org/viewvc/llvm-project?rev=133615&view=rev Log: Replace the existing forms of ConstantArray::get() with a single form that takes an ArrayRef. Modified: llvm/trunk/include/llvm/Constants.h llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/ShadowStackGC.cpp llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp llvm/trunk/lib/VMCore/Constants.cpp llvm/trunk/lib/VMCore/Core.cpp Modified: llvm/trunk/include/llvm/Constants.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=133615&r1=133614&r2=133615&view=diff ============================================================================== --- llvm/trunk/include/llvm/Constants.h (original) +++ llvm/trunk/include/llvm/Constants.h Wed Jun 22 04:24:39 2011 @@ -350,9 +350,7 @@ ConstantArray(const ArrayType *T, const std::vector &Val); public: // ConstantArray accessors - static Constant *get(const ArrayType *T, const std::vector &V); - static Constant *get(const ArrayType *T, Constant *const *Vals, - unsigned NumVals); + static Constant *get(const ArrayType *T, ArrayRef V); /// This method constructs a ConstantArray and initializes it with a text /// string. The default behavior (AddNull==true) causes a null terminator to Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=133615&r1=133614&r2=133615&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Wed Jun 22 04:24:39 2011 @@ -2062,7 +2062,7 @@ " is not of type '" + getTypeString(Elts[0]->getType())); } - ID.ConstantVal = ConstantArray::get(ATy, Elts.data(), Elts.size()); + ID.ConstantVal = ConstantArray::get(ATy, Elts); ID.Kind = ValID::t_Constant; return false; } Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=133615&r1=133614&r2=133615&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Wed Jun 22 04:24:39 2011 @@ -292,7 +292,7 @@ // Make the new constant. Constant *NewC; if (ConstantArray *UserCA = dyn_cast(UserC)) { - NewC = ConstantArray::get(UserCA->getType(), &NewOps[0], NewOps.size()); + NewC = ConstantArray::get(UserCA->getType(), NewOps); } else if (ConstantStruct *UserCS = dyn_cast(UserC)) { NewC = ConstantStruct::get(UserCS->getType(), NewOps); } else if (isa(UserC)) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=133615&r1=133614&r2=133615&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Jun 22 04:24:39 2011 @@ -7470,7 +7470,7 @@ const TargetData &TD = *TLI.getTargetData(); // Create a ConstantArray of the two constants. - Constant *CA = ConstantArray::get(ArrayType::get(FPTy, 2), Elts, 2); + Constant *CA = ConstantArray::get(ArrayType::get(FPTy, 2), Elts); SDValue CPIdx = DAG.getConstantPool(CA, TLI.getPointerTy(), TD.getPrefTypeAlignment(FPTy)); unsigned Alignment = cast(CPIdx)->getAlignment(); Modified: llvm/trunk/lib/CodeGen/ShadowStackGC.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ShadowStackGC.cpp?rev=133615&r1=133614&r2=133615&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ShadowStackGC.cpp (original) +++ llvm/trunk/lib/CodeGen/ShadowStackGC.cpp Wed Jun 22 04:24:39 2011 @@ -201,6 +201,7 @@ NumMeta = I + 1; Metadata.push_back(ConstantExpr::getBitCast(C, VoidPtr)); } + Metadata.resize(NumMeta); const Type *Int32Ty = Type::getInt32Ty(F.getContext()); @@ -211,8 +212,7 @@ Constant *DescriptorElts[] = { ConstantStruct::get(StructType::get(Int32Ty, Int32Ty, NULL), BaseElts), - ConstantArray::get(ArrayType::get(VoidPtr, NumMeta), - Metadata.begin(), NumMeta) + ConstantArray::get(ArrayType::get(VoidPtr, NumMeta), Metadata) }; Constant *FrameMap = Modified: llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp?rev=133615&r1=133614&r2=133615&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp (original) +++ llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp Wed Jun 22 04:24:39 2011 @@ -561,11 +561,11 @@ Edge += Successors; } + ArrayRef V(&EdgeTable[0], Succs.size() * Preds.size()); GlobalVariable *EdgeTableGV = new GlobalVariable( *M, EdgeTableTy, true, GlobalValue::InternalLinkage, - ConstantArray::get(EdgeTableTy, - &EdgeTable[0], Succs.size() * Preds.size()), + ConstantArray::get(EdgeTableTy, V), "__llvm_gcda_edge_table"); EdgeTableGV->setUnnamedAddr(true); return EdgeTableGV; Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=133615&r1=133614&r2=133615&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Wed Jun 22 04:24:39 2011 @@ -571,8 +571,7 @@ } } -Constant *ConstantArray::get(const ArrayType *Ty, - const std::vector &V) { +Constant *ConstantArray::get(const ArrayType *Ty, ArrayRef V) { for (unsigned i = 0, e = V.size(); i != e; ++i) { assert(V[i]->getType() == Ty->getElementType() && "Wrong type in array element initializer"); @@ -592,13 +591,6 @@ return ConstantAggregateZero::get(Ty); } - -Constant *ConstantArray::get(const ArrayType* T, Constant *const* Vals, - unsigned NumVals) { - // FIXME: make this the primary ctor method. - return get(T, std::vector(Vals, Vals+NumVals)); -} - /// ConstantArray::get(const string&) - Return an array that is initialized to /// contain the specified string. If length is zero then a null terminator is /// added to the specified string so that it may be used in a natural way. Modified: llvm/trunk/lib/VMCore/Core.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=133615&r1=133614&r2=133615&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Core.cpp (original) +++ llvm/trunk/lib/VMCore/Core.cpp Wed Jun 22 04:24:39 2011 @@ -625,9 +625,8 @@ } LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, LLVMValueRef *ConstantVals, unsigned Length) { - return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), - unwrap(ConstantVals, Length), - Length)); + ArrayRef V(unwrap(ConstantVals, Length), Length); + return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), V)); } LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed) { From nobled at dreamwidth.org Wed Jun 22 07:18:46 2011 From: nobled at dreamwidth.org (nobled) Date: Wed, 22 Jun 2011 08:18:46 -0400 Subject: [llvm-commits] [PATCHES] don't include config.h in public headers Message-ID: llvm/Config/config.h contains a lot of standard macros like PACKAGE_VERSION that don't make sense to expose to clients, who will probably have their own private config.h with its own definition of PACKAGE_VERSION et al. Right now, Klee runs into this and seems to be working around it with #undef[1]. It's not actually needed in most cases, and these four patches remove all the uses in llvm and clang headers. Unless it's also being included in dragonegg or lldb sources or something, the file can probably be excluded from `make install` entirely after this (but I'm not sure how to do that). Okay to commit? [1] http://llvm.org/viewvc/llvm-project/klee/trunk/lib/Core/ExternalDispatcher.cpp?r1=98467&r2=98466&pathrev=98467 -------------- next part -------------- From 96493bc1061dd38b05e63fcf99808de7ed7ae429 Mon Sep 17 00:00:00 2001 From: nobled Date: Tue, 21 Jun 2011 07:25:37 +0000 Subject: [PATCH 1/3] Only use llvm-config.h in public headers llvm-config.h defines most of the important macros "so that they can be in exported headers and won't override package specific directives." e.g., PACKAGE_NAME. Endian.h wasn't using any macros at all though, so just delete the include there instead. --- include/llvm/Support/Endian.h | 1 - include/llvm/Support/system_error.h | 2 +- 2 files changed, 1 insertions(+), 2 deletions(-) diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h index f62eab0..af1b506 100644 --- a/include/llvm/Support/Endian.h +++ b/include/llvm/Support/Endian.h @@ -14,7 +14,6 @@ #ifndef LLVM_SUPPORT_ENDIAN_H #define LLVM_SUPPORT_ENDIAN_H -#include "llvm/Config/config.h" #include "llvm/Support/Host.h" #include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/type_traits.h" diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h index b77030d..2c15b69 100644 --- a/include/llvm/Support/system_error.h +++ b/include/llvm/Support/system_error.h @@ -222,7 +222,7 @@ template <> struct hash; */ -#include "llvm/Config/config.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Support/type_traits.h" #include #include -- 1.7.0.4 -------------- next part -------------- From bbd1d7666736afe19b3b0c967666fab810e79aa7 Mon Sep 17 00:00:00 2001 From: nobled Date: Tue, 21 Jun 2011 13:15:51 +0000 Subject: [PATCH] avoid using config.h in public headers This is the only usage in clang's headers, and it's for a define that only exists on CMake builds for the sake of the MSVC compiler, so just use an ifdef instead. Also add an include for config.h in a file that actually needs it, but was picking it up by accident indirectly. --- include/clang/Basic/FileManager.h | 5 ++++- lib/Frontend/CompilerInstance.cpp | 1 + 2 files changed, 5 insertions(+), 1 deletions(-) diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h index 2ca344d..1324533 100644 --- a/include/clang/Basic/FileManager.h +++ b/include/clang/Basic/FileManager.h @@ -21,10 +21,13 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/Allocator.h" -#include "llvm/Config/config.h" // for mode_t // FIXME: Enhance libsystem to support inode and other fields in stat. #include +#ifdef _MSC_VER +typedef unsigned short mode_t; +#endif + struct stat; namespace llvm { diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 38fcfe3..cb91c89 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -38,6 +38,7 @@ #include "llvm/Support/Program.h" #include "llvm/Support/Signals.h" #include "llvm/Support/system_error.h" +#include "llvm/Config/config.h" using namespace clang; CompilerInstance::CompilerInstance() -- 1.7.0.4 -------------- next part -------------- From fbc6303d169f7b50b4340c9380af66e00210ac0c Mon Sep 17 00:00:00 2001 From: nobled Date: Tue, 21 Jun 2011 13:21:11 +0000 Subject: [PATCH 2/3] remove CMake mode_t define It's now replaced with a simple ifdef _MSC_VER in the one place it's needed (clang's FileManager.h header). --- cmake/config-ix.cmake | 1 - include/llvm/Config/config.h.cmake | 3 --- 2 files changed, 0 insertions(+), 4 deletions(-) diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index c1b22d4..1a2cba5 100755 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -349,7 +349,6 @@ endif( MINGW ) if( MSVC ) set(error_t int) - set(mode_t "unsigned short") set(LTDL_SHLIBPATH_VAR "PATH") set(LTDL_SYSSEARCHPATH "") set(LTDL_DLOPEN_DEPLIBS 1) diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index 755daa6..d07e0b2 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -686,9 +686,6 @@ `char[]'. */ #undef YYTEXT_POINTER -/* Define to a type to use for `mode_t' if it is not otherwise available. */ -#cmakedefine mode_t ${mode_t} - /* Define to a function replacing strtoll */ #cmakedefine strtoll ${strtoll} -- 1.7.0.4 -------------- next part -------------- From e28c74fd0a90b02cf541450004e3d16fb3949bbd Mon Sep 17 00:00:00 2001 From: nobled Date: Tue, 21 Jun 2011 07:30:57 +0000 Subject: [PATCH 3/3] make floating-exception header private It has only one user. This eliminates the last include of config.h from the public headers -- it should probably not even be installed at `make install` time now. --- include/llvm/Support/FEnv.h | 56 -------------------------------------- lib/Analysis/ConstantFolding.cpp | 3 +- lib/Analysis/FEnv.h | 56 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 57 deletions(-) delete mode 100644 include/llvm/Support/FEnv.h create mode 100644 lib/Analysis/FEnv.h diff --git a/include/llvm/Support/FEnv.h b/include/llvm/Support/FEnv.h deleted file mode 100644 index f6f4333..0000000 --- a/include/llvm/Support/FEnv.h +++ /dev/null @@ -1,56 +0,0 @@ -//===- llvm/Support/FEnv.h - Host floating-point exceptions ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides an operating system independent interface to -// floating-point exception interfaces. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SYSTEM_FENV_H -#define LLVM_SYSTEM_FENV_H - -#include "llvm/Config/config.h" -#include -#ifdef HAVE_FENV_H -#include -#endif - -// FIXME: Clang's #include handling apparently doesn't work for libstdc++'s -// fenv.h; see PR6907 for details. -#if defined(__clang__) && defined(_GLIBCXX_FENV_H) -#undef HAVE_FENV_H -#endif - -namespace llvm { -namespace sys { - -/// llvm_fenv_clearexcept - Clear the floating-point exception state. -static inline void llvm_fenv_clearexcept() { -#ifdef HAVE_FENV_H - feclearexcept(FE_ALL_EXCEPT); -#endif - errno = 0; -} - -/// llvm_fenv_testexcept - Test if a floating-point exception was raised. -static inline bool llvm_fenv_testexcept() { - int errno_val = errno; - if (errno_val == ERANGE || errno_val == EDOM) - return true; -#ifdef HAVE_FENV_H - if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT)) - return true; -#endif - return false; -} - -} // End sys namespace -} // End llvm namespace - -#endif diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index b5fafd6..b64f3b9 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -31,9 +31,10 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/MathExtras.h" -#include "llvm/Support/FEnv.h" #include #include + +#include "FEnv.h" using namespace llvm; //===----------------------------------------------------------------------===// diff --git a/lib/Analysis/FEnv.h b/lib/Analysis/FEnv.h new file mode 100644 index 0000000..f6f4333 --- /dev/null +++ b/lib/Analysis/FEnv.h @@ -0,0 +1,56 @@ +//===- llvm/Support/FEnv.h - Host floating-point exceptions ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides an operating system independent interface to +// floating-point exception interfaces. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SYSTEM_FENV_H +#define LLVM_SYSTEM_FENV_H + +#include "llvm/Config/config.h" +#include +#ifdef HAVE_FENV_H +#include +#endif + +// FIXME: Clang's #include handling apparently doesn't work for libstdc++'s +// fenv.h; see PR6907 for details. +#if defined(__clang__) && defined(_GLIBCXX_FENV_H) +#undef HAVE_FENV_H +#endif + +namespace llvm { +namespace sys { + +/// llvm_fenv_clearexcept - Clear the floating-point exception state. +static inline void llvm_fenv_clearexcept() { +#ifdef HAVE_FENV_H + feclearexcept(FE_ALL_EXCEPT); +#endif + errno = 0; +} + +/// llvm_fenv_testexcept - Test if a floating-point exception was raised. +static inline bool llvm_fenv_testexcept() { + int errno_val = errno; + if (errno_val == ERANGE || errno_val == EDOM) + return true; +#ifdef HAVE_FENV_H + if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT)) + return true; +#endif + return false; +} + +} // End sys namespace +} // End llvm namespace + +#endif -- 1.7.0.4 From vanboxem.ruben at gmail.com Wed Jun 22 10:28:22 2011 From: vanboxem.ruben at gmail.com (Ruben Van Boxem) Date: Wed, 22 Jun 2011 17:28:22 +0200 Subject: [llvm-commits] [PATCH] Fix build on MinGW Message-ID: Hi, Attached is a patch for MinGW. The first bit selects the correct _mkdir function for all Windows platforms, not just MSVC, which is wrong, and makes the MinGW build fail. The second bit is about this bug: http://llvm.org/bugs/show_bug.cgi?id=8850 The patch only affects MinGW on x86_64, which is localized to exactly where the crash occurs. Please apply these as soon as you have time. Thanks! Ruben -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110622/913af8f3/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: mingw.patch Type: application/octet-stream Size: 1044 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110622/913af8f3/attachment.obj From vanboxem.ruben at gmail.com Wed Jun 22 10:33:52 2011 From: vanboxem.ruben at gmail.com (Ruben Van Boxem) Date: Wed, 22 Jun 2011 17:33:52 +0200 Subject: [llvm-commits] [PATCH] Fix build on MinGW In-Reply-To: References: Message-ID: 2011/6/22 Ruben Van Boxem > > Hi, > > Attached is a patch for MinGW. > > The first bit selects the correct _mkdir function for all Windows platforms, not just MSVC, which is wrong, and makes the MinGW build fail. > > The second bit is about this bug: http://llvm.org/bugs/show_bug.cgi?id=8850 > The patch only affects MinGW on x86_64, which is localized to exactly where the crash occurs. > > Please apply these as soon as you have time. Thanks! > > Ruben I'm terribly sorry, but the second bit was wrong in my first patch. Attached is the correct version. Ruben -------------- next part -------------- A non-text attachment was scrubbed... Name: mingw.patch Type: application/octet-stream Size: 1088 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110622/db5892fc/attachment.obj From stoklund at 2pi.dk Wed Jun 22 10:46:37 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 22 Jun 2011 08:46:37 -0700 Subject: [llvm-commits] [LLVMdev] [PATCH] Get DCE to consider livein PhysRegs to successor basic blocks. In-Reply-To: <4E00EBFF.1050205@playingwithpointers.com> References: <4E004D97.2040707@playingwithpointers.com> <82C2784C-2409-4EFB-A59F-BAB30A22D5E2@2pi.dk> <4E00EBFF.1050205@playingwithpointers.com> Message-ID: <058362BA-2F8A-4DFA-BA69-DFB5418AA685@2pi.dk> On Jun 21, 2011, at 12:07 PM, Sanjoy Das wrote: >> >> Looks good, but keep the comment (sans FIXME). >> > > Revised patch attached. Three nits: - // FIXME: Add live-ins from sucessors to LivePhysRegs. Normally, physregs + // Add live-ins from sucessors to LivePhysRegs. Normally, physregs // are not live across blocks, but some targets (x86) can have flags live // out of a block. + for (MachineBasicBlock::succ_iterator S = MBB->succ_begin(); + S != MBB->succ_end(); S++) { + for (MachineBasicBlock::livein_iterator LI = (*S)->livein_begin(); + LI != (*S)->livein_end(); LI++) { + LivePhysRegs.set(*LI); + } + } 1. Wrap the comment properly. 2. Use the standard LLVM idiom for evaluating the end() methods only once. 3. Don't use {} for single statements. But note that you really shouldn't be depending on this patch for your work. Live physregs prevent code motion and (now) dead code elimination. Virtual registers are always better. /jakob From justin.holewinski at gmail.com Wed Jun 22 11:07:04 2011 From: justin.holewinski at gmail.com (Justin Holewinski) Date: Wed, 22 Jun 2011 16:07:04 -0000 Subject: [llvm-commits] [llvm] r133619 - in /llvm/trunk/lib/Target/PTX: PTXAsmPrinter.cpp PTXInstrInfo.cpp PTXInstrInfo.h PTXRegisterInfo.cpp PTXRegisterInfo.h Message-ID: <20110622160704.127662A6C12C@llvm.org> Author: jholewinski Date: Wed Jun 22 11:07:03 2011 New Revision: 133619 URL: http://llvm.org/viewvc/llvm-project?rev=133619&view=rev Log: PTX: Fix FrameIndex mapping bug Modified: llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp llvm/trunk/lib/Target/PTX/PTXInstrInfo.h llvm/trunk/lib/Target/PTX/PTXRegisterInfo.cpp llvm/trunk/lib/Target/PTX/PTXRegisterInfo.h Modified: llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp?rev=133619&r1=133618&r2=133619&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp Wed Jun 22 11:07:03 2011 @@ -204,15 +204,18 @@ } const MachineFrameInfo* FrameInfo = MF->getFrameInfo(); - DEBUG(dbgs() << "Have " << FrameInfo->getNumObjects() << " frame object(s)\n"); + DEBUG(dbgs() << "Have " << FrameInfo->getNumObjects() + << " frame object(s)\n"); for (unsigned i = 0, e = FrameInfo->getNumObjects(); i != e; ++i) { DEBUG(dbgs() << "Size of object: " << FrameInfo->getObjectSize(i) << "\n"); - std::string def = "\t.reg .b"; - def += utostr(FrameInfo->getObjectSize(i)*8); // Convert to bits - def += " s"; - def += utostr(i); - def += ";"; - OutStreamer.EmitRawText(Twine(def)); + if (FrameInfo->getObjectSize(i) > 0) { + std::string def = "\t.reg .b"; + def += utostr(FrameInfo->getObjectSize(i)*8); // Convert to bits + def += " s"; + def += utostr(i); + def += ";"; + OutStreamer.EmitRawText(Twine(def)); + } } } Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp?rev=133619&r1=133618&r2=133619&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp Wed Jun 22 11:07:03 2011 @@ -291,7 +291,7 @@ // Memory operand folding for spills void PTXInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MII, - unsigned SrcReg, bool isKill, int FrameIdx, + unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const { MachineInstr& MI = *MII; @@ -318,7 +318,7 @@ // Build the store instruction (really a mov) MachineInstrBuilder MIB = BuildMI(MBB, MII, DL, get(OpCode)); - MIB.addImm(FrameIdx); + MIB.addFrameIndex(FrameIdx); MIB.addReg(SrcReg); AddDefaultPredicate(MIB); @@ -354,7 +354,7 @@ // Build the load instruction (really a mov) MachineInstrBuilder MIB = BuildMI(MBB, MII, DL, get(OpCode)); MIB.addReg(DestReg); - MIB.addImm(FrameIdx); + MIB.addFrameIndex(FrameIdx); AddDefaultPredicate(MIB); } Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.h?rev=133619&r1=133618&r2=133619&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.h (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.h Wed Jun 22 11:07:03 2011 @@ -93,7 +93,7 @@ // efficient code anyway. // virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, // MachineInstr* MI, - // const SmallVectorImpl &Ops, + // const SmallVectorImpl &Ops, // int FrameIndex) const; virtual void storeRegToStackSlot(MachineBasicBlock& MBB, Modified: llvm/trunk/lib/Target/PTX/PTXRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXRegisterInfo.cpp?rev=133619&r1=133618&r2=133619&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXRegisterInfo.cpp Wed Jun 22 11:07:03 2011 @@ -13,7 +13,34 @@ #include "PTX.h" #include "PTXRegisterInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; #include "PTXGenRegisterInfo.inc" + + +void PTXRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, + RegScavenger *RS) const { + unsigned Index; + MachineInstr& MI = *II; + + Index = 0; + while (!MI.getOperand(Index).isFI()) { + ++Index; + assert(Index < MI.getNumOperands() && + "Instr does not have a FrameIndex operand!"); + } + + int FrameIndex = MI.getOperand(Index).getIndex(); + + DEBUG(dbgs() << "eliminateFrameIndex: " << MI); + DEBUG(dbgs() << "- SPAdj: " << SPAdj << "\n"); + DEBUG(dbgs() << "- FrameIndex: " << FrameIndex << "\n"); + + // This frame index is post stack slot re-use assignments + MI.getOperand(Index).ChangeToImmediate(FrameIndex); +} Modified: llvm/trunk/lib/Target/PTX/PTXRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXRegisterInfo.h?rev=133619&r1=133618&r2=133619&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXRegisterInfo.h (original) +++ llvm/trunk/lib/Target/PTX/PTXRegisterInfo.h Wed Jun 22 11:07:03 2011 @@ -38,11 +38,9 @@ return Reserved; // reserve no regs } - virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, + virtual void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, - RegScavenger *RS = NULL) const { - llvm_unreachable("PTX does not support general function call"); - } + RegScavenger *RS = NULL) const; virtual unsigned getFrameRegister(const MachineFunction &MF) const { llvm_unreachable("PTX does not have a frame register"); From dan at dneg.com Wed Jun 22 04:04:31 2011 From: dan at dneg.com (Dan Bailey) Date: Wed, 22 Jun 2011 09:04:31 -0000 Subject: [llvm-commits] [llvm] r133613 - /llvm/trunk/lib/Target/PTX/PTX.td Message-ID: <20110622090431.18F192A6C12C@llvm.org> Author: drb Date: Wed Jun 22 04:04:30 2011 New Revision: 133613 URL: http://llvm.org/viewvc/llvm-project?rev=133613&view=rev Log: Test Commit. Modified: llvm/trunk/lib/Target/PTX/PTX.td Modified: llvm/trunk/lib/Target/PTX/PTX.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTX.td?rev=133613&r1=133612&r2=133613&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTX.td (original) +++ llvm/trunk/lib/Target/PTX/PTX.td Wed Jun 22 04:04:30 2011 @@ -16,7 +16,7 @@ include "llvm/Target/Target.td" //===----------------------------------------------------------------------===// -// Subtarget Features. +// Subtarget Features //===----------------------------------------------------------------------===// //===- Architectural Features ---------------------------------------------===// @@ -57,7 +57,7 @@ [FeatureSM13]>; //===----------------------------------------------------------------------===// -// PTX supported processors. +// PTX supported processors //===----------------------------------------------------------------------===// class Proc Features> From echristo at apple.com Wed Jun 22 12:53:17 2011 From: echristo at apple.com (Eric Christopher) Date: Wed, 22 Jun 2011 10:53:17 -0700 Subject: [llvm-commits] [PATCHES] don't include config.h in public headers In-Reply-To: References: Message-ID: <752F1885-24B8-4C7C-9324-0E8A06118031@apple.com> On Jun 22, 2011, at 5:18 AM, nobled wrote: > llvm/Config/config.h contains a lot of standard macros like > PACKAGE_VERSION that don't make sense to expose to clients, who will > probably have their own private config.h with its own definition of > PACKAGE_VERSION et al. Right now, Klee runs into this and seems to be > working around it with #undef[1]. > > It's not actually needed in most cases, and these four patches remove > all the uses in llvm and clang headers. Unless it's also being > included in dragonegg or lldb sources or something, the file can > probably be excluded from `make install` entirely after this (but I'm > not sure how to do that). Okay to commit? Looks good to me. Thanks! -eric From echristo at apple.com Wed Jun 22 12:53:33 2011 From: echristo at apple.com (Eric Christopher) Date: Wed, 22 Jun 2011 10:53:33 -0700 Subject: [llvm-commits] [cfe-commits] [PATCHES] don't include config.h in public headers In-Reply-To: References: Message-ID: <3B3A865E-1550-47DB-B3FD-C1FB05734C76@apple.com> On Jun 22, 2011, at 5:18 AM, nobled wrote: > llvm/Config/config.h contains a lot of standard macros like > PACKAGE_VERSION that don't make sense to expose to clients, who will > probably have their own private config.h with its own definition of > PACKAGE_VERSION et al. Right now, Klee runs into this and seems to be > working around it with #undef[1]. > > It's not actually needed in most cases, and these four patches remove > all the uses in llvm and clang headers. Unless it's also being > included in dragonegg or lldb sources or something, the file can > probably be excluded from `make install` entirely after this (but I'm > not sure how to do that). Okay to commit? Looks good to me. Thanks! -eric From echristo at apple.com Wed Jun 22 13:24:27 2011 From: echristo at apple.com (Eric Christopher) Date: Wed, 22 Jun 2011 11:24:27 -0700 Subject: [llvm-commits] [llvm] r133513 - in /llvm/trunk: include/llvm/ include/llvm/Support/ lib/Target/CppBackend/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ In-Reply-To: <20110621103319.B0D332A6C12C@llvm.org> References: <20110621103319.B0D332A6C12C@llvm.org> Message-ID: <5AAC95DA-F372-4AC4-BF66-AF474C061E34@apple.com> On Jun 21, 2011, at 3:33 AM, Jay Foad wrote: > Author: foad > Date: Tue Jun 21 05:33:19 2011 > New Revision: 133513 > > URL: http://llvm.org/viewvc/llvm-project?rev=133513&view=rev > Log: > Reinstate r133435 and r133449 (reverted in r133499) now that the clang > self-hosted build failure has been fixed (r133512). > This is causing some additional warnings: /Developer/usr/local/include/llvm/Instructions.h: In member function 'llvm::BasicBlock* llvm::PHINode::getIncomingBlock(const llvm::Use&) const': /Developer/usr/local/include/llvm/Instructions.h:1909: warning: implicit conversion shortens 64-bit value into a 32-bit value To duplicate just turn on conversion warnings, in particular with llvm-gcc -Wshorten-64-to-32, in a file that includes Instructions.h. Could you get these? Thanks. -eric From nicholas at mxc.ca Wed Jun 22 13:55:03 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 22 Jun 2011 18:55:03 -0000 Subject: [llvm-commits] [llvm] r133631 - in /llvm/trunk: lib/CodeGen/AsmPrinter/AsmPrinter.cpp test/CodeGen/ARM/constants.ll Message-ID: <20110622185503.95D912A6C12C@llvm.org> Author: nicholas Date: Wed Jun 22 13:55:03 2011 New Revision: 133631 URL: http://llvm.org/viewvc/llvm-project?rev=133631&view=rev Log: Emit trailing padding on constant vectors when TargetData says that the vector is larger than the sum of the elements (including per-element padding). Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/trunk/test/CodeGen/ARM/constants.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=133631&r1=133630&r2=133631&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Wed Jun 22 13:55:03 2011 @@ -1516,6 +1516,13 @@ unsigned AddrSpace, AsmPrinter &AP) { for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) EmitGlobalConstantImpl(CV->getOperand(i), AddrSpace, AP); + + const TargetData &TD = *AP.TM.getTargetData(); + unsigned Size = TD.getTypeAllocSize(CV->getType()); + unsigned EmittedSize = TD.getTypeAllocSize(CV->getType()->getElementType()) * + CV->getType()->getNumElements(); + if (unsigned Padding = Size - EmittedSize) + AP.OutStreamer.EmitZeros(Padding, AddrSpace); } static void EmitGlobalConstantStruct(const ConstantStruct *CS, Modified: llvm/trunk/test/CodeGen/ARM/constants.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/constants.ll?rev=133631&r1=133630&r2=133631&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/constants.ll (original) +++ llvm/trunk/test/CodeGen/ARM/constants.ll Wed Jun 22 13:55:03 2011 @@ -44,3 +44,16 @@ r: ret void } + +%t1 = type { <3 x float>, <3 x float> } + + at const1 = global %t1 { <3 x float> zeroinitializer, + <3 x float> }, align 16 +; CHECK: const1 +; CHECK: .zero 16 +; CHECK: float 1.0 +; CHECK: float 2.0 +; CHECK: float 3.0 +; CHECK: .zero 4 From nlewycky at google.com Wed Jun 22 14:01:03 2011 From: nlewycky at google.com (Nick Lewycky) Date: Wed, 22 Jun 2011 12:01:03 -0700 Subject: [llvm-commits] patch: fix emission of npot vectors which need trailing padding In-Reply-To: References: Message-ID: On 22 June 2011 01:26, Renato Golin wrote: > On 22 June 2011 00:19, Nick Lewycky wrote: > > Hi Renato! Sorry, but I don't understand your reply at all. > > I think you did, and answered my question at the same time. ;) > > > > There's nothing ARM-specific about this change, which is why it belongs > in > > generic CodeGen and shouldn't be in the ARMAsmPrinter. It just so happens > > that <3 x float> on ARM provides a counter-example that would require > this > > padding or trigger this assertion. > > I was fooled by your comment on ARM's vector size and thought your > patch was in the wrong place. As you say (and Eli has shown), this is > not platform specific, so the patch is good. > > Sorry about the confusion. > No problem, thanks for the review! Nick -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110622/bd0b7b45/attachment.html From nicholas at mxc.ca Wed Jun 22 14:42:14 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 22 Jun 2011 19:42:14 -0000 Subject: [llvm-commits] [llvm] r133634 - /llvm/trunk/test/CodeGen/ARM/constants.ll Message-ID: <20110622194215.0289D2A6C12C@llvm.org> Author: nicholas Date: Wed Jun 22 14:42:14 2011 New Revision: 133634 URL: http://llvm.org/viewvc/llvm-project?rev=133634&view=rev Log: Needs a triple. Modified: llvm/trunk/test/CodeGen/ARM/constants.ll Modified: llvm/trunk/test/CodeGen/ARM/constants.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/constants.ll?rev=133634&r1=133633&r2=133634&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/constants.ll (original) +++ llvm/trunk/test/CodeGen/ARM/constants.ll Wed Jun 22 14:42:14 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=arm -disable-cgp-branch-opts | FileCheck %s +; RUN: llc < %s -mtriple=armv4t-unknown-linux-gnueabi -disable-cgp-branch-opts | FileCheck %s define i32 @f1() { ; CHECK: f1 From dpatel at apple.com Wed Jun 22 14:52:37 2011 From: dpatel at apple.com (Devang Patel) Date: Wed, 22 Jun 2011 19:52:37 -0000 Subject: [llvm-commits] [llvm] r133636 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <20110622195237.198C72A6C12C@llvm.org> Author: dpatel Date: Wed Jun 22 14:52:36 2011 New Revision: 133636 URL: http://llvm.org/viewvc/llvm-project?rev=133636&view=rev Log: Set debug loc. Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=133636&r1=133635&r2=133636&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Wed Jun 22 14:52:36 2011 @@ -1400,6 +1400,8 @@ // Patch the new value into place. if (Op->hasName()) NewVal->takeName(Op); + if (Instruction *NewValI = dyn_cast(NewVal)) + NewValI->setDebugLoc(User->getDebugLoc()); User->replaceUsesOfWith(Op, NewVal); UI->setOperandValToReplace(NewVal); From grosbach at apple.com Wed Jun 22 15:14:52 2011 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 22 Jun 2011 20:14:52 -0000 Subject: [llvm-commits] [llvm] r133638 - in /llvm/trunk/lib/Target/ARM: ARM.h ARMAsmBackend.cpp ARMMachObjectWriter.cpp CMakeLists.txt Message-ID: <20110622201452.7C55A2A6C12C@llvm.org> Author: grosbach Date: Wed Jun 22 15:14:52 2011 New Revision: 133638 URL: http://llvm.org/viewvc/llvm-project?rev=133638&view=rev Log: Move ARMMachObjectWriter to its own file. Just tidy up a bit. No functional change. Added: llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp Modified: llvm/trunk/lib/Target/ARM/ARM.h llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp llvm/trunk/lib/Target/ARM/CMakeLists.txt Modified: llvm/trunk/lib/Target/ARM/ARM.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARM.h?rev=133638&r1=133637&r2=133638&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARM.h (original) +++ llvm/trunk/lib/Target/ARM/ARM.h Wed Jun 22 15:14:52 2011 @@ -27,6 +27,7 @@ class JITCodeEmitter; class formatted_raw_ostream; class MCCodeEmitter; +class MCObjectWriter; class TargetAsmBackend; class MachineInstr; class ARMAsmPrinter; @@ -58,6 +59,12 @@ void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, ARMAsmPrinter &AP); +/// createARMMachObjectWriter - Construct an ARM Mach-O object writer. +MCObjectWriter *createARMMachObjectWriter(raw_ostream &OS, + bool Is64Bit, + uint32_t CPUType, + uint32_t CPUSubtype); + } // end namespace llvm; #endif Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=133638&r1=133637&r2=133638&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Wed Jun 22 15:14:52 2011 @@ -28,14 +28,6 @@ using namespace llvm; namespace { -class ARMMachObjectWriter : public MCMachObjectTargetWriter { -public: - ARMMachObjectWriter(bool Is64Bit, uint32_t CPUType, - uint32_t CPUSubtype) - : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype, - /*UseAggressiveSymbolFolding=*/true) {} -}; - class ARMELFObjectWriter : public MCELFObjectTargetWriter { public: ARMELFObjectWriter(Triple::OSType OSType) @@ -423,12 +415,9 @@ : ARMAsmBackend(T), Subtype(st) { } MCObjectWriter *createObjectWriter(raw_ostream &OS) const { - return createMachObjectWriter(new ARMMachObjectWriter( - /*Is64Bit=*/false, - object::mach::CTM_ARM, - Subtype), - OS, - /*IsLittleEndian=*/true); + return createARMMachObjectWriter(OS, /*Is64Bit=*/false, + object::mach::CTM_ARM, + Subtype); } void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, Added: llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp?rev=133638&view=auto ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp (added) +++ llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp Wed Jun 22 15:14:52 2011 @@ -0,0 +1,32 @@ +//===-- ARMMachObjectWriter.cpp - ARM Mach Object Writer ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ARM.h" +#include "llvm/MC/MCMachObjectWriter.h" +using namespace llvm; + +namespace { +class ARMMachObjectWriter : public MCMachObjectTargetWriter { +public: + ARMMachObjectWriter(bool Is64Bit, uint32_t CPUType, + uint32_t CPUSubtype) + : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype, + /*UseAggressiveSymbolFolding=*/true) {} +}; +} + +MCObjectWriter *llvm::createARMMachObjectWriter(raw_ostream &OS, + bool Is64Bit, + uint32_t CPUType, + uint32_t CPUSubtype) { + return createMachObjectWriter(new ARMMachObjectWriter(Is64Bit, + CPUType, + CPUSubtype), + OS, /*IsLittleEndian=*/true); +} Modified: llvm/trunk/lib/Target/ARM/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/CMakeLists.txt?rev=133638&r1=133637&r2=133638&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/CMakeLists.txt (original) +++ llvm/trunk/lib/Target/ARM/CMakeLists.txt Wed Jun 22 15:14:52 2011 @@ -34,6 +34,7 @@ ARMISelLowering.cpp ARMInstrInfo.cpp ARMJITInfo.cpp + ARMMachObjectWriter.cpp ARMMCCodeEmitter.cpp ARMMCExpr.cpp ARMLoadStoreOptimizer.cpp From nlewycky at google.com Wed Jun 22 15:40:42 2011 From: nlewycky at google.com (Nick Lewycky) Date: Wed, 22 Jun 2011 13:40:42 -0700 Subject: [llvm-commits] [llvm] r133638 - in /llvm/trunk/lib/Target/ARM: ARM.h ARMAsmBackend.cpp ARMMachObjectWriter.cpp CMakeLists.txt In-Reply-To: <20110622201452.7C55A2A6C12C@llvm.org> References: <20110622201452.7C55A2A6C12C@llvm.org> Message-ID: Hi Jim, ARMMachObjectWriter is missing #include "llvm/Support/DataTypes.h" for uint32_t! llvm[3]: Compiling ARMISelDAGToDAG.cpp for Debug+Asserts build In file included from ARMAsmBackend.cpp:10: ARM.h:65: error: ?uint32_t? has not been declared ARM.h:66: error: ?uint32_t? has not been declared In file included from ARMBaseRegisterInfo.cpp:14: ARM.h:65: error: ?uint32_t? has not been declared ARM.h:66: error: ?uint32_t? has not been declared In file included from ARMExpandPseudoInsts.cpp:18: ARM.h:65: error: ?uint32_t? has not been declared ARM.h:66: error: ?uint32_t? has not been declared In file included from ARMConstantIslandPass.cpp:17: ARM.h:65: error: ?uint32_t? has not been declared ARM.h:66: error: ?uint32_t? has not been declared [...] Nick On 22 June 2011 13:14, Jim Grosbach wrote: > Author: grosbach > Date: Wed Jun 22 15:14:52 2011 > New Revision: 133638 > > URL: http://llvm.org/viewvc/llvm-project?rev=133638&view=rev > Log: > Move ARMMachObjectWriter to its own file. > > Just tidy up a bit. No functional change. > > Added: > llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp > Modified: > llvm/trunk/lib/Target/ARM/ARM.h > llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp > llvm/trunk/lib/Target/ARM/CMakeLists.txt > > Modified: llvm/trunk/lib/Target/ARM/ARM.h > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARM.h?rev=133638&r1=133637&r2=133638&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARM.h (original) > +++ llvm/trunk/lib/Target/ARM/ARM.h Wed Jun 22 15:14:52 2011 > @@ -27,6 +27,7 @@ > class JITCodeEmitter; > class formatted_raw_ostream; > class MCCodeEmitter; > +class MCObjectWriter; > class TargetAsmBackend; > class MachineInstr; > class ARMAsmPrinter; > @@ -58,6 +59,12 @@ > void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, > ARMAsmPrinter &AP); > > +/// createARMMachObjectWriter - Construct an ARM Mach-O object writer. > +MCObjectWriter *createARMMachObjectWriter(raw_ostream &OS, > + bool Is64Bit, > + uint32_t CPUType, > + uint32_t CPUSubtype); > + > } // end namespace llvm; > > #endif > > Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=133638&r1=133637&r2=133638&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Wed Jun 22 15:14:52 2011 > @@ -28,14 +28,6 @@ > using namespace llvm; > > namespace { > -class ARMMachObjectWriter : public MCMachObjectTargetWriter { > -public: > - ARMMachObjectWriter(bool Is64Bit, uint32_t CPUType, > - uint32_t CPUSubtype) > - : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype, > - /*UseAggressiveSymbolFolding=*/true) {} > -}; > - > class ARMELFObjectWriter : public MCELFObjectTargetWriter { > public: > ARMELFObjectWriter(Triple::OSType OSType) > @@ -423,12 +415,9 @@ > : ARMAsmBackend(T), Subtype(st) { } > > MCObjectWriter *createObjectWriter(raw_ostream &OS) const { > - return createMachObjectWriter(new ARMMachObjectWriter( > - /*Is64Bit=*/false, > - object::mach::CTM_ARM, > - Subtype), > - OS, > - /*IsLittleEndian=*/true); > + return createARMMachObjectWriter(OS, /*Is64Bit=*/false, > + object::mach::CTM_ARM, > + Subtype); > } > > void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, > > Added: llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp?rev=133638&view=auto > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp (added) > +++ llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp Wed Jun 22 15:14:52 > 2011 > @@ -0,0 +1,32 @@ > +//===-- ARMMachObjectWriter.cpp - ARM Mach Object Writer > ------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > > +//===----------------------------------------------------------------------===// > + > +#include "ARM.h" > +#include "llvm/MC/MCMachObjectWriter.h" > +using namespace llvm; > + > +namespace { > +class ARMMachObjectWriter : public MCMachObjectTargetWriter { > +public: > + ARMMachObjectWriter(bool Is64Bit, uint32_t CPUType, > + uint32_t CPUSubtype) > + : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype, > + /*UseAggressiveSymbolFolding=*/true) {} > +}; > +} > + > +MCObjectWriter *llvm::createARMMachObjectWriter(raw_ostream &OS, > + bool Is64Bit, > + uint32_t CPUType, > + uint32_t CPUSubtype) { > + return createMachObjectWriter(new ARMMachObjectWriter(Is64Bit, > + CPUType, > + CPUSubtype), > + OS, /*IsLittleEndian=*/true); > +} > > Modified: llvm/trunk/lib/Target/ARM/CMakeLists.txt > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/CMakeLists.txt?rev=133638&r1=133637&r2=133638&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/CMakeLists.txt (original) > +++ llvm/trunk/lib/Target/ARM/CMakeLists.txt Wed Jun 22 15:14:52 2011 > @@ -34,6 +34,7 @@ > ARMISelLowering.cpp > ARMInstrInfo.cpp > ARMJITInfo.cpp > + ARMMachObjectWriter.cpp > ARMMCCodeEmitter.cpp > ARMMCExpr.cpp > ARMLoadStoreOptimizer.cpp > > > _______________________________________________ > 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/20110622/1bef5209/attachment.html From mcrosier at apple.com Wed Jun 22 15:44:25 2011 From: mcrosier at apple.com (Chad Rosier) Date: Wed, 22 Jun 2011 13:44:25 -0700 Subject: [llvm-commits] [llvm] r133607 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp In-Reply-To: <20110622040159.1F7682A6C12C@llvm.org> References: <20110622040159.1F7682A6C12C@llvm.org> Message-ID: <3C3F2F7A-B5FD-4157-91BA-7F0902CF54C6@apple.com> Hi Rafael, I'm seeing a failure in gccTestSuite for gcc.c-torture/compile/pr21356.c (errors below). This is causing one of our internal buildbots to fail. Would you mind taking a look? Regards, Chad Test Run By mcrosier on Wed Jun 22 13:32:56 2011 Native configuration is i386-apple-darwin10 === gcc tests === Schedule of variations: unix Running target unix Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target. Using /usr/share/dejagnu/config/unix.exp as generic interface file for target. Using /Users/mcrosier/clang-gcc-4_2-testsuite/src/config/default.exp as tool-and-target-specific interface file. Running /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/compile.exp ... Executing on host: /Users/mcrosier/llvm-clean/install/bin/clang -O0 -w -fno-show-column -c -o pr21356.o /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/pr21356.c (timeout = 300) spawn /Users/mcrosier/llvm-clean/install/bin/clang -O0 -w -fno-show-column -c -o pr21356.o /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/pr21356.c PASS: gcc.c-torture/compile/pr21356.c -O0 (test for excess errors) Executing on host: /Users/mcrosier/llvm-clean/install/bin/clang -O1 -w -fno-show-column -c -o pr21356.o /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/pr21356.c (timeout = 300) spawn /Users/mcrosier/llvm-clean/install/bin/clang -O1 -w -fno-show-column -c -o pr21356.o /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/pr21356.c fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp7' compiler exited with status 1 output is: fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp7' FAIL: gcc.c-torture/compile/pr21356.c -O1 (test for excess errors) Excess errors: fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp7' Executing on host: /Users/mcrosier/llvm-clean/install/bin/clang -O2 -w -fno-show-column -c -o pr21356.o /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/pr21356.c (timeout = 300) spawn /Users/mcrosier/llvm-clean/install/bin/clang -O2 -w -fno-show-column -c -o pr21356.o /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/pr21356.c fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp7' compiler exited with status 1 output is: fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp7' FAIL: gcc.c-torture/compile/pr21356.c -O2 (test for excess errors) Excess errors: fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp7' Executing on host: /Users/mcrosier/llvm-clean/install/bin/clang -O3 -fomit-frame-pointer -w -fno-show-column -c -o pr21356.o /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/pr21356.c (timeout = 300) spawn /Users/mcrosier/llvm-clean/install/bin/clang -O3 -fomit-frame-pointer -w -fno-show-column -c -o pr21356.o /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/pr21356.c fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp2' compiler exited with status 1 output is: fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp2' FAIL: gcc.c-torture/compile/pr21356.c -O3 -fomit-frame-pointer (test for excess errors) Excess errors: fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp2' Executing on host: /Users/mcrosier/llvm-clean/install/bin/clang -O3 -g -w -fno-show-column -c -o pr21356.o /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/pr21356.c (timeout = 300) spawn /Users/mcrosier/llvm-clean/install/bin/clang -O3 -g -w -fno-show-column -c -o pr21356.o /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/pr21356.c fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp12' compiler exited with status 1 output is: fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp12' FAIL: gcc.c-torture/compile/pr21356.c -O3 -g (test for excess errors) Excess errors: fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp12' Executing on host: /Users/mcrosier/llvm-clean/install/bin/clang -Os -w -fno-show-column -c -o pr21356.o /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/pr21356.c (timeout = 300) spawn /Users/mcrosier/llvm-clean/install/bin/clang -Os -w -fno-show-column -c -o pr21356.o /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/pr21356.c fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp7' compiler exited with status 1 output is: fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp7' FAIL: gcc.c-torture/compile/pr21356.c -Os (test for excess errors) Excess errors: fatal error: error in backend: unsupported relocation of undefined symbol 'Ltmp7' testcase /Users/mcrosier/clang-gcc-4_2-testsuite/src/gcc.c-torture/compile/compile.exp completed in 0 seconds === gcc Summary === # of expected passes 1 # of unexpected failures 5 Executing on host: /Users/mcrosier/llvm-clean/install/bin/clang -v (timeout = 300) spawn /Users/mcrosier/llvm-clean/install/bin/clang -v clang version 3.0 (trunk 133604) Target: x86_64-apple-darwin Thread model: posix /Users/mcrosier/llvm-clean/install/bin/clang version 3.0 (trunk 133604) runtest completed at Wed Jun 22 13:32:59 2011 On Jun 21, 2011, at 9:01 PM, Rafael Espindola wrote: > Author: rafael > Date: Tue Jun 21 23:01:58 2011 > New Revision: 133607 > > URL: http://llvm.org/viewvc/llvm-project?rev=133607&view=rev > Log: > Reenable the optimization added in 133415, but change the definition of a "simple" bb to > be one with only one unconditional branch and no phis. Duplicating the phis in this case > is possible, but requeres liveness analysis or breaking edges. > > Modified: > llvm/trunk/lib/CodeGen/TailDuplication.cpp > > Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=133607&r1=133606&r2=133607&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) > +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Tue Jun 21 23:01:58 2011 > @@ -568,9 +568,9 @@ > TailDuplicatePass::isSimpleBB(MachineBasicBlock *TailBB) { > if (TailBB->succ_size() != 1) > return false; > - MachineBasicBlock::iterator I = TailBB->getFirstNonPHI(); > + MachineBasicBlock::iterator I = TailBB->begin(); > MachineBasicBlock::iterator E = TailBB->end(); > - while (I->isDebugValue() && I != E) > + while (I != E && I->isDebugValue()) > ++I; > if (I == E) > return true; > @@ -712,7 +712,7 @@ > DenseSet UsedByPhi; > getRegsUsedByPHIs(*TailBB, &UsedByPhi); > > - if (0 && isSimpleBB(TailBB)) > + if (isSimpleBB(TailBB)) > return duplicateSimpleBB(TailBB, TDBBs, UsedByPhi, Copies); > > // Iterate through all the unique predecessors and tail-duplicate this > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From grosbach at apple.com Wed Jun 22 15:40:30 2011 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 22 Jun 2011 20:40:30 -0000 Subject: [llvm-commits] [llvm] r133640 - /llvm/trunk/lib/Target/ARM/ARM.h Message-ID: <20110622204030.CCB512A6C12C@llvm.org> Author: grosbach Date: Wed Jun 22 15:40:30 2011 New Revision: 133640 URL: http://llvm.org/viewvc/llvm-project?rev=133640&view=rev Log: Add missing header. Modified: llvm/trunk/lib/Target/ARM/ARM.h Modified: llvm/trunk/lib/Target/ARM/ARM.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARM.h?rev=133640&r1=133639&r2=133640&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARM.h (original) +++ llvm/trunk/lib/Target/ARM/ARM.h Wed Jun 22 15:40:30 2011 @@ -16,6 +16,7 @@ #define TARGET_ARM_H #include "ARMBaseInfo.h" +#include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetMachine.h" #include From grosbach at apple.com Wed Jun 22 15:47:06 2011 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 22 Jun 2011 13:47:06 -0700 Subject: [llvm-commits] [llvm] r133638 - in /llvm/trunk/lib/Target/ARM: ARM.h ARMAsmBackend.cpp ARMMachObjectWriter.cpp CMakeLists.txt In-Reply-To: References: <20110622201452.7C55A2A6C12C@llvm.org> Message-ID: Huh. Must be a difference in underlying headers on my system or something. Sorry for the breakage. Fixed in 133640. -Jim On Jun 22, 2011, at 1:40 PM, Nick Lewycky wrote: > Hi Jim, > > ARMMachObjectWriter is missing #include "llvm/Support/DataTypes.h" for uint32_t! > > llvm[3]: Compiling ARMISelDAGToDAG.cpp for Debug+Asserts build > In file included from ARMAsmBackend.cpp:10: > ARM.h:65: error: ?uint32_t? has not been declared > ARM.h:66: error: ?uint32_t? has not been declared > In file included from ARMBaseRegisterInfo.cpp:14: > ARM.h:65: error: ?uint32_t? has not been declared > ARM.h:66: error: ?uint32_t? has not been declared > In file included from ARMExpandPseudoInsts.cpp:18: > ARM.h:65: error: ?uint32_t? has not been declared > ARM.h:66: error: ?uint32_t? has not been declared > In file included from ARMConstantIslandPass.cpp:17: > ARM.h:65: error: ?uint32_t? has not been declared > ARM.h:66: error: ?uint32_t? has not been declared > [...] > > Nick > > On 22 June 2011 13:14, Jim Grosbach wrote: > Author: grosbach > Date: Wed Jun 22 15:14:52 2011 > New Revision: 133638 > > URL: http://llvm.org/viewvc/llvm-project?rev=133638&view=rev > Log: > Move ARMMachObjectWriter to its own file. > > Just tidy up a bit. No functional change. > > Added: > llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp > Modified: > llvm/trunk/lib/Target/ARM/ARM.h > llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp > llvm/trunk/lib/Target/ARM/CMakeLists.txt > > Modified: llvm/trunk/lib/Target/ARM/ARM.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARM.h?rev=133638&r1=133637&r2=133638&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARM.h (original) > +++ llvm/trunk/lib/Target/ARM/ARM.h Wed Jun 22 15:14:52 2011 > @@ -27,6 +27,7 @@ > class JITCodeEmitter; > class formatted_raw_ostream; > class MCCodeEmitter; > +class MCObjectWriter; > class TargetAsmBackend; > class MachineInstr; > class ARMAsmPrinter; > @@ -58,6 +59,12 @@ > void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, > ARMAsmPrinter &AP); > > +/// createARMMachObjectWriter - Construct an ARM Mach-O object writer. > +MCObjectWriter *createARMMachObjectWriter(raw_ostream &OS, > + bool Is64Bit, > + uint32_t CPUType, > + uint32_t CPUSubtype); > + > } // end namespace llvm; > > #endif > > Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=133638&r1=133637&r2=133638&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Wed Jun 22 15:14:52 2011 > @@ -28,14 +28,6 @@ > using namespace llvm; > > namespace { > -class ARMMachObjectWriter : public MCMachObjectTargetWriter { > -public: > - ARMMachObjectWriter(bool Is64Bit, uint32_t CPUType, > - uint32_t CPUSubtype) > - : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype, > - /*UseAggressiveSymbolFolding=*/true) {} > -}; > - > class ARMELFObjectWriter : public MCELFObjectTargetWriter { > public: > ARMELFObjectWriter(Triple::OSType OSType) > @@ -423,12 +415,9 @@ > : ARMAsmBackend(T), Subtype(st) { } > > MCObjectWriter *createObjectWriter(raw_ostream &OS) const { > - return createMachObjectWriter(new ARMMachObjectWriter( > - /*Is64Bit=*/false, > - object::mach::CTM_ARM, > - Subtype), > - OS, > - /*IsLittleEndian=*/true); > + return createARMMachObjectWriter(OS, /*Is64Bit=*/false, > + object::mach::CTM_ARM, > + Subtype); > } > > void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, > > Added: llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp?rev=133638&view=auto > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp (added) > +++ llvm/trunk/lib/Target/ARM/ARMMachObjectWriter.cpp Wed Jun 22 15:14:52 2011 > @@ -0,0 +1,32 @@ > +//===-- ARMMachObjectWriter.cpp - ARM Mach Object Writer ------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#include "ARM.h" > +#include "llvm/MC/MCMachObjectWriter.h" > +using namespace llvm; > + > +namespace { > +class ARMMachObjectWriter : public MCMachObjectTargetWriter { > +public: > + ARMMachObjectWriter(bool Is64Bit, uint32_t CPUType, > + uint32_t CPUSubtype) > + : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype, > + /*UseAggressiveSymbolFolding=*/true) {} > +}; > +} > + > +MCObjectWriter *llvm::createARMMachObjectWriter(raw_ostream &OS, > + bool Is64Bit, > + uint32_t CPUType, > + uint32_t CPUSubtype) { > + return createMachObjectWriter(new ARMMachObjectWriter(Is64Bit, > + CPUType, > + CPUSubtype), > + OS, /*IsLittleEndian=*/true); > +} > > Modified: llvm/trunk/lib/Target/ARM/CMakeLists.txt > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/CMakeLists.txt?rev=133638&r1=133637&r2=133638&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/CMakeLists.txt (original) > +++ llvm/trunk/lib/Target/ARM/CMakeLists.txt Wed Jun 22 15:14:52 2011 > @@ -34,6 +34,7 @@ > ARMISelLowering.cpp > ARMInstrInfo.cpp > ARMJITInfo.cpp > + ARMMachObjectWriter.cpp > ARMMCCodeEmitter.cpp > ARMMCExpr.cpp > ARMLoadStoreOptimizer.cpp > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From daniel at zuster.org Wed Jun 22 15:41:53 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 22 Jun 2011 20:41:53 -0000 Subject: [llvm-commits] [llvm] r133641 - /llvm/trunk/test/Unit/lit.cfg Message-ID: <20110622204153.802F72A6C12C@llvm.org> Author: ddunbar Date: Wed Jun 22 15:41:53 2011 New Revision: 133641 URL: http://llvm.org/viewvc/llvm-project?rev=133641&view=rev Log: test/Unit: Fix enable shared test to follow check that we have actually loaded the site config. Modified: llvm/trunk/test/Unit/lit.cfg Modified: llvm/trunk/test/Unit/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Unit/lit.cfg?rev=133641&r1=133640&r2=133641&view=diff ============================================================================== --- llvm/trunk/test/Unit/lit.cfg (original) +++ llvm/trunk/test/Unit/lit.cfg Wed Jun 22 15:41:53 2011 @@ -30,14 +30,6 @@ ### -# If necessary, point the dynamic loader at libLLVM.so. -if config.enable_shared: - shlibpath = config.environment.get(config.shlibpath_var,'') - if shlibpath: - shlibpath = os.pathsep + shlibpath - shlibpath = config.shlibdir + shlibpath - config.environment[config.shlibpath_var] = shlibpath - # Check that the object root is known. if config.test_exec_root is None: # Otherwise, we haven't loaded the site specific configuration (the user is @@ -81,3 +73,11 @@ lit.note('using out-of-tree build at %r' % llvm_obj_root) lit.load_config(config, site_cfg) raise SystemExit + +# If necessary, point the dynamic loader at libLLVM.so. +if config.enable_shared: + shlibpath = config.environment.get(config.shlibpath_var,'') + if shlibpath: + shlibpath = os.pathsep + shlibpath + shlibpath = config.shlibdir + shlibpath + config.environment[config.shlibpath_var] = shlibpath From dpatel at apple.com Wed Jun 22 15:56:56 2011 From: dpatel at apple.com (Devang Patel) Date: Wed, 22 Jun 2011 20:56:56 -0000 Subject: [llvm-commits] [llvm] r133642 - /llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Message-ID: <20110622205656.816062A6C12C@llvm.org> Author: dpatel Date: Wed Jun 22 15:56:56 2011 New Revision: 133642 URL: http://llvm.org/viewvc/llvm-project?rev=133642&view=rev Log: New binops need debug loc. Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=133642&r1=133641&r2=133642&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Wed Jun 22 15:56:56 2011 @@ -159,7 +159,8 @@ } // If we haven't found this binop, insert it. - Value *BO = Builder.CreateBinOp(Opcode, LHS, RHS, "tmp"); + Instruction *BO = cast(Builder.CreateBinOp(Opcode, LHS, RHS, "tmp")); + BO->setDebugLoc(SaveInsertPt->getDebugLoc()); rememberInstruction(BO); // Restore the original insert point. @@ -1155,6 +1156,7 @@ Instruction *Add = BinaryOperator::CreateAdd(CanonicalIV, One, "indvar.next", HP->getTerminator()); + Add->setDebugLoc(HP->getTerminator()->getDebugLoc()); rememberInstruction(Add); CanonicalIV->addIncoming(Add, HP); } else { From aggarwa4 at illinois.edu Wed Jun 22 15:57:15 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Wed, 22 Jun 2011 20:57:15 -0000 Subject: [llvm-commits] [poolalloc] r133643 - in /poolalloc/trunk: include/assistDS/TypeChecks.h lib/AssistDS/TypeChecks.cpp lib/AssistDS/TypeChecksOpt.cpp runtime/DynamicTypeChecks/Makefile runtime/DynamicTypeChecks/TypeRuntime.c runtime/DynamicTypeChecks/TypeRuntime.cpp Message-ID: <20110622205715.47D362A6C12C@llvm.org> Author: aggarwa4 Date: Wed Jun 22 15:57:15 2011 New Revision: 133643 URL: http://llvm.org/viewvc/llvm-project?rev=133643&view=rev Log: Modify handling of va lists. Store the metadata(total arguments, metadata for each, and number read) in a map in memory, instead of in SSA values. This makes the handling much easier. Also clean up a lot of dead code, caused by this and the previous changes. Added: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Removed: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c Modified: poolalloc/trunk/include/assistDS/TypeChecks.h poolalloc/trunk/lib/AssistDS/TypeChecks.cpp poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp poolalloc/trunk/runtime/DynamicTypeChecks/Makefile Modified: poolalloc/trunk/include/assistDS/TypeChecks.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/TypeChecks.h?rev=133643&r1=133642&r2=133643&view=diff ============================================================================== --- poolalloc/trunk/include/assistDS/TypeChecks.h (original) +++ poolalloc/trunk/include/assistDS/TypeChecks.h Wed Jun 22 15:57:15 2011 @@ -34,15 +34,11 @@ class TypeChecks : public ModulePass { private: std::map UsedTypes; - std::map VAListFunctionsMap; std::map IndFunctionsMap; std::list VAArgFunctions; - std::list VAListFunctions; std::list ByValFunctions; std::list AddressTakenFunctions; std::set IndCalls; - // Map of VAList to current count - std::map CounterMap; // Analysis from other passes. TargetData *TD; @@ -68,6 +64,7 @@ bool visitLoadInst(Module &M, LoadInst &LI); bool visitStoreInst(Module &M, StoreInst &SI); bool visitAllocaInst(Module &M, AllocaInst &AI); + bool visitVAArgInst(Module &M, VAArgInst &VI); bool visitGlobal(Module &M, GlobalVariable &GV, Constant *C, Instruction &I, SmallVector); @@ -80,8 +77,6 @@ bool visitVarArgFunction(Module &M, Function &F); - bool visitVAListFunction(Module &M, Function &F); - void visitVAListCall(Function *F); bool visitInternalVarArgFunction(Module &M, Function &F); bool visitInputFunctionValue(Module &M, Value *V, Instruction *CI); Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=133643&r1=133642&r2=133643&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Wed Jun 22 15:57:15 2011 @@ -60,19 +60,28 @@ static const Type *Int32Ty = 0; static const Type *Int64Ty = 0; static const PointerType *VoidPtrTy = 0; +static Constant *One = 0; +static Constant *Zero = 0; +static Constant *RegisterArgv; +static Constant *RegisterEnvp; + static Constant *trackGlobal; +static Constant *trackStoreInst; static Constant *trackStringInput; static Constant *trackArray; + static Constant *trackInitInst; static Constant *trackUnInitInst; -static Constant *trackStoreInst; + +static Constant *getTypeTag; static Constant *checkTypeInst; + static Constant *copyTypeInfo; static Constant *setTypeInfo; -static Constant *RegisterArgv; -static Constant *RegisterEnvp; -static Constant *compareTypeAndNumber; -static Constant *getTypeTag; + +static Constant *setVAInfo; +static Constant *copyVAInfo; +static Constant *checkVAArg; unsigned int TypeChecks::getTypeMarker(const Type * Ty) { if(DisablePointerTypeChecks) { @@ -122,6 +131,8 @@ Int32Ty = IntegerType::getInt32Ty(M.getContext()); Int64Ty = IntegerType::getInt64Ty(M.getContext()); VoidPtrTy = PointerType::getUnqual(Int8Ty); + One = ConstantInt::get(Int64Ty, 1); + Zero = ConstantInt::get(Int64Ty, 0); RegisterArgv = M.getOrInsertFunction("trackArgvType", VoidTy, @@ -193,22 +204,33 @@ Int64Ty,/*size*/ Int32Ty,/*tag*/ NULL); - compareTypeAndNumber = M.getOrInsertFunction("compareTypeAndNumber", - VoidTy, - Int64Ty,/*Total Args*/ - Int64Ty,/*Arg accessed*/ - Int8Ty,/*type*/ - VoidPtrTy,/*metadata ptr*/ - Int32Ty,/*tag*/ - NULL); trackStringInput = M.getOrInsertFunction("trackStringInput", VoidTy, VoidPtrTy, Int32Ty, NULL); + setVAInfo = M.getOrInsertFunction("setVAInfo", + VoidTy, + VoidPtrTy,/*va_list ptr*/ + Int64Ty,/*total num of elements in va_list */ + VoidPtrTy,/*ptr to metadta*/ + Int32Ty,/*tag*/ + NULL); + copyVAInfo = M.getOrInsertFunction("copyVAInfo", + VoidTy, + VoidPtrTy,/*dst va_list*/ + VoidPtrTy,/*src va_list */ + Int32Ty,/*tag*/ + NULL); + checkVAArg = M.getOrInsertFunction("checkVAArgType", + VoidTy, + VoidPtrTy,/*va_list ptr*/ + Int8Ty,/*type*/ + Int32Ty,/*tag*/ + NULL); + UsedTypes.clear(); // Reset if run multiple times. - VAListFunctions.clear(); VAArgFunctions.clear(); ByValFunctions.clear(); AddressTakenFunctions.clear(); @@ -258,23 +280,6 @@ VAArgFunctions.push_back(&F); continue; } - // Iterate and find all VAList functions - bool isVAListFunc = false; - const Type *ListType = M.getTypeByName("struct.__va_list_tag"); - if(!ListType) - continue; - - const Type *ListPtrType = ListType->getPointerTo(); - for (Function::arg_iterator I = F.arg_begin(); I != F.arg_end(); ++I) { - if(I->getType() == ListPtrType) { - isVAListFunc = true; - break; - } - } - if(isVAListFunc) { - VAListFunctions.push_back(&F); - continue; - } } // Modify all byval functions @@ -285,21 +290,6 @@ } - // NOTE:must visit before VAArgFunctions, to populate the map with the - // correct cloned functions. - while(!VAListFunctions.empty()) { - Function *F = VAListFunctions.back(); - VAListFunctions.pop_back(); - modified |= visitVAListFunction(M, *F); - } - - // iterate through all the VAList funtions and modify call sites - // to call the new function - std::map::iterator FI = VAListFunctionsMap.begin(), - FE = VAListFunctionsMap.end(); - for(; FI != FE; FI++) { - visitVAListCall(FI->second); - } while(!VAArgFunctions.empty()) { Function *F = VAArgFunctions.back(); VAArgFunctions.pop_back(); @@ -335,6 +325,8 @@ modified |= visitInvokeInst(M, *II); } else if (AllocaInst *AI = dyn_cast(&I)) { modified |= visitAllocaInst(M, *AI); + } else if (VAArgInst *VI = dyn_cast(&I)) { + modified |= visitVAArgInst(M, *VI); } } } @@ -347,7 +339,7 @@ modified |= visitIndirectCallSite(M,I); } - FI = IndFunctionsMap.begin(), FE = IndFunctionsMap.end(); + std::map::iterator FI = IndFunctionsMap.begin(), FE = IndFunctionsMap.end(); for(;FI!=FE;++FI) { Function *F = FI->first; @@ -475,211 +467,6 @@ ); } -void TypeChecks::visitVAListCall(Function *F) { - for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { - for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { - CallInst *CI = dyn_cast(I++); - if(!CI) - continue; - Function *CalledF = dyn_cast(CI->getCalledFunction()); - if(VAListFunctionsMap.find(CalledF) == VAListFunctionsMap.end()) - continue; - const Type *ListType = F->getParent()->getTypeByName("struct.__va_list_tag"); - const Type *ListPtrType = ListType->getPointerTo(); - unsigned VAListArgNum = 0; - for (Function::arg_iterator I = CalledF->arg_begin(); - I != CalledF->arg_end(); ++I) { - VAListArgNum ++; - if(I->getType() == ListPtrType) { - break; - } - } - - if(CounterMap.find(CI->getOperand(VAListArgNum)->stripPointerCasts()) == CounterMap.end()) { - // If this is a va_list we do not know about, - // do not insert checks. - - // FIXME: Handle cases where va_list is stored in memory - continue; - } - Function::arg_iterator NII = F->arg_begin(); - std::vectorArgs; - Args.push_back(NII++); // total count - Value *CounterSrc = CounterMap[CI->getOperand(VAListArgNum)->stripPointerCasts()]; - LoadInst *CountValue = new LoadInst(CounterSrc, "count", CI); - Args.push_back(CountValue); // current count - NII++; - Args.push_back(NII); // MD - for(unsigned i = 1 ;i < CI->getNumOperands(); i++) { - // Add the original argument - Args.push_back(CI->getOperand(i)); - } - CallInst *CINew = CallInst::Create(VAListFunctionsMap[CalledF], - Args.begin(), - Args.end(), - "", CI); - CI->replaceAllUsesWith(CINew); - CI->eraseFromParent(); - } - } -} - -bool TypeChecks::visitVAListFunction(Module &M, Function &F_orig) { - if(!F_orig.hasInternalLinkage()) - return false; - - int VAListArgNum = 0; - // Check if one of the arguments is a va_list - const Type *ListType = M.getTypeByName("struct.__va_list_tag"); - if(!ListType) - return false; - const Type *ListPtrType = ListType->getPointerTo(); - Argument *VAListArg = NULL; - for (Function::arg_iterator I = F_orig.arg_begin(); - I != F_orig.arg_end(); ++I) { - VAListArgNum ++; - if(I->getType() == ListPtrType) { - VAListArg = I; - break; - } - } - - // Clone the function to add arguments for count, MD - - // 1. Create the new argument types vector - std::vectorTP; - TP.push_back(Int64Ty); // for count - TP.push_back(Int64Ty); // for count - TP.push_back(VoidPtrTy); // for MD - for (Function::arg_iterator I = F_orig.arg_begin(); - I != F_orig.arg_end(); ++I) { - TP.push_back(I->getType()); - } - // 2. Create the new function prototype - const FunctionType *NewFTy = FunctionType::get(F_orig.getReturnType(), - TP,/*argument types*/ - false);/*vararg*/ - Function *F = Function::Create(NewFTy, - GlobalValue::InternalLinkage, - F_orig.getNameStr() + ".INT", - &M); - - // 3. Set the mapping for args - Function::arg_iterator NI = F->arg_begin(); - DenseMap ValueMap; - NI->setName("TotalCount"); - NI++; - NI->setName("CurrentCount"); - NI++; - NI->setName("MD"); - NI++; - for (Function::arg_iterator II = F_orig.arg_begin(); - NI != F->arg_end(); ++II, ++NI) { - // Each new argument maps to the argument in the old function - // For these arguments, also copy over the attributes - ValueMap[II] = NI; - NI->setName(II->getName()); - NI->addAttr(F_orig.getAttributes() - .getParamAttributes(II->getArgNo() + 1)); - } - - // 4. Copy over the attributes for the function. - F->setAttributes(F->getAttributes() - .addAttr(0, F_orig.getAttributes().getRetAttributes())); - F->setAttributes(F->getAttributes() - .addAttr(~0, F_orig.getAttributes().getFnAttributes())); - - // 5. Perform the cloning. - SmallVector Returns; - CloneFunctionInto(F, &F_orig, ValueMap, Returns); - - VAListFunctionsMap[&F_orig] = F; - inst_iterator InsPt = inst_begin(F); - - - // Store the information - Function::arg_iterator NII = F->arg_begin(); - AllocaInst *VASizeLoc = new AllocaInst(Int64Ty, "", &*InsPt); - new StoreInst(NII, VASizeLoc, &*InsPt); - NII++; - AllocaInst *Counter = new AllocaInst(Int64Ty, "",&*InsPt); - new StoreInst(NII, Counter, &*InsPt); - errs() << F->getNameStr() <<"\n"; - NII++; - AllocaInst *VAMDLoc = new AllocaInst(VoidPtrTy, "", &*InsPt); - new StoreInst(NII, VAMDLoc, &*InsPt); - - CounterMap[ValueMap[VAListArg]] = Counter; - // Find all va_copy calls - for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { - for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;I++) { - CallInst *CI = dyn_cast(I); - if(!CI) - continue; - Function *CalledF = dyn_cast(CI->getCalledFunction()); - if(!CalledF) - continue; - if(!CalledF->isIntrinsic()) - continue; - if(CalledF->getIntrinsicID() != Intrinsic::vacopy) - continue; - if(CounterMap.find(CI->getOperand(2)->stripPointerCasts()) == CounterMap.end()) { - // If this is a va_list we do not know about, - // do not insert checks. - - // FIXME: Handle cases where va_list is stored in memory - continue; - } - // Reinitialize the counter - AllocaInst *CounterDest = new AllocaInst(Int64Ty, "",&*InsPt); - Value *CounterSource = CounterMap[CI->getOperand(2)->stripPointerCasts()]; - LoadInst *CurrentValue = new LoadInst(CounterSource, "count", CI); - new StoreInst(CurrentValue, CounterDest, CI); - CounterMap[CI->getOperand(1)->stripPointerCasts()] = CounterDest; - } - } - - - // instrument va_arg to increment the counter - for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { - for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { - VAArgInst *VI = dyn_cast(I++); - if(!VI) - continue; - if(CounterMap.find(VI->getOperand(0)->stripPointerCasts()) == CounterMap.end()) { - // If this is a va_list we do not know about, - // do not insert checks. - - // FIXME: Handle cases where va_list is stored in memory - continue; - } - Constant *One = ConstantInt::get(Int64Ty, 1); - Value *CounterSrc = CounterMap[VI->getOperand(0)->stripPointerCasts()]; - LoadInst *OldValue = new LoadInst(CounterSrc, "count", VI); - Instruction *NewValue = BinaryOperator::Create(BinaryOperator::Add, - OldValue, - One, - "count", - VI); - new StoreInst(NewValue, CounterSrc, VI); - std::vector Args; - Instruction *VASize = new LoadInst(VASizeLoc, "", VI); - Instruction *VAMetaData = new LoadInst(VAMDLoc, "", VI); - Args.push_back(VASize); - Args.push_back(OldValue); - Args.push_back(getTypeMarkerConstant(VI)); - Args.push_back(VAMetaData); - Args.push_back(getTagCounter()); - CallInst::Create(compareTypeAndNumber, - Args.begin(), - Args.end(), - "", VI); - } - } - - return true; -} - bool TypeChecks::visitAddressTakenFunction(Module &M, Function &F) { // Clone function // 1. Create the new argument types vector @@ -823,13 +610,13 @@ true); Function *NewF = Function::Create(NewFTy, GlobalValue::InternalLinkage, - F.getNameStr() + ".mod", + F.getNameStr() + ".vararg", &M); // 3. Set the mapping for the args Function::arg_iterator NI = NewF->arg_begin(); DenseMap ValueMap; - NI->setName("TotalCount"); + NI->setName("TotalArgCount"); NI++; NI->setName("MD"); NI++; @@ -856,7 +643,6 @@ // Store the information inst_iterator InsPt = inst_begin(NewF); Function::arg_iterator NII = NewF->arg_begin(); - AllocaInst *VASizeLoc = new AllocaInst(Int64Ty, "", &*InsPt); // Subtract the number of initial arguments Constant *InitialArgs = ConstantInt::get(Int64Ty, F.arg_size()); Instruction *NewValue = BinaryOperator::Create(BinaryOperator::Sub, @@ -864,10 +650,8 @@ InitialArgs, "varargs", &*InsPt); - new StoreInst(NewValue, VASizeLoc, &*InsPt); NII++; - AllocaInst *VAMDLoc = new AllocaInst(VoidPtrTy, "", &*InsPt); // Increment by the number of Initial Args, so as to not read the metadata //for those. Value *Idx[2]; @@ -877,12 +661,6 @@ Idx, Idx + 1, "", &*InsPt); - new StoreInst(GEP, VAMDLoc, &*InsPt); - // Add a counter variable to the function entry - AllocaInst *Counter = new AllocaInst(Int64Ty, "",&*InsPt); - new StoreInst(ConstantInt::get(Int64Ty, 0), Counter, &*InsPt); - - // visit all VAStarts and initialize the counter for (Function::iterator B = NewF->begin(), FE = NewF->end(); B != FE; ++B) { for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;I++) { @@ -897,9 +675,13 @@ if(CalledF->getIntrinsicID() != Intrinsic::vastart) continue; // Reinitialize the counter - StoreInst *SI3 = new StoreInst(ConstantInt::get(Int64Ty, 0), Counter); - SI3->insertAfter(CI); - CounterMap[CI->getOperand(1)->stripPointerCasts()] = Counter; + CastInst *BCI = BitCastInst::CreatePointerCast(CI->getOperand(1), VoidPtrTy, "", CI); + std::vector Args; + Args.push_back(BCI); + Args.push_back(NewValue); + Args.push_back(GEP); + Args.push_back(getTagCounter()); + CallInst::Create(setVAInfo, Args.begin(), Args.end(), "", CI); } } @@ -916,93 +698,13 @@ continue; if(CalledF->getIntrinsicID() != Intrinsic::vacopy) continue; - // Reinitialize the counter - AllocaInst *CounterDest = new AllocaInst(Int64Ty, "",&*InsPt); - Value *CounterSource = CounterMap[CI->getOperand(2)->stripPointerCasts()]; - LoadInst *CurrentValue = new LoadInst(CounterSource, "count", CI); - new StoreInst(CurrentValue, CounterDest, CI); - CounterMap[CI->getOperand(1)->stripPointerCasts()] = CounterDest; - } - } - - // Modify function to add checks on every var_arg call to ensure that we - // are not accessing more arguments than we passed in. - - // Increment the counter - for (Function::iterator B = NewF->begin(), FE = NewF->end(); B != FE; ++B) { - for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { - VAArgInst *VI = dyn_cast(I++); - if(!VI) - continue; - if(CounterMap.find(VI->getOperand(0)->stripPointerCasts()) == CounterMap.end()) { - // If this is a va_list we do not know about, - // do not insert checks. - - // FIXME: Handle cases where va_list is stored in memory - continue; - } - Constant *One = ConstantInt::get(Int64Ty, 1); - Value *CounterSrc = CounterMap[VI->getOperand(0)->stripPointerCasts()]; - LoadInst *OldValue = new LoadInst(CounterSrc, "count", VI); - Instruction *NewValue = BinaryOperator::Create(BinaryOperator::Add, - OldValue, - One, - "count", - VI); - new StoreInst(NewValue, CounterSrc, VI); + CastInst *BCI_Src = BitCastInst::CreatePointerCast(CI->getOperand(2), VoidPtrTy, "", CI); + CastInst *BCI_Dest = BitCastInst::CreatePointerCast(CI->getOperand(1), VoidPtrTy, "", CI); std::vector Args; - Instruction *VASize = new LoadInst(VASizeLoc, "", VI); - Instruction *VAMetaData = new LoadInst(VAMDLoc, "", VI); - Args.push_back(VASize); - Args.push_back(OldValue); - Args.push_back(getTypeMarkerConstant(VI)); - Args.push_back(VAMetaData); + Args.push_back(BCI_Dest); + Args.push_back(BCI_Src); Args.push_back(getTagCounter()); - CallInst::Create(compareTypeAndNumber, - Args.begin(), - Args.end(), - "", VI); - } - } - - - // modify calls to va list functions to pass the metadata - for (Function::iterator B = NewF->begin(), FE = NewF->end(); B != FE; ++B) { - for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { - CallInst *CI = dyn_cast(I++); - if(!CI) - continue; - Function *CalledF = dyn_cast(CI->getCalledFunction()); - - if(VAListFunctionsMap.find(CalledF) == VAListFunctionsMap.end()) - continue; - const Type *ListType = M.getTypeByName("struct.__va_list_tag"); - const Type *ListPtrType = ListType->getPointerTo(); - unsigned VAListArgNum = 0; - for (Function::arg_iterator I = CalledF->arg_begin(); - I != CalledF->arg_end(); ++I) { - VAListArgNum ++; - if(I->getType() == ListPtrType) { - break; - } - } - std::vectorArgs; - - Value *CounterSrc = CounterMap[CI->getOperand(VAListArgNum)->stripPointerCasts()]; - Instruction *VASize = new LoadInst(VASizeLoc, "", CI); - Instruction *VACounter = new LoadInst(CounterSrc, "", CI); - Instruction *VAMetaData = new LoadInst(VAMDLoc, "", CI); - Args.push_back(VASize); // toatl count - Args.push_back(VACounter); // current count - Args.push_back(VAMetaData); // MD - for(unsigned i = 1 ;i < CI->getNumOperands(); i++) { - // Add the original argument - Args.push_back(CI->getOperand(i)); - } - CallInst *CINew = CallInst::Create(VAListFunctionsMap[CalledF], - Args.begin(), Args.end(), "", CI); - CI->replaceAllUsesWith(CINew); - CI->eraseFromParent(); + CallInst::Create(copyVAInfo, Args.begin(), Args.end(), "", CI); } } @@ -1357,7 +1059,7 @@ if(!I->hasInitializer()) continue; SmallVectorindex; - index.push_back(ConstantInt::get(Int64Ty, 0)); + index.push_back(Zero); visitGlobal(M, *I, I->getInitializer(), *InsertPt, index); } // @@ -1538,6 +1240,17 @@ } return true; } +bool TypeChecks::visitVAArgInst(Module &M, VAArgInst &VI) { + if(!VI.getParent()->getParent()->hasInternalLinkage()) + return false; + CastInst *BCI = BitCastInst::CreatePointerCast(VI.getOperand(0), VoidPtrTy, "", &VI); + std::vectorArgs; + Args.push_back(BCI); + Args.push_back(getTypeMarkerConstant(&VI)); + Args.push_back(getTagCounter()); + CallInst::Create(checkVAArg, Args.begin(), Args.end(), "", &VI); + return false; +} // Insert code to initialize meta data to bottom // Insert code to set objects to 0 @@ -1880,7 +1593,6 @@ Args.push_back(BCI); CastInst *Size = CastInst::CreateIntegerCast(I, Int64Ty, false); Size->insertAfter(I); - Constant *One = ConstantInt::get(Int64Ty, 1); Instruction *NewValue = BinaryOperator::Create(BinaryOperator::Add, Size, One); @@ -2112,4 +1824,3 @@ return true; } - Modified: poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp?rev=133643&r1=133642&r2=133643&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp Wed Jun 22 15:57:15 2011 @@ -43,7 +43,6 @@ static const PointerType *VoidPtrTy = 0; static Constant *trackGlobal; static Constant *trackStringInput; -static Constant *trackArray; static Constant *trackInitInst; static Constant *trackUnInitInst; static Constant *trackStoreInst; @@ -51,7 +50,6 @@ static Constant *setTypeInfo; static Constant *checkTypeInst; static Constant *MallocFunc; -static Constant *getTypeTag; bool TypeChecksOpt::runOnModule(Module &M) { TS = &getAnalysis >(); @@ -63,12 +61,6 @@ Int64Ty = IntegerType::getInt64Ty(M.getContext()); VoidPtrTy = PointerType::getUnqual(Int8Ty); - getTypeTag = M.getOrInsertFunction("getTypeTag", - VoidTy, - VoidPtrTy, /*ptr*/ - Int64Ty, /*size*/ - VoidPtrTy, /*dest for type tag*/ - NULL); trackGlobal = M.getOrInsertFunction("trackGlobal", VoidTy, VoidPtrTy,/*ptr*/ @@ -76,13 +68,6 @@ Int64Ty,/*size*/ Int32Ty,/*tag*/ NULL); - trackArray = M.getOrInsertFunction("trackArray", - VoidTy, - VoidPtrTy,/*ptr*/ - Int64Ty,/*size*/ - Int64Ty,/*count*/ - Int32Ty,/*tag*/ - NULL); trackInitInst = M.getOrInsertFunction("trackInitInst", VoidTy, VoidPtrTy,/*ptr*/ Modified: poolalloc/trunk/runtime/DynamicTypeChecks/Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/DynamicTypeChecks/Makefile?rev=133643&r1=133642&r2=133643&view=diff ============================================================================== --- poolalloc/trunk/runtime/DynamicTypeChecks/Makefile (original) +++ poolalloc/trunk/runtime/DynamicTypeChecks/Makefile Wed Jun 22 15:57:15 2011 @@ -8,6 +8,10 @@ endif endif +ifdef ENABLE_OPTIMIZED +CXXFLAGS += -DNDEBUG=1 +endif + include $(LEVEL)/Makefile.common # Always build optimized and debug versions Removed: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c?rev=133642&view=auto ============================================================================== --- poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c (original) +++ poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.c (removed) @@ -1,303 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG (0) - -/* Size of shadow memory. We're hoping everything fits in 46bits. */ -#define SIZE ((size_t)(1L << 46)) - -/* Fixed start of memory. Needs to be page-aligned, - * and it needs to be large enough that program itself is loaded below it - * and so are the libraries. - * FIXME: This address has been picked for maute. Might not work on other - * machines. Need a more robust way of picking base address. - * For now, run a version of the tool without the base fixed, and - * choose address. - #define BASE ((void *)(0x2aaaab2a5000)) - */ -#define BASE ((void *)(0x2aaaab88c000)) -/* - * Do some macro magic to get mmap macros defined properly on all platforms. - */ -#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) -# define MAP_ANONYMOUS MAP_ANON -#endif /* defined(MAP_ANON) && !defined(MAP_ANONYMOUS) */ - -uint8_t * const shadow_begin = BASE; - -extern char* typeNames[]; - -void trackInitInst(void *ptr, uint64_t size, uint32_t tag); - -inline uintptr_t maskAddress(void *ptr) { - uintptr_t p = (uintptr_t)ptr; - if (p >= (uintptr_t)BASE + SIZE) p -= SIZE; - -#if DEBUG - assert(p <= SIZE && "Pointer out of range!"); -#endif - return p; -} - - -void trackStringInput(void *ptr, uint32_t tag) { - trackInitInst(ptr, strlen(ptr) + 1, tag); -} - - -/** - * Initialize the shadow memory which records the 1:1 mapping of addresses to types. - */ -void shadowInit() { - char * res = mmap(BASE, SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); - - if (res == MAP_FAILED) { - fprintf(stderr, "Failed to map the shadow memory!\n"); - fflush(stderr); - assert(0 && "MAP_FAILED"); - } -} - -/** - * Copy arguments into a new array, and initialize - * metadata for that location to TOP/initialized. - */ -void trackArgvType(int argc, char **argv) { - int index = 0; - for (; index < argc; ++index) { - trackInitInst(argv[index], (strlen(argv[index]) + 1)*sizeof(char), 0); - } - trackInitInst(argv, (argc + 1)*sizeof(char*), 0); -} - -void trackEnvpType(char **envp) { - int index = 0; - for(;envp[index] != NULL; ++index) - trackInitInst(envp[index], (strlen(envp[index]) + 1)*sizeof(char), 0); - trackInitInst(envp, (index )*sizeof(char*), 0); -} - -/** - * Record the global type and address in the shadow memory. - */ -void trackGlobal(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) { - uintptr_t p = maskAddress(ptr); - shadow_begin[p] = typeNumber; - memset(&shadow_begin[p + 1], 0, size - 1); -#if DEBUG - printf("Global(%d): %p, %p = %u | %lu bytes\n", tag, ptr, (void *)p, typeNumber, size); -#endif -} - -/** - * Record the type stored at ptr(of size size) and replicate it - */ -void trackArray(void *ptr, uint64_t size, uint64_t count, uint32_t tag) { - uintptr_t p = maskAddress(ptr); - uintptr_t p1 = maskAddress(ptr); - uint64_t i; - - for (i = 1; i < count; ++i) { - p += size; - memcpy(&shadow_begin[p], &shadow_begin[p1], size); - } -} - -/** - * Record the stored type and address in the shadow memory. - */ -void trackStoreInst(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) { - uintptr_t p = maskAddress(ptr); - shadow_begin[p] = typeNumber; - memset(&shadow_begin[p + 1], 0, size - 1); - printf("Store(%d): %p, %p = %u | %lu bytes | \n", tag, ptr, (void *)p, typeNumber, size); - -} - -/** - * Check that the two types match - */ -void compareTypes(uint8_t typeNumberSrc, uint8_t typeNumberDest, uint32_t tag) { - if(typeNumberSrc != typeNumberDest) { - printf("Type mismatch(%u): expecting %s, found %s! \n", tag, typeNames[typeNumberDest], typeNames[typeNumberSrc]); - } -} - -/** - * Check that number of VAArg accessed is not greater than those passed - */ -void compareNumber(uint64_t NumArgsPassed, uint64_t ArgAccessed, uint32_t tag){ - if(ArgAccessed > NumArgsPassed) { - printf("Type mismatch(%u): Accessing variable %lu, passed only %lu! \n", tag, ArgAccessed, NumArgsPassed); - } -} - -/** - * Combined check for Va_arg. - * Check that no. of arguments is less than passed - * Check that the type being accessed is correct - * MD : pointer to array of metadata for each argument passed - */ -void compareTypeAndNumber(uint64_t NumArgsPassed, uint64_t ArgAccessed, uint8_t TypeAccessed, void *MD, uint32_t tag) { - compareNumber(NumArgsPassed, ArgAccessed, tag); - compareTypes(TypeAccessed, ((uint8_t*)MD)[ArgAccessed], tag); -} - -void getTypeTag(void *ptr, uint64_t size, uint8_t *dest) { - uintptr_t p = maskAddress(ptr); - assert(p + size < SIZE); - - memcpy(dest, &shadow_begin[p], size); -} - -void checkType(uint8_t typeNumber, uint64_t size, uint8_t *metadata, void *ptr, uint32_t tag) { - uint8_t i = 1; - /* Check if this an initialized but untyped memory.*/ - if (typeNumber != metadata[0]) { - if (metadata[0] != 0xFF) { - printf("Type mismatch(%u): %p expecting %s, found %s!\n", tag, ptr, typeNames[typeNumber], typeNames[metadata[0]]); - return; - } else { - /* If so, set type to the type being read. - Check that none of the bytes are typed.*/ - for (; i < size; ++i) { - if (0xFF != metadata[i]) { - printf("Type alignment mismatch(%u): expecting %s, found %s!\n", tag, typeNames[typeNumber], typeNames[metadata[i]]); - break; - } - } - trackStoreInst(ptr, typeNumber, size, tag); - return ; - } - } - - for (; i < size; ++i) { - if (0 != metadata[i]) { - printf("Type alignment mismatch(%u): expecting %s, found %s!\n", tag, typeNames[typeNumber], typeNames[metadata[0]]); - break; - } - } - -} - -/** - * For memset type instructions, that set values. - * 0xFF type indicates that any type can be read, - */ -void trackInitInst(void *ptr, uint64_t size, uint32_t tag) { - uintptr_t p = maskAddress(ptr); - memset(&shadow_begin[p], 0xFF, size); -#if DEBUG - printf("Initialize: %p, %p | %lu bytes | %u\n", ptr, (void *)p, size, tag); -#endif -} - -/** - * Clear the metadata for given pointer - */ -void trackUnInitInst(void *ptr, uint64_t size, uint32_t tag) { - uintptr_t p = maskAddress(ptr); - memset(&shadow_begin[p], 0x00, size); -#if DEBUG - printf("Unitialize: %p, %p | %lu bytes | %u\n", ptr, (void *)p, size, tag); -#endif -} - -/** - * Copy size bits of metadata from src ptr to dest ptr. - */ -void copyTypeInfo(void *dstptr, void *srcptr, uint64_t size, uint32_t tag) { - uintptr_t d = maskAddress(dstptr); - uintptr_t s = maskAddress(srcptr); - memcpy(&shadow_begin[d], &shadow_begin[s], size); -#if DEBUG - printf("Copy(%d): %p, %p = %u | %lu bytes \n", tag, dstptr, srcptr, shadow_begin[s], size); -#endif -} -void setTypeInfo(void *dstptr, void *metadata, uint64_t size, uint32_t tag) { - uintptr_t d = maskAddress(dstptr); - memcpy(&shadow_begin[d], metadata, size); -} - -/** - * Initialize metadata for the pointer returned by __ctype_b_loc - */ -void trackctype(void *ptr, uint32_t tag) { - short *p, *p1; - trackInitInst(ptr, sizeof(short*), tag); - p = *(short**)ptr; - p1 = p -128; - trackInitInst(p1, sizeof(short)*384, tag); -} - -void trackctype_32(void *ptr, uint32_t tag) { - int *p, *p1; - trackInitInst(ptr, sizeof(int*), tag); - p = *(int**)ptr; - p1 = p -128 ; - trackInitInst(p1, sizeof(int)*384, tag); -} - -/** - * Initialize metadata for the dst pointer of strncpy - */ -void trackStrncpyInst(void *dst, void *src, uint64_t size, uint32_t tag) { - if(strlen(src) < size) - size = strlen(src) + 1; - copyTypeInfo(dst, src, size, tag); -} - -/** - * Initialize metadata for the dst pointer of strcpy - */ -void trackStrcpyInst(void *dst, void *src, uint32_t tag) { - copyTypeInfo(dst, src, strlen(src)+1, tag); -} - -void trackStrcatInst(void *dst, void *src, uint32_t tag) { - uintptr_t dst_start = (uintptr_t)(dst) + strlen(dst) -1; - copyTypeInfo((void*)dst_start, src, strlen(src)+1, tag); -} - -void trackgetcwd(void *ptr, uint32_t tag) { - if(!ptr) - return; - trackInitInst(ptr, strlen(ptr) + 1, tag); -} - -void trackgethostname(void *ptr, uint32_t tag) { - trackInitInst(ptr, strlen(ptr) + 1, tag); -} - -void trackgetaddrinfo(void *ptr, uint32_t tag) { - struct addrinfo *res; - struct addrinfo ** result = (struct addrinfo **)ptr; - for(res = *result; res != NULL; res = res->ai_next) { - trackInitInst(res->ai_addr, sizeof(struct sockaddr), tag); - trackInitInst(res, sizeof(struct addrinfo), tag); - } - - trackInitInst(result, sizeof(struct addrinfo*), tag); -} - -void trackaccept(void *ptr, uint32_t tag) { - trackInitInst(ptr, sizeof(struct sockaddr), tag); -} - -void trackpoll(void *ptr, uint64_t nfds, uint32_t tag) { - struct pollfd *fds = (struct pollfd *)ptr; - unsigned i = 0; - while (i < nfds) { - trackInitInst(&fds[i], sizeof(struct pollfd), tag); - i++; - } -} Added: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp?rev=133643&view=auto ============================================================================== --- poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp (added) +++ poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Wed Jun 22 15:57:15 2011 @@ -0,0 +1,389 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DEBUG (0) + +/* Size of shadow memory. We're hoping everything fits in 46bits. */ +#define SIZE ((size_t)(1L << 46)) + +/* Fixed start of memory. Needs to be page-aligned, + * and it needs to be large enough that program itself is loaded below it + * and so are the libraries. + * FIXME: This address has been picked for maute. Might not work on other + * machines. Need a more robust way of picking base address. + * For now, run a version of the tool without the base fixed, and + * choose address. + */ +#define BASE ((uint8_t *)(0x2aaaab88c000)) +/* + * Do some macro magic to get mmap macros defined properly on all platforms. + */ +#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) +# define MAP_ANONYMOUS MAP_ANON +#endif /* defined(MAP_ANON) && !defined(MAP_ANONYMOUS) */ + +struct va_info { + uint64_t numElements; + uint64_t counter; + uint8_t *metadata; +}; + +// Map to store info about va lists +std::map VA_InfoMap; + +// Pointer to the shadow_memory +uint8_t * const shadow_begin = BASE; + +// Map from type numbers to type names. +extern char* typeNames[]; + +extern "C" { + void trackInitInst(void *ptr, uint64_t size, uint32_t tag); + void shadowInit(); + void trackArgvType(int argc, char **argv) ; + void trackEnvpType(char **envp) ; + void trackGlobal(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) ; + void trackArray(void *ptr, uint64_t size, uint64_t count, uint32_t tag) ; + void trackStoreInst(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) ; + void trackStringInput(void *ptr, uint32_t tag) ; + void compareTypes(uint8_t typeNumberSrc, uint8_t typeNumberDest, uint32_t tag) ; + void compareNumber(uint64_t NumArgsPassed, uint64_t ArgAccessed, uint32_t tag); + void compareTypeAndNumber(uint64_t NumArgsPassed, uint64_t ArgAccessed, uint8_t TypeAccessed, void *MD, uint32_t tag) ; + void checkVAArgType(void *va_list, uint8_t TypeAccessed, uint32_t tag) ; + void getTypeTag(void *ptr, uint64_t size, uint8_t *dest) ; + void checkType(uint8_t typeNumber, uint64_t size, uint8_t *metadata, void *ptr, uint32_t tag); + void trackInitInst(void *ptr, uint64_t size, uint32_t tag) ; + void trackUnInitInst(void *ptr, uint64_t size, uint32_t tag) ; + void copyTypeInfo(void *dstptr, void *srcptr, uint64_t size, uint32_t tag) ; + void setTypeInfo(void *dstptr, void *metadata, uint64_t size, uint32_t tag) ; + void setVAInfo(void *va_list, uint64_t totalCount, uint8_t *metadata_ptr) ; + void copyVAInfo(void *va_list_dst, uint8_t *va_list_src) ; + void trackctype(void *ptr, uint32_t tag) ; + void trackctype_32(void *ptr, uint32_t tag) ; + void trackStrncpyInst(void *dst, void *src, uint64_t size, uint32_t tag) ; + void trackStrcpyInst(void *dst, void *src, uint32_t tag) ; + void trackStrcatInst(void *dst, void *src, uint32_t tag) ; + void trackgetcwd(void *ptr, uint32_t tag) ; + void trackgethostname(void *ptr, uint32_t tag) ; + void trackgetaddrinfo(void *ptr, uint32_t tag) ; + void trackaccept(void *ptr, uint32_t tag) ; + void trackpoll(void *ptr, uint64_t nfds, uint32_t tag) ; +} + +void trackInitInst(void *ptr, uint64_t size, uint32_t tag); + +inline uintptr_t maskAddress(void *ptr) { + uintptr_t p = (uintptr_t)ptr; + if (p >= (uintptr_t)BASE + SIZE) p -= SIZE; + +#if DEBUG + assert(p <= SIZE && "Pointer out of range!"); +#endif + return p; +} + +/** + * Initialize the shadow memory which records the 1:1 mapping of addresses to types. + */ +void shadowInit() { + void * res = mmap(BASE, SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); + + if (res == MAP_FAILED) { + fprintf(stderr, "Failed to map the shadow memory!\n"); + fflush(stderr); + assert(0 && "MAP_FAILED"); + } + VA_InfoMap.clear(); +} + +/** + * initialize metadata to TOP/initialized. + */ +void trackArgvType(int argc, char **argv) { + int index = 0; + for (; index < argc; ++index) { + trackInitInst(argv[index], (strlen(argv[index]) + 1)*sizeof(char), 0); + } + trackInitInst(argv, (argc + 1)*sizeof(char*), 0); +} + +/** + * initialize metadata to TOP/initialized. + */ +void trackEnvpType(char **envp) { + int index = 0; + for(;envp[index] != NULL; ++index) + trackInitInst(envp[index], (strlen(envp[index]) + 1)*sizeof(char), 0); + trackInitInst(envp, (index )*sizeof(char*), 0); +} + +/** + * Record the global type and address in the shadow memory. + */ +void trackGlobal(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) { + uintptr_t p = maskAddress(ptr); + shadow_begin[p] = typeNumber; + memset(&shadow_begin[p + 1], 0, size - 1); +#if DEBUG + printf("Global(%d): %p, %p = %u | %lu bytes\n", tag, ptr, (void *)p, typeNumber, size); +#endif +} + +/** + * Record the type stored at ptr(of size size) and replicate it + */ +void trackArray(void *ptr, uint64_t size, uint64_t count, uint32_t tag) { + uintptr_t p = maskAddress(ptr); + uintptr_t p1 = maskAddress(ptr); + uint64_t i; + + for (i = 1; i < count; ++i) { + p += size; + memcpy(&shadow_begin[p], &shadow_begin[p1], size); + } +} + +/** + * Record the stored type and address in the shadow memory. + */ +void trackStoreInst(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) { + uintptr_t p = maskAddress(ptr); + shadow_begin[p] = typeNumber; + memset(&shadow_begin[p + 1], 0, size - 1); +#if DEBUG + printf("Store(%d): %p, %p = %u | %lu bytes | \n", tag, ptr, (void *)p, typeNumber, size); +#endif + +} + +/** + * Record that a string is stored at ptr + */ +void trackStringInput(void *ptr, uint32_t tag) { + trackInitInst(ptr, strlen((const char *)ptr) + 1, tag); +} + +/** + * Check that the two types match + */ +void compareTypes(uint8_t typeNumberSrc, uint8_t typeNumberDest, uint32_t tag) { + if(typeNumberSrc != typeNumberDest) { + printf("Type mismatch(%u): expecting %s, found %s! \n", tag, typeNames[typeNumberDest], typeNames[typeNumberSrc]); + } +} + +/** + * Check that number of VAArg accessed is not greater than those passed + */ +void compareNumber(uint64_t NumArgsPassed, uint64_t ArgAccessed, uint32_t tag){ + if(ArgAccessed > NumArgsPassed) { + printf("Type mismatch(%u): Accessing variable %lu, passed only %lu! \n", tag, ArgAccessed, NumArgsPassed); + } +} + +/** + * Combined check for Va_arg. + * Check that no. of arguments is less than passed + * Check that the type being accessed is correct + */ +void checkVAArgType(void *va_list, uint8_t TypeAccessed, uint32_t tag) { + va_info v = VA_InfoMap[va_list]; + compareNumber(v.numElements, v.counter, tag); + compareTypes(TypeAccessed, v.metadata[v.counter], tag); + v.counter++; + VA_InfoMap[va_list] = v; +} + +/** + * For loads, return the metadata(for size bytes) stored at the ptr + * Store it in dest + */ +void getTypeTag(void *ptr, uint64_t size, uint8_t *dest) { + uintptr_t p = maskAddress(ptr); + assert(p + size < SIZE); + + memcpy(dest, &shadow_begin[p], size); +} + +/** + * Compare the typeNumber with the type info(for given size) stored at the metadata ptr. + * ptr and tag are for debugging + */ +void __attribute__((always_inline)) +checkType(uint8_t typeNumber, uint64_t size, uint8_t *metadata, void *ptr, uint32_t tag) { + /* Check if this an initialized but untyped memory.*/ + if (typeNumber != metadata[0]) { + if (metadata[0] != 0xFF) { + printf("Type mismatch(%u): %p expecting %s, found %s!\n", tag, ptr, typeNames[typeNumber], typeNames[metadata[0]]); + return; + } else { + /* If so, set type to the type being read. + Check that none of the bytes are typed.*/ + for (unsigned i = 1; i < size; ++i) { + if (0xFF != metadata[i]) { + printf("Type alignment mismatch(%u): expecting %s, found %s!\n", tag, typeNames[typeNumber], typeNames[metadata[i]]); + break; + } + } + trackStoreInst(ptr, typeNumber, size, tag); + return ; + } + } + + for (unsigned i = 1 ; i < size; ++i) { + if (0 != metadata[i]) { + printf("Type alignment mismatch(%u): expecting %s, found %s!\n", tag, typeNames[typeNumber], typeNames[metadata[0]]); + break; + } + } +} + +/** + * For memset type instructions, that set values. + * 0xFF type indicates that any type can be read, + */ +void trackInitInst(void *ptr, uint64_t size, uint32_t tag) { + uintptr_t p = maskAddress(ptr); + memset(&shadow_begin[p], 0xFF, size); +#if DEBUG + printf("Initialize: %p, %p | %lu bytes | %u\n", ptr, (void *)p, size, tag); +#endif +} + +/** + * Clear the metadata for given pointer + */ +void trackUnInitInst(void *ptr, uint64_t size, uint32_t tag) { + uintptr_t p = maskAddress(ptr); + memset(&shadow_begin[p], 0x00, size); +#if DEBUG + printf("Unitialize: %p, %p | %lu bytes | %u\n", ptr, (void *)p, size, tag); +#endif +} + +/** + * Copy size bytes of metadata from src ptr to dest ptr. + */ +void copyTypeInfo(void *dstptr, void *srcptr, uint64_t size, uint32_t tag) { + uintptr_t d = maskAddress(dstptr); + uintptr_t s = maskAddress(srcptr); + memcpy(&shadow_begin[d], &shadow_begin[s], size); +#if DEBUG + printf("Copy(%d): %p, %p = %u | %lu bytes \n", tag, dstptr, srcptr, shadow_begin[s], size); +#endif +} + +/** + * Copy size bytes of metadata from metadata to dest ptr + */ +void setTypeInfo(void *dstptr, void *metadata, uint64_t size, uint32_t tag) { + uintptr_t d = maskAddress(dstptr); + memcpy(&shadow_begin[d], metadata, size); +} + +/** + * Initialize the metadata for a given VAList + */ +void setVAInfo(void *va_list, uint64_t totalCount, uint8_t *metadata_ptr, uint32_t tag) { + struct va_info v = {totalCount, 0, metadata_ptr}; + VA_InfoMap[va_list] = v; +} + +/** + * Copy va list metadata from one list to the other. + */ +void copyVAInfo(void *va_list_dst, uint8_t *va_list_src, uint32_t tag) { + VA_InfoMap[va_list_dst] = VA_InfoMap[va_list_src]; +} + +/** + * Initialize metadata for the pointer returned by __ctype_b_loc + */ +void trackctype(void *ptr, uint32_t tag) { + short *p, *p1; + trackInitInst(ptr, sizeof(short*), tag); + p = *(short**)ptr; + p1 = p -128; + trackInitInst(p1, sizeof(short)*384, tag); +} + +void trackctype_32(void *ptr, uint32_t tag) { + int *p, *p1; + trackInitInst(ptr, sizeof(int*), tag); + p = *(int**)ptr; + p1 = p -128 ; + trackInitInst(p1, sizeof(int)*384, tag); +} + +/** + * Initialize metadata for the dst pointer of strncpy + */ +void trackStrncpyInst(void *dst, void *src, uint64_t size, uint32_t tag) { + if(strlen((const char *)src) < size) + size = strlen((const char *)src) + 1; + copyTypeInfo(dst, src, size, tag); +} + +/** + * Initialize metadata for the dst pointer of strcpy + */ +void trackStrcpyInst(void *dst, void *src, uint32_t tag) { + copyTypeInfo(dst, src, strlen((const char *)src)+1, tag); +} + +/** + * Initialize the metadata fr dst pointer of strcap + */ +void trackStrcatInst(void *dst, void *src, uint32_t tag) { + uintptr_t dst_start = (uintptr_t)(dst) + strlen((const char *)dst) -1; + copyTypeInfo((void*)dst_start, src, strlen((const char *)src)+1, tag); +} + +/** + * Initialize metadata for some library functions + */ + +void trackgetcwd(void *ptr, uint32_t tag) { + if(!ptr) + return; + trackInitInst(ptr, strlen((const char *)ptr) + 1, tag); +} + +void trackgethostname(void *ptr, uint32_t tag) { + trackInitInst(ptr, strlen((const char *)ptr) + 1, tag); +} + +void trackgetaddrinfo(void *ptr, uint32_t tag) { + struct addrinfo *res; + struct addrinfo ** result = (struct addrinfo **)ptr; + for(res = *result; res != NULL; res = res->ai_next) { + trackInitInst(res->ai_addr, sizeof(struct sockaddr), tag); + trackInitInst(res, sizeof(struct addrinfo), tag); + } + + trackInitInst(result, sizeof(struct addrinfo*), tag); +} + +void trackaccept(void *ptr, uint32_t tag) { + trackInitInst(ptr, sizeof(struct sockaddr), tag); +} + +void trackpoll(void *ptr, uint64_t nfds, uint32_t tag) { + struct pollfd *fds = (struct pollfd *)ptr; + unsigned i = 0; + while (i < nfds) { + trackInitInst(&fds[i], sizeof(struct pollfd), tag); + i++; + } +} From isanbard at gmail.com Wed Jun 22 16:07:27 2011 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 22 Jun 2011 21:07:27 -0000 Subject: [llvm-commits] [llvm] r133645 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20110622210727.E1FCA2A6C12C@llvm.org> Author: void Date: Wed Jun 22 16:07:27 2011 New Revision: 133645 URL: http://llvm.org/viewvc/llvm-project?rev=133645&view=rev Log: Move class methods out-of-line. This reduces the indentation, and is more in line with LLVM's general coding style. No functionality change. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=133645&r1=133644&r2=133645&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Jun 22 16:07:27 2011 @@ -120,37 +120,8 @@ return SectionAddress.lookup(SD); } uint64_t getSymbolAddress(const MCSymbolData* SD, - const MCAsmLayout &Layout) const { - const MCSymbol &S = SD->getSymbol(); - - // If this is a variable, then recursively evaluate now. - if (S.isVariable()) { - MCValue Target; - if (!S.getVariableValue()->EvaluateAsRelocatable(Target, Layout)) - report_fatal_error("unable to evaluate offset for variable '" + - S.getName() + "'"); - - // Verify that any used symbols are defined. - if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined()) - report_fatal_error("unable to evaluate offset to undefined symbol '" + - Target.getSymA()->getSymbol().getName() + "'"); - if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined()) - report_fatal_error("unable to evaluate offset to undefined symbol '" + - Target.getSymB()->getSymbol().getName() + "'"); - - uint64_t Address = Target.getConstant(); - if (Target.getSymA()) - Address += getSymbolAddress(&Layout.getAssembler().getSymbolData( - Target.getSymA()->getSymbol()), Layout); - if (Target.getSymB()) - Address += getSymbolAddress(&Layout.getAssembler().getSymbolData( - Target.getSymB()->getSymbol()), Layout); - return Address; - } + const MCAsmLayout &Layout) const; - return getSectionAddress(SD->getFragment()->getParent()) + - Layout.getSymbolOffset(SD); - } uint64_t getFragmentAddress(const MCFragment *Fragment, const MCAsmLayout &Layout) const { return getSectionAddress(Fragment->getParent()) + @@ -158,18 +129,7 @@ } uint64_t getPaddingSize(const MCSectionData *SD, - const MCAsmLayout &Layout) const { - uint64_t EndAddr = getSectionAddress(SD) + Layout.getSectionAddressSize(SD); - unsigned Next = SD->getLayoutOrder() + 1; - if (Next >= Layout.getSectionOrder().size()) - return 0; - - const MCSectionData &NextSD = *Layout.getSectionOrder()[Next]; - if (NextSD.getSection().isVirtualSection()) - return 0; - return OffsetToAlignment(EndAddr, NextSD.getAlignment()); - } - + const MCAsmLayout &Layout) const; public: MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS, bool _IsLittleEndian) @@ -188,33 +148,7 @@ /// @} void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, - bool SubsectionsViaSymbols) { - uint32_t Flags = 0; - - if (SubsectionsViaSymbols) - Flags |= macho::HF_SubsectionsViaSymbols; - - // struct mach_header (28 bytes) or - // struct mach_header_64 (32 bytes) - - uint64_t Start = OS.tell(); - (void) Start; - - Write32(is64Bit() ? macho::HM_Object64 : macho::HM_Object32); - - Write32(TargetObjectWriter->getCPUType()); - Write32(TargetObjectWriter->getCPUSubtype()); - - Write32(macho::HFT_Object); - Write32(NumLoadCommands); - Write32(LoadCommandsSize); - Write32(Flags); - if (is64Bit()) - Write32(0); // reserved - - assert(OS.tell() - Start == - (is64Bit() ? macho::Header64Size : macho::Header32Size)); - } + bool SubsectionsViaSymbols); /// WriteSegmentLoadCommand - Write a segment load command. /// @@ -223,105 +157,15 @@ void WriteSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, uint64_t SectionDataStartOffset, - uint64_t SectionDataSize) { - // struct segment_command (56 bytes) or - // struct segment_command_64 (72 bytes) - - uint64_t Start = OS.tell(); - (void) Start; - - unsigned SegmentLoadCommandSize = - is64Bit() ? macho::SegmentLoadCommand64Size: - macho::SegmentLoadCommand32Size; - Write32(is64Bit() ? macho::LCT_Segment64 : macho::LCT_Segment); - Write32(SegmentLoadCommandSize + - NumSections * (is64Bit() ? macho::Section64Size : - macho::Section32Size)); - - WriteBytes("", 16); - if (is64Bit()) { - Write64(0); // vmaddr - Write64(VMSize); // vmsize - Write64(SectionDataStartOffset); // file offset - Write64(SectionDataSize); // file size - } else { - Write32(0); // vmaddr - Write32(VMSize); // vmsize - Write32(SectionDataStartOffset); // file offset - Write32(SectionDataSize); // file size - } - Write32(0x7); // maxprot - Write32(0x7); // initprot - Write32(NumSections); - Write32(0); // flags - - assert(OS.tell() - Start == SegmentLoadCommandSize); - } + uint64_t SectionDataSize); void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCSectionData &SD, uint64_t FileOffset, - uint64_t RelocationsStart, unsigned NumRelocations) { - uint64_t SectionSize = Layout.getSectionAddressSize(&SD); - - // The offset is unused for virtual sections. - if (SD.getSection().isVirtualSection()) { - assert(Layout.getSectionFileSize(&SD) == 0 && "Invalid file size!"); - FileOffset = 0; - } - - // struct section (68 bytes) or - // struct section_64 (80 bytes) - - uint64_t Start = OS.tell(); - (void) Start; - - const MCSectionMachO &Section = cast(SD.getSection()); - WriteBytes(Section.getSectionName(), 16); - WriteBytes(Section.getSegmentName(), 16); - if (is64Bit()) { - Write64(getSectionAddress(&SD)); // address - Write64(SectionSize); // size - } else { - Write32(getSectionAddress(&SD)); // address - Write32(SectionSize); // size - } - Write32(FileOffset); - - unsigned Flags = Section.getTypeAndAttributes(); - if (SD.hasInstructions()) - Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS; - - assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!"); - Write32(Log2_32(SD.getAlignment())); - Write32(NumRelocations ? RelocationsStart : 0); - Write32(NumRelocations); - Write32(Flags); - Write32(IndirectSymBase.lookup(&SD)); // reserved1 - Write32(Section.getStubSize()); // reserved2 - if (is64Bit()) - Write32(0); // reserved3 - - assert(OS.tell() - Start == (is64Bit() ? macho::Section64Size : - macho::Section32Size)); - } + uint64_t RelocationsStart, unsigned NumRelocations); void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, uint32_t StringTableOffset, - uint32_t StringTableSize) { - // struct symtab_command (24 bytes) - - uint64_t Start = OS.tell(); - (void) Start; - - Write32(macho::LCT_Symtab); - Write32(macho::SymtabLoadCommandSize); - Write32(SymbolOffset); - Write32(NumSymbols); - Write32(StringTableOffset); - Write32(StringTableSize); - - assert(OS.tell() - Start == macho::SymtabLoadCommandSize); - } + uint32_t StringTableSize); void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols, @@ -330,100 +174,9 @@ uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols, uint32_t IndirectSymbolOffset, - uint32_t NumIndirectSymbols) { - // struct dysymtab_command (80 bytes) - - uint64_t Start = OS.tell(); - (void) Start; - - Write32(macho::LCT_Dysymtab); - Write32(macho::DysymtabLoadCommandSize); - Write32(FirstLocalSymbol); - Write32(NumLocalSymbols); - Write32(FirstExternalSymbol); - Write32(NumExternalSymbols); - Write32(FirstUndefinedSymbol); - Write32(NumUndefinedSymbols); - Write32(0); // tocoff - Write32(0); // ntoc - Write32(0); // modtaboff - Write32(0); // nmodtab - Write32(0); // extrefsymoff - Write32(0); // nextrefsyms - Write32(IndirectSymbolOffset); - Write32(NumIndirectSymbols); - Write32(0); // extreloff - Write32(0); // nextrel - Write32(0); // locreloff - Write32(0); // nlocrel - - assert(OS.tell() - Start == macho::DysymtabLoadCommandSize); - } - - void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout) { - MCSymbolData &Data = *MSD.SymbolData; - const MCSymbol &Symbol = Data.getSymbol(); - uint8_t Type = 0; - uint16_t Flags = Data.getFlags(); - uint32_t Address = 0; - - // Set the N_TYPE bits. See . - // - // FIXME: Are the prebound or indirect fields possible here? - if (Symbol.isUndefined()) - Type = macho::STT_Undefined; - else if (Symbol.isAbsolute()) - Type = macho::STT_Absolute; - else - Type = macho::STT_Section; - - // FIXME: Set STAB bits. - - if (Data.isPrivateExtern()) - Type |= macho::STF_PrivateExtern; - - // Set external bit. - if (Data.isExternal() || Symbol.isUndefined()) - Type |= macho::STF_External; - - // Compute the symbol address. - if (Symbol.isDefined()) { - if (Symbol.isAbsolute()) { - Address = cast(Symbol.getVariableValue())->getValue(); - } else { - Address = getSymbolAddress(&Data, Layout); - } - } else if (Data.isCommon()) { - // Common symbols are encoded with the size in the address - // field, and their alignment in the flags. - Address = Data.getCommonSize(); - - // Common alignment is packed into the 'desc' bits. - if (unsigned Align = Data.getCommonAlignment()) { - unsigned Log2Size = Log2_32(Align); - assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); - if (Log2Size > 15) - report_fatal_error("invalid 'common' alignment '" + - Twine(Align) + "'"); - // FIXME: Keep this mask with the SymbolFlags enumeration. - Flags = (Flags & 0xF0FF) | (Log2Size << 8); - } - } + uint32_t NumIndirectSymbols); - // struct nlist (12 bytes) - - Write32(MSD.StringIndex); - Write8(Type); - Write8(MSD.SectionIndex); - - // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc' - // value. - Write16(Flags); - if (is64Bit()) - Write64(Address); - else - Write32(Address); - } + void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout); // FIXME: We really need to improve the relocation validation. Basically, we // want to implement a separate computation which evaluates the relocation @@ -446,650 +199,453 @@ void RecordX86_64Relocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) { - unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); - unsigned IsRIPRel = isFixupKindRIPRel(Fixup.getKind()); - unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); - - // See . - uint32_t FixupOffset = - Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); - uint32_t FixupAddress = - getFragmentAddress(Fragment, Layout) + Fixup.getOffset(); - int64_t Value = 0; - unsigned Index = 0; - unsigned IsExtern = 0; - unsigned Type = 0; - - Value = Target.getConstant(); - - if (IsPCRel) { - // Compensate for the relocation offset, Darwin x86_64 relocations only - // have the addend and appear to have attempted to define it to be the - // actual expression addend without the PCrel bias. However, instructions - // with data following the relocation are not accommodated for (see comment - // below regarding SIGNED{1,2,4}), so it isn't exactly that either. - Value += 1LL << Log2Size; - } - - if (Target.isAbsolute()) { // constant - // SymbolNum of 0 indicates the absolute section. - Type = macho::RIT_X86_64_Unsigned; - Index = 0; - - // FIXME: I believe this is broken, I don't think the linker can - // understand it. I think it would require a local relocation, but I'm not - // sure if that would work either. The official way to get an absolute - // PCrel relocation is to use an absolute symbol (which we don't support - // yet). - if (IsPCRel) { - IsExtern = 1; - Type = macho::RIT_X86_64_Branch; - } - } else if (Target.getSymB()) { // A - B + constant - const MCSymbol *A = &Target.getSymA()->getSymbol(); - MCSymbolData &A_SD = Asm.getSymbolData(*A); - const MCSymbolData *A_Base = Asm.getAtom(&A_SD); - - const MCSymbol *B = &Target.getSymB()->getSymbol(); - MCSymbolData &B_SD = Asm.getSymbolData(*B); - const MCSymbolData *B_Base = Asm.getAtom(&B_SD); - - // Neither symbol can be modified. - if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None || - Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None) - report_fatal_error("unsupported relocation of modified symbol"); - - // We don't support PCrel relocations of differences. Darwin 'as' doesn't - // implement most of these correctly. - if (IsPCRel) - report_fatal_error("unsupported pc-relative relocation of difference"); - - // The support for the situation where one or both of the symbols would - // require a local relocation is handled just like if the symbols were - // external. This is certainly used in the case of debug sections where - // the section has only temporary symbols and thus the symbols don't have - // base symbols. This is encoded using the section ordinal and - // non-extern relocation entries. - - // Darwin 'as' doesn't emit correct relocations for this (it ends up with - // a single SIGNED relocation); reject it for now. Except the case where - // both symbols don't have a base, equal but both NULL. - if (A_Base == B_Base && A_Base) - report_fatal_error("unsupported relocation with identical base"); - - Value += getSymbolAddress(&A_SD, Layout) - - (A_Base == NULL ? 0 : getSymbolAddress(A_Base, Layout)); - Value -= getSymbolAddress(&B_SD, Layout) - - (B_Base == NULL ? 0 : getSymbolAddress(B_Base, Layout)); - - if (A_Base) { - Index = A_Base->getIndex(); - IsExtern = 1; - } - else { - Index = A_SD.getFragment()->getParent()->getOrdinal() + 1; - IsExtern = 0; - } - Type = macho::RIT_X86_64_Unsigned; - - macho::RelocationEntry MRE; - MRE.Word0 = FixupOffset; - MRE.Word1 = ((Index << 0) | - (IsPCRel << 24) | - (Log2Size << 25) | - (IsExtern << 27) | - (Type << 28)); - Relocations[Fragment->getParent()].push_back(MRE); - - if (B_Base) { - Index = B_Base->getIndex(); - IsExtern = 1; - } - else { - Index = B_SD.getFragment()->getParent()->getOrdinal() + 1; - IsExtern = 0; - } - Type = macho::RIT_X86_64_Subtractor; - } else { - const MCSymbol *Symbol = &Target.getSymA()->getSymbol(); - MCSymbolData &SD = Asm.getSymbolData(*Symbol); - const MCSymbolData *Base = Asm.getAtom(&SD); - - // Relocations inside debug sections always use local relocations when - // possible. This seems to be done because the debugger doesn't fully - // understand x86_64 relocation entries, and expects to find values that - // have already been fixed up. - if (Symbol->isInSection()) { - const MCSectionMachO &Section = static_cast( - Fragment->getParent()->getSection()); - if (Section.hasAttribute(MCSectionMachO::S_ATTR_DEBUG)) - Base = 0; - } - - // x86_64 almost always uses external relocations, except when there is no - // symbol to use as a base address (a local symbol with no preceding - // non-local symbol). - if (Base) { - Index = Base->getIndex(); - IsExtern = 1; - - // Add the local offset, if needed. - if (Base != &SD) - Value += Layout.getSymbolOffset(&SD) - Layout.getSymbolOffset(Base); - } else if (Symbol->isInSection() && !Symbol->isVariable()) { - // The index is the section ordinal (1-based). - Index = SD.getFragment()->getParent()->getOrdinal() + 1; - IsExtern = 0; - Value += getSymbolAddress(&SD, Layout); - - if (IsPCRel) - Value -= FixupAddress + (1 << Log2Size); - } else if (Symbol->isVariable()) { - const MCExpr *Value = Symbol->getVariableValue(); - int64_t Res; - bool isAbs = Value->EvaluateAsAbsolute(Res, Layout, SectionAddress); - if (isAbs) { - FixedValue = Res; - return; - } else { - report_fatal_error("unsupported relocation of variable '" + - Symbol->getName() + "'"); - } - } else { - report_fatal_error("unsupported relocation of undefined symbol '" + - Symbol->getName() + "'"); - } - - MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind(); - if (IsPCRel) { - if (IsRIPRel) { - if (Modifier == MCSymbolRefExpr::VK_GOTPCREL) { - // x86_64 distinguishes movq foo at GOTPCREL so that the linker can - // rewrite the movq to an leaq at link time if the symbol ends up in - // the same linkage unit. - if (unsigned(Fixup.getKind()) == X86::reloc_riprel_4byte_movq_load) - Type = macho::RIT_X86_64_GOTLoad; - else - Type = macho::RIT_X86_64_GOT; - } else if (Modifier == MCSymbolRefExpr::VK_TLVP) { - Type = macho::RIT_X86_64_TLV; - } else if (Modifier != MCSymbolRefExpr::VK_None) { - report_fatal_error("unsupported symbol modifier in relocation"); - } else { - Type = macho::RIT_X86_64_Signed; - - // The Darwin x86_64 relocation format has a problem where it cannot - // encode an address (L + ) which is outside the atom - // containing L. Generally, this shouldn't occur but it does - // happen when we have a RIPrel instruction with data following the - // relocation entry (e.g., movb $012, L0(%rip)). Even with the PCrel - // adjustment Darwin x86_64 uses, the offset is still negative and - // the linker has no way to recognize this. - // - // To work around this, Darwin uses several special relocation types - // to indicate the offsets. However, the specification or - // implementation of these seems to also be incomplete; they should - // adjust the addend as well based on the actual encoded instruction - // (the additional bias), but instead appear to just look at the - // final offset. - switch (-(Target.getConstant() + (1LL << Log2Size))) { - case 1: Type = macho::RIT_X86_64_Signed1; break; - case 2: Type = macho::RIT_X86_64_Signed2; break; - case 4: Type = macho::RIT_X86_64_Signed4; break; - } - } - } else { - if (Modifier != MCSymbolRefExpr::VK_None) - report_fatal_error("unsupported symbol modifier in branch " - "relocation"); - - Type = macho::RIT_X86_64_Branch; - } - } else { - if (Modifier == MCSymbolRefExpr::VK_GOT) { - Type = macho::RIT_X86_64_GOT; - } else if (Modifier == MCSymbolRefExpr::VK_GOTPCREL) { - // GOTPCREL is allowed as a modifier on non-PCrel instructions, in - // which case all we do is set the PCrel bit in the relocation entry; - // this is used with exception handling, for example. The source is - // required to include any necessary offset directly. - Type = macho::RIT_X86_64_GOT; - IsPCRel = 1; - } else if (Modifier == MCSymbolRefExpr::VK_TLVP) { - report_fatal_error("TLVP symbol modifier should have been rip-rel"); - } else if (Modifier != MCSymbolRefExpr::VK_None) - report_fatal_error("unsupported symbol modifier in relocation"); - else - Type = macho::RIT_X86_64_Unsigned; - } - } - - // x86_64 always writes custom values into the fixups. - FixedValue = Value; - - // struct relocation_info (8 bytes) - macho::RelocationEntry MRE; - MRE.Word0 = FixupOffset; - MRE.Word1 = ((Index << 0) | - (IsPCRel << 24) | - (Log2Size << 25) | - (IsExtern << 27) | - (Type << 28)); - Relocations[Fragment->getParent()].push_back(MRE); - } + uint64_t &FixedValue); void RecordScatteredRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, unsigned Log2Size, - uint64_t &FixedValue) { - uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); - unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); - unsigned Type = macho::RIT_Vanilla; - - // See . - const MCSymbol *A = &Target.getSymA()->getSymbol(); - MCSymbolData *A_SD = &Asm.getSymbolData(*A); - - if (!A_SD->getFragment()) - report_fatal_error("symbol '" + A->getName() + - "' can not be undefined in a subtraction expression"); - - uint32_t Value = getSymbolAddress(A_SD, Layout); - uint64_t SecAddr = getSectionAddress(A_SD->getFragment()->getParent()); - FixedValue += SecAddr; - uint32_t Value2 = 0; - - if (const MCSymbolRefExpr *B = Target.getSymB()) { - MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol()); - - if (!B_SD->getFragment()) - report_fatal_error("symbol '" + B->getSymbol().getName() + - "' can not be undefined in a subtraction expression"); - - // Select the appropriate difference relocation type. - // - // Note that there is no longer any semantic difference between these two - // relocation types from the linkers point of view, this is done solely - // for pedantic compatibility with 'as'. - Type = A_SD->isExternal() ? (unsigned)macho::RIT_Difference : - (unsigned)macho::RIT_Generic_LocalDifference; - Value2 = getSymbolAddress(B_SD, Layout); - FixedValue -= getSectionAddress(B_SD->getFragment()->getParent()); - } - - // Relocations are written out in reverse order, so the PAIR comes first. - if (Type == macho::RIT_Difference || - Type == macho::RIT_Generic_LocalDifference) { - macho::RelocationEntry MRE; - MRE.Word0 = ((0 << 0) | - (macho::RIT_Pair << 24) | - (Log2Size << 28) | - (IsPCRel << 30) | - macho::RF_Scattered); - MRE.Word1 = Value2; - Relocations[Fragment->getParent()].push_back(MRE); - } - - macho::RelocationEntry MRE; - MRE.Word0 = ((FixupOffset << 0) | - (Type << 24) | - (Log2Size << 28) | - (IsPCRel << 30) | - macho::RF_Scattered); - MRE.Word1 = Value; - Relocations[Fragment->getParent()].push_back(MRE); - } + uint64_t &FixedValue); void RecordARMScatteredRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, unsigned Log2Size, - uint64_t &FixedValue) { - uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); - unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); - unsigned Type = macho::RIT_Vanilla; - - // See . - const MCSymbol *A = &Target.getSymA()->getSymbol(); - MCSymbolData *A_SD = &Asm.getSymbolData(*A); - - if (!A_SD->getFragment()) - report_fatal_error("symbol '" + A->getName() + - "' can not be undefined in a subtraction expression"); - - uint32_t Value = getSymbolAddress(A_SD, Layout); - uint64_t SecAddr = getSectionAddress(A_SD->getFragment()->getParent()); - FixedValue += SecAddr; - uint32_t Value2 = 0; - - if (const MCSymbolRefExpr *B = Target.getSymB()) { - MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol()); - - if (!B_SD->getFragment()) - report_fatal_error("symbol '" + B->getSymbol().getName() + - "' can not be undefined in a subtraction expression"); - - // Select the appropriate difference relocation type. - Type = macho::RIT_Difference; - Value2 = getSymbolAddress(B_SD, Layout); - FixedValue -= getSectionAddress(B_SD->getFragment()->getParent()); - } - - // Relocations are written out in reverse order, so the PAIR comes first. - if (Type == macho::RIT_Difference || - Type == macho::RIT_Generic_LocalDifference) { - macho::RelocationEntry MRE; - MRE.Word0 = ((0 << 0) | - (macho::RIT_Pair << 24) | - (Log2Size << 28) | - (IsPCRel << 30) | - macho::RF_Scattered); - MRE.Word1 = Value2; - Relocations[Fragment->getParent()].push_back(MRE); - } - - macho::RelocationEntry MRE; - MRE.Word0 = ((FixupOffset << 0) | - (Type << 24) | - (Log2Size << 28) | - (IsPCRel << 30) | - macho::RF_Scattered); - MRE.Word1 = Value; - Relocations[Fragment->getParent()].push_back(MRE); - } + uint64_t &FixedValue); void RecordARMMovwMovtRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) { - uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); - unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); - unsigned Type = macho::RIT_ARM_Half; + uint64_t &FixedValue); - // See . - const MCSymbol *A = &Target.getSymA()->getSymbol(); - MCSymbolData *A_SD = &Asm.getSymbolData(*A); + void RecordTLVPRelocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, MCValue Target, + uint64_t &FixedValue); - if (!A_SD->getFragment()) - report_fatal_error("symbol '" + A->getName() + - "' can not be undefined in a subtraction expression"); + static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType, + unsigned &Log2Size); - uint32_t Value = getSymbolAddress(A_SD, Layout); - uint32_t Value2 = 0; - uint64_t SecAddr = getSectionAddress(A_SD->getFragment()->getParent()); - FixedValue += SecAddr; + void RecordARMRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment *Fragment, const MCFixup &Fixup, + MCValue Target, uint64_t &FixedValue); - if (const MCSymbolRefExpr *B = Target.getSymB()) { - MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol()); + void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment *Fragment, const MCFixup &Fixup, + MCValue Target, uint64_t &FixedValue); - if (!B_SD->getFragment()) - report_fatal_error("symbol '" + B->getSymbol().getName() + - "' can not be undefined in a subtraction expression"); + void BindIndirectSymbols(MCAssembler &Asm); - // Select the appropriate difference relocation type. - Type = macho::RIT_ARM_HalfDifference; - Value2 = getSymbolAddress(B_SD, Layout); - FixedValue -= getSectionAddress(B_SD->getFragment()->getParent()); - } + /// ComputeSymbolTable - Compute the symbol table data + /// + /// \param StringTable [out] - The string table data. + /// \param StringIndexMap [out] - Map from symbol names to offsets in the + /// string table. + void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, + std::vector &LocalSymbolData, + std::vector &ExternalSymbolData, + std::vector &UndefinedSymbolData); - // Relocations are written out in reverse order, so the PAIR comes first. - // ARM_RELOC_HALF and ARM_RELOC_HALF_SECTDIFF abuse the r_length field: - // - // For these two r_type relocations they always have a pair following them - // and the r_length bits are used differently. The encoding of the - // r_length is as follows: - // low bit of r_length: - // 0 - :lower16: for movw instructions - // 1 - :upper16: for movt instructions - // high bit of r_length: - // 0 - arm instructions - // 1 - thumb instructions - // the other half of the relocated expression is in the following pair - // relocation entry in the the low 16 bits of r_address field. - unsigned ThumbBit = 0; - unsigned MovtBit = 0; - switch ((unsigned)Fixup.getKind()) { - default: break; - case ARM::fixup_arm_movt_hi16: - case ARM::fixup_arm_movt_hi16_pcrel: - MovtBit = 1; - break; - case ARM::fixup_t2_movt_hi16: - case ARM::fixup_t2_movt_hi16_pcrel: - MovtBit = 1; - // Fallthrough - case ARM::fixup_t2_movw_lo16: - case ARM::fixup_t2_movw_lo16_pcrel: - ThumbBit = 1; - break; - } + void computeSectionAddresses(const MCAssembler &Asm, + const MCAsmLayout &Layout); + void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout); - if (Type == macho::RIT_ARM_HalfDifference) { - uint32_t OtherHalf = MovtBit - ? (FixedValue & 0xffff) : ((FixedValue & 0xffff0000) >> 16); - - macho::RelocationEntry MRE; - MRE.Word0 = ((OtherHalf << 0) | - (macho::RIT_Pair << 24) | - (MovtBit << 28) | - (ThumbBit << 29) | - (IsPCRel << 30) | - macho::RF_Scattered); - MRE.Word1 = Value2; - Relocations[Fragment->getParent()].push_back(MRE); - } + virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const; - macho::RelocationEntry MRE; - MRE.Word0 = ((FixupOffset << 0) | - (Type << 24) | - (MovtBit << 28) | - (ThumbBit << 29) | - (IsPCRel << 30) | - macho::RF_Scattered); - MRE.Word1 = Value; - Relocations[Fragment->getParent()].push_back(MRE); - } + void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); +}; - void RecordTLVPRelocation(const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) { - assert(Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP && - !is64Bit() && - "Should only be called with a 32-bit TLVP relocation!"); - - unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); - uint32_t Value = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); - unsigned IsPCRel = 0; - - // Get the symbol data. - MCSymbolData *SD_A = &Asm.getSymbolData(Target.getSymA()->getSymbol()); - unsigned Index = SD_A->getIndex(); - - // We're only going to have a second symbol in pic mode and it'll be a - // subtraction from the picbase. For 32-bit pic the addend is the difference - // between the picbase and the next address. For 32-bit static the addend - // is zero. - if (Target.getSymB()) { - // If this is a subtraction then we're pcrel. - uint32_t FixupAddress = - getFragmentAddress(Fragment, Layout) + Fixup.getOffset(); - MCSymbolData *SD_B = &Asm.getSymbolData(Target.getSymB()->getSymbol()); - IsPCRel = 1; - FixedValue = (FixupAddress - getSymbolAddress(SD_B, Layout) + - Target.getConstant()); - FixedValue += 1ULL << Log2Size; - } else { - FixedValue = 0; - } +} // end anonymous namespace - // struct relocation_info (8 bytes) - macho::RelocationEntry MRE; - MRE.Word0 = Value; - MRE.Word1 = ((Index << 0) | - (IsPCRel << 24) | - (Log2Size << 25) | - (1 << 27) | // Extern - (macho::RIT_Generic_TLV << 28)); // Type - Relocations[Fragment->getParent()].push_back(MRE); +uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD, + const MCAsmLayout &Layout) const { + const MCSymbol &S = SD->getSymbol(); + + // If this is a variable, then recursively evaluate now. + if (S.isVariable()) { + MCValue Target; + if (!S.getVariableValue()->EvaluateAsRelocatable(Target, Layout)) + report_fatal_error("unable to evaluate offset for variable '" + + S.getName() + "'"); + + // Verify that any used symbols are defined. + if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined()) + report_fatal_error("unable to evaluate offset to undefined symbol '" + + Target.getSymA()->getSymbol().getName() + "'"); + if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined()) + report_fatal_error("unable to evaluate offset to undefined symbol '" + + Target.getSymB()->getSymbol().getName() + "'"); + + uint64_t Address = Target.getConstant(); + if (Target.getSymA()) + Address += getSymbolAddress(&Layout.getAssembler().getSymbolData( + Target.getSymA()->getSymbol()), Layout); + if (Target.getSymB()) + Address += getSymbolAddress(&Layout.getAssembler().getSymbolData( + Target.getSymB()->getSymbol()), Layout); + return Address; } - static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType, - unsigned &Log2Size) { - RelocType = unsigned(macho::RIT_Vanilla); - Log2Size = ~0U; + return getSectionAddress(SD->getFragment()->getParent()) + + Layout.getSymbolOffset(SD); +} - switch (Kind) { - default: - return false; +uint64_t MachObjectWriter::getPaddingSize(const MCSectionData *SD, + const MCAsmLayout &Layout) const { + uint64_t EndAddr = getSectionAddress(SD) + Layout.getSectionAddressSize(SD); + unsigned Next = SD->getLayoutOrder() + 1; + if (Next >= Layout.getSectionOrder().size()) + return 0; + + const MCSectionData &NextSD = *Layout.getSectionOrder()[Next]; + if (NextSD.getSection().isVirtualSection()) + return 0; + return OffsetToAlignment(EndAddr, NextSD.getAlignment()); +} - case FK_Data_1: - Log2Size = llvm::Log2_32(1); - return true; - case FK_Data_2: - Log2Size = llvm::Log2_32(2); - return true; - case FK_Data_4: - Log2Size = llvm::Log2_32(4); - return true; - case FK_Data_8: - Log2Size = llvm::Log2_32(8); - return true; +void MachObjectWriter::WriteHeader(unsigned NumLoadCommands, + unsigned LoadCommandsSize, + bool SubsectionsViaSymbols) { + uint32_t Flags = 0; + + if (SubsectionsViaSymbols) + Flags |= macho::HF_SubsectionsViaSymbols; + + // struct mach_header (28 bytes) or + // struct mach_header_64 (32 bytes) + + uint64_t Start = OS.tell(); + (void) Start; + + Write32(is64Bit() ? macho::HM_Object64 : macho::HM_Object32); + + Write32(TargetObjectWriter->getCPUType()); + Write32(TargetObjectWriter->getCPUSubtype()); + + Write32(macho::HFT_Object); + Write32(NumLoadCommands); + Write32(LoadCommandsSize); + Write32(Flags); + if (is64Bit()) + Write32(0); // reserved - // Handle 24-bit branch kinds. - case ARM::fixup_arm_ldst_pcrel_12: - case ARM::fixup_arm_pcrel_10: - case ARM::fixup_arm_adr_pcrel_12: - case ARM::fixup_arm_condbranch: - case ARM::fixup_arm_uncondbranch: - RelocType = unsigned(macho::RIT_ARM_Branch24Bit); - // Report as 'long', even though that is not quite accurate. - Log2Size = llvm::Log2_32(4); - return true; + assert(OS.tell() - Start == + (is64Bit() ? macho::Header64Size : macho::Header32Size)); +} - // Handle Thumb branches. - case ARM::fixup_arm_thumb_br: - RelocType = unsigned(macho::RIT_ARM_ThumbBranch22Bit); - Log2Size = llvm::Log2_32(2); - return true; - - case ARM::fixup_arm_thumb_bl: - case ARM::fixup_arm_thumb_blx: - RelocType = unsigned(macho::RIT_ARM_ThumbBranch22Bit); - Log2Size = llvm::Log2_32(4); - return true; +/// WriteSegmentLoadCommand - Write a segment load command. +/// +/// \arg NumSections - The number of sections in this segment. +/// \arg SectionDataSize - The total size of the sections. +void MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections, + uint64_t VMSize, + uint64_t SectionDataStartOffset, + uint64_t SectionDataSize) { + // struct segment_command (56 bytes) or + // struct segment_command_64 (72 bytes) + + uint64_t Start = OS.tell(); + (void) Start; + + unsigned SegmentLoadCommandSize = + is64Bit() ? macho::SegmentLoadCommand64Size: + macho::SegmentLoadCommand32Size; + Write32(is64Bit() ? macho::LCT_Segment64 : macho::LCT_Segment); + Write32(SegmentLoadCommandSize + + NumSections * (is64Bit() ? macho::Section64Size : + macho::Section32Size)); + + WriteBytes("", 16); + if (is64Bit()) { + Write64(0); // vmaddr + Write64(VMSize); // vmsize + Write64(SectionDataStartOffset); // file offset + Write64(SectionDataSize); // file size + } else { + Write32(0); // vmaddr + Write32(VMSize); // vmsize + Write32(SectionDataStartOffset); // file offset + Write32(SectionDataSize); // file size + } + Write32(0x7); // maxprot + Write32(0x7); // initprot + Write32(NumSections); + Write32(0); // flags - case ARM::fixup_arm_movt_hi16: - case ARM::fixup_arm_movt_hi16_pcrel: - case ARM::fixup_t2_movt_hi16: - case ARM::fixup_t2_movt_hi16_pcrel: - RelocType = unsigned(macho::RIT_ARM_HalfDifference); - // Report as 'long', even though that is not quite accurate. - Log2Size = llvm::Log2_32(4); - return true; + assert(OS.tell() - Start == SegmentLoadCommandSize); +} - case ARM::fixup_arm_movw_lo16: - case ARM::fixup_arm_movw_lo16_pcrel: - case ARM::fixup_t2_movw_lo16: - case ARM::fixup_t2_movw_lo16_pcrel: - RelocType = unsigned(macho::RIT_ARM_Half); - // Report as 'long', even though that is not quite accurate. - Log2Size = llvm::Log2_32(4); - return true; +void MachObjectWriter::WriteSection(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCSectionData &SD, + uint64_t FileOffset, + uint64_t RelocationsStart, + unsigned NumRelocations) { + uint64_t SectionSize = Layout.getSectionAddressSize(&SD); + + // The offset is unused for virtual sections. + if (SD.getSection().isVirtualSection()) { + assert(Layout.getSectionFileSize(&SD) == 0 && "Invalid file size!"); + FileOffset = 0; + } + + // struct section (68 bytes) or + // struct section_64 (80 bytes) + + uint64_t Start = OS.tell(); + (void) Start; + + const MCSectionMachO &Section = cast(SD.getSection()); + WriteBytes(Section.getSectionName(), 16); + WriteBytes(Section.getSegmentName(), 16); + if (is64Bit()) { + Write64(getSectionAddress(&SD)); // address + Write64(SectionSize); // size + } else { + Write32(getSectionAddress(&SD)); // address + Write32(SectionSize); // size + } + Write32(FileOffset); + + unsigned Flags = Section.getTypeAndAttributes(); + if (SD.hasInstructions()) + Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS; + + assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!"); + Write32(Log2_32(SD.getAlignment())); + Write32(NumRelocations ? RelocationsStart : 0); + Write32(NumRelocations); + Write32(Flags); + Write32(IndirectSymBase.lookup(&SD)); // reserved1 + Write32(Section.getStubSize()); // reserved2 + if (is64Bit()) + Write32(0); // reserved3 + + assert(OS.tell() - Start == (is64Bit() ? macho::Section64Size : + macho::Section32Size)); +} + +void MachObjectWriter::WriteSymtabLoadCommand(uint32_t SymbolOffset, + uint32_t NumSymbols, + uint32_t StringTableOffset, + uint32_t StringTableSize) { + // struct symtab_command (24 bytes) + + uint64_t Start = OS.tell(); + (void) Start; + + Write32(macho::LCT_Symtab); + Write32(macho::SymtabLoadCommandSize); + Write32(SymbolOffset); + Write32(NumSymbols); + Write32(StringTableOffset); + Write32(StringTableSize); + + assert(OS.tell() - Start == macho::SymtabLoadCommandSize); +} + +void MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, + uint32_t NumLocalSymbols, + uint32_t FirstExternalSymbol, + uint32_t NumExternalSymbols, + uint32_t FirstUndefinedSymbol, + uint32_t NumUndefinedSymbols, + uint32_t IndirectSymbolOffset, + uint32_t NumIndirectSymbols) { + // struct dysymtab_command (80 bytes) + + uint64_t Start = OS.tell(); + (void) Start; + + Write32(macho::LCT_Dysymtab); + Write32(macho::DysymtabLoadCommandSize); + Write32(FirstLocalSymbol); + Write32(NumLocalSymbols); + Write32(FirstExternalSymbol); + Write32(NumExternalSymbols); + Write32(FirstUndefinedSymbol); + Write32(NumUndefinedSymbols); + Write32(0); // tocoff + Write32(0); // ntoc + Write32(0); // modtaboff + Write32(0); // nmodtab + Write32(0); // extrefsymoff + Write32(0); // nextrefsyms + Write32(IndirectSymbolOffset); + Write32(NumIndirectSymbols); + Write32(0); // extreloff + Write32(0); // nextrel + Write32(0); // locreloff + Write32(0); // nlocrel + + assert(OS.tell() - Start == macho::DysymtabLoadCommandSize); +} + +void MachObjectWriter::WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout) { + MCSymbolData &Data = *MSD.SymbolData; + const MCSymbol &Symbol = Data.getSymbol(); + uint8_t Type = 0; + uint16_t Flags = Data.getFlags(); + uint32_t Address = 0; + + // Set the N_TYPE bits. See . + // + // FIXME: Are the prebound or indirect fields possible here? + if (Symbol.isUndefined()) + Type = macho::STT_Undefined; + else if (Symbol.isAbsolute()) + Type = macho::STT_Absolute; + else + Type = macho::STT_Section; + + // FIXME: Set STAB bits. + + if (Data.isPrivateExtern()) + Type |= macho::STF_PrivateExtern; + + // Set external bit. + if (Data.isExternal() || Symbol.isUndefined()) + Type |= macho::STF_External; + + // Compute the symbol address. + if (Symbol.isDefined()) { + if (Symbol.isAbsolute()) { + Address = cast(Symbol.getVariableValue())->getValue(); + } else { + Address = getSymbolAddress(&Data, Layout); } - } - void RecordARMRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCFixup &Fixup, - MCValue Target, uint64_t &FixedValue) { - unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); - unsigned Log2Size; - unsigned RelocType = macho::RIT_Vanilla; - if (!getARMFixupKindMachOInfo(Fixup.getKind(), RelocType, Log2Size)) { - report_fatal_error("unknown ARM fixup kind!"); - return; - } - - // If this is a difference or a defined symbol plus an offset, then we need - // a scattered relocation entry. Differences always require scattered - // relocations. - if (Target.getSymB()) { - if (RelocType == macho::RIT_ARM_Half || - RelocType == macho::RIT_ARM_HalfDifference) - return RecordARMMovwMovtRelocation(Asm, Layout, Fragment, Fixup, - Target, FixedValue); - return RecordARMScatteredRelocation(Asm, Layout, Fragment, Fixup, - Target, Log2Size, FixedValue); + } else if (Data.isCommon()) { + // Common symbols are encoded with the size in the address + // field, and their alignment in the flags. + Address = Data.getCommonSize(); + + // Common alignment is packed into the 'desc' bits. + if (unsigned Align = Data.getCommonAlignment()) { + unsigned Log2Size = Log2_32(Align); + assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); + if (Log2Size > 15) + report_fatal_error("invalid 'common' alignment '" + + Twine(Align) + "'"); + // FIXME: Keep this mask with the SymbolFlags enumeration. + Flags = (Flags & 0xF0FF) | (Log2Size << 8); } + } - // Get the symbol data, if any. - MCSymbolData *SD = 0; - if (Target.getSymA()) - SD = &Asm.getSymbolData(Target.getSymA()->getSymbol()); + // struct nlist (12 bytes) + + Write32(MSD.StringIndex); + Write8(Type); + Write8(MSD.SectionIndex); + + // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc' + // value. + Write16(Flags); + if (is64Bit()) + Write64(Address); + else + Write32(Address); +} - // FIXME: For other platforms, we need to use scattered relocations for - // internal relocations with offsets. If this is an internal relocation - // with an offset, it also needs a scattered relocation entry. - // - // Is this right for ARM? - uint32_t Offset = Target.getConstant(); - if (IsPCRel && RelocType == macho::RIT_Vanilla) - Offset += 1 << Log2Size; - if (Offset && SD && !doesSymbolRequireExternRelocation(SD)) - return RecordARMScatteredRelocation(Asm, Layout, Fragment, Fixup, Target, - Log2Size, FixedValue); - - // See . - uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); - unsigned Index = 0; - unsigned IsExtern = 0; - unsigned Type = 0; - - if (Target.isAbsolute()) { // constant - // FIXME! - report_fatal_error("FIXME: relocations to absolute targets " - "not yet implemented"); - } else { - // Resolve constant variables. - if (SD->getSymbol().isVariable()) { - int64_t Res; - if (SD->getSymbol().getVariableValue()->EvaluateAsAbsolute( - Res, Layout, SectionAddress)) { - FixedValue = Res; - return; - } - } +void MachObjectWriter::RecordX86_64Relocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, + MCValue Target, + uint64_t &FixedValue) { + unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); + unsigned IsRIPRel = isFixupKindRIPRel(Fixup.getKind()); + unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); + + // See . + uint32_t FixupOffset = + Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); + uint32_t FixupAddress = + getFragmentAddress(Fragment, Layout) + Fixup.getOffset(); + int64_t Value = 0; + unsigned Index = 0; + unsigned IsExtern = 0; + unsigned Type = 0; + + Value = Target.getConstant(); + + if (IsPCRel) { + // Compensate for the relocation offset, Darwin x86_64 relocations only have + // the addend and appear to have attempted to define it to be the actual + // expression addend without the PCrel bias. However, instructions with data + // following the relocation are not accommodated for (see comment below + // regarding SIGNED{1,2,4}), so it isn't exactly that either. + Value += 1LL << Log2Size; + } + + if (Target.isAbsolute()) { // constant + // SymbolNum of 0 indicates the absolute section. + Type = macho::RIT_X86_64_Unsigned; + Index = 0; - // Check whether we need an external or internal relocation. - if (doesSymbolRequireExternRelocation(SD)) { - IsExtern = 1; - Index = SD->getIndex(); - // For external relocations, make sure to offset the fixup value to - // compensate for the addend of the symbol address, if it was - // undefined. This occurs with weak definitions, for example. - if (!SD->Symbol->isUndefined()) - FixedValue -= Layout.getSymbolOffset(SD); - } else { - // The index is the section ordinal (1-based). - const MCSectionData &SymSD = Asm.getSectionData( - SD->getSymbol().getSection()); - Index = SymSD.getOrdinal() + 1; - FixedValue += getSectionAddress(&SymSD); - } - if (IsPCRel) - FixedValue -= getSectionAddress(Fragment->getParent()); + // FIXME: I believe this is broken, I don't think the linker can understand + // it. I think it would require a local relocation, but I'm not sure if that + // would work either. The official way to get an absolute PCrel relocation + // is to use an absolute symbol (which we don't support yet). + if (IsPCRel) { + IsExtern = 1; + Type = macho::RIT_X86_64_Branch; + } + } else if (Target.getSymB()) { // A - B + constant + const MCSymbol *A = &Target.getSymA()->getSymbol(); + MCSymbolData &A_SD = Asm.getSymbolData(*A); + const MCSymbolData *A_Base = Asm.getAtom(&A_SD); - // The type is determined by the fixup kind. - Type = RelocType; + const MCSymbol *B = &Target.getSymB()->getSymbol(); + MCSymbolData &B_SD = Asm.getSymbolData(*B); + const MCSymbolData *B_Base = Asm.getAtom(&B_SD); + + // Neither symbol can be modified. + if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None || + Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None) + report_fatal_error("unsupported relocation of modified symbol"); + + // We don't support PCrel relocations of differences. Darwin 'as' doesn't + // implement most of these correctly. + if (IsPCRel) + report_fatal_error("unsupported pc-relative relocation of difference"); + + // The support for the situation where one or both of the symbols would + // require a local relocation is handled just like if the symbols were + // external. This is certainly used in the case of debug sections where the + // section has only temporary symbols and thus the symbols don't have base + // symbols. This is encoded using the section ordinal and non-extern + // relocation entries. + + // Darwin 'as' doesn't emit correct relocations for this (it ends up with a + // single SIGNED relocation); reject it for now. Except the case where both + // symbols don't have a base, equal but both NULL. + if (A_Base == B_Base && A_Base) + report_fatal_error("unsupported relocation with identical base"); + + Value += getSymbolAddress(&A_SD, Layout) - + (A_Base == NULL ? 0 : getSymbolAddress(A_Base, Layout)); + Value -= getSymbolAddress(&B_SD, Layout) - + (B_Base == NULL ? 0 : getSymbolAddress(B_Base, Layout)); + + if (A_Base) { + Index = A_Base->getIndex(); + IsExtern = 1; + } + else { + Index = A_SD.getFragment()->getParent()->getOrdinal() + 1; + IsExtern = 0; } + Type = macho::RIT_X86_64_Unsigned; - // struct relocation_info (8 bytes) macho::RelocationEntry MRE; MRE.Word0 = FixupOffset; MRE.Word1 = ((Index << 0) | @@ -1098,523 +654,1088 @@ (IsExtern << 27) | (Type << 28)); Relocations[Fragment->getParent()].push_back(MRE); - } - void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCFixup &Fixup, - MCValue Target, uint64_t &FixedValue) { - // FIXME: These needs to be factored into the target Mach-O writer. - if (isARM()) { - RecordARMRelocation(Asm, Layout, Fragment, Fixup, Target, FixedValue); - return; - } - if (is64Bit()) { - RecordX86_64Relocation(Asm, Layout, Fragment, Fixup, Target, FixedValue); - return; - } - - unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); - unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); - - // If this is a 32-bit TLVP reloc it's handled a bit differently. - if (Target.getSymA() && - Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP) { - RecordTLVPRelocation(Asm, Layout, Fragment, Fixup, Target, FixedValue); - return; - } - - // If this is a difference or a defined symbol plus an offset, then we need - // a scattered relocation entry. - // Differences always require scattered relocations. - if (Target.getSymB()) - return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup, - Target, Log2Size, FixedValue); - - // Get the symbol data, if any. - MCSymbolData *SD = 0; - if (Target.getSymA()) - SD = &Asm.getSymbolData(Target.getSymA()->getSymbol()); + if (B_Base) { + Index = B_Base->getIndex(); + IsExtern = 1; + } + else { + Index = B_SD.getFragment()->getParent()->getOrdinal() + 1; + IsExtern = 0; + } + Type = macho::RIT_X86_64_Subtractor; + } else { + const MCSymbol *Symbol = &Target.getSymA()->getSymbol(); + MCSymbolData &SD = Asm.getSymbolData(*Symbol); + const MCSymbolData *Base = Asm.getAtom(&SD); + + // Relocations inside debug sections always use local relocations when + // possible. This seems to be done because the debugger doesn't fully + // understand x86_64 relocation entries, and expects to find values that + // have already been fixed up. + if (Symbol->isInSection()) { + const MCSectionMachO &Section = static_cast( + Fragment->getParent()->getSection()); + if (Section.hasAttribute(MCSectionMachO::S_ATTR_DEBUG)) + Base = 0; + } + + // x86_64 almost always uses external relocations, except when there is no + // symbol to use as a base address (a local symbol with no preceding + // non-local symbol). + if (Base) { + Index = Base->getIndex(); + IsExtern = 1; + + // Add the local offset, if needed. + if (Base != &SD) + Value += Layout.getSymbolOffset(&SD) - Layout.getSymbolOffset(Base); + } else if (Symbol->isInSection() && !Symbol->isVariable()) { + // The index is the section ordinal (1-based). + Index = SD.getFragment()->getParent()->getOrdinal() + 1; + IsExtern = 0; + Value += getSymbolAddress(&SD, Layout); - // If this is an internal relocation with an offset, it also needs a - // scattered relocation entry. - uint32_t Offset = Target.getConstant(); - if (IsPCRel) - Offset += 1 << Log2Size; - if (Offset && SD && !doesSymbolRequireExternRelocation(SD)) - return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup, - Target, Log2Size, FixedValue); - - // See . - uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); - unsigned Index = 0; - unsigned IsExtern = 0; - unsigned Type = 0; - - if (Target.isAbsolute()) { // constant - // SymbolNum of 0 indicates the absolute section. - // - // FIXME: Currently, these are never generated (see code below). I cannot - // find a case where they are actually emitted. - Type = macho::RIT_Vanilla; - } else { - // Resolve constant variables. - if (SD->getSymbol().isVariable()) { - int64_t Res; - if (SD->getSymbol().getVariableValue()->EvaluateAsAbsolute( - Res, Layout, SectionAddress)) { - FixedValue = Res; - return; - } + if (IsPCRel) + Value -= FixupAddress + (1 << Log2Size); + } else if (Symbol->isVariable()) { + const MCExpr *Value = Symbol->getVariableValue(); + int64_t Res; + bool isAbs = Value->EvaluateAsAbsolute(Res, Layout, SectionAddress); + if (isAbs) { + FixedValue = Res; + return; + } else { + report_fatal_error("unsupported relocation of variable '" + + Symbol->getName() + "'"); } + } else { + report_fatal_error("unsupported relocation of undefined symbol '" + + Symbol->getName() + "'"); + } - // Check whether we need an external or internal relocation. - if (doesSymbolRequireExternRelocation(SD)) { - IsExtern = 1; - Index = SD->getIndex(); - // For external relocations, make sure to offset the fixup value to - // compensate for the addend of the symbol address, if it was - // undefined. This occurs with weak definitions, for example. - if (!SD->Symbol->isUndefined()) - FixedValue -= Layout.getSymbolOffset(SD); + MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind(); + if (IsPCRel) { + if (IsRIPRel) { + if (Modifier == MCSymbolRefExpr::VK_GOTPCREL) { + // x86_64 distinguishes movq foo at GOTPCREL so that the linker can + // rewrite the movq to an leaq at link time if the symbol ends up in + // the same linkage unit. + if (unsigned(Fixup.getKind()) == X86::reloc_riprel_4byte_movq_load) + Type = macho::RIT_X86_64_GOTLoad; + else + Type = macho::RIT_X86_64_GOT; + } else if (Modifier == MCSymbolRefExpr::VK_TLVP) { + Type = macho::RIT_X86_64_TLV; + } else if (Modifier != MCSymbolRefExpr::VK_None) { + report_fatal_error("unsupported symbol modifier in relocation"); + } else { + Type = macho::RIT_X86_64_Signed; + + // The Darwin x86_64 relocation format has a problem where it cannot + // encode an address (L + ) which is outside the atom + // containing L. Generally, this shouldn't occur but it does + // happen when we have a RIPrel instruction with data following the + // relocation entry (e.g., movb $012, L0(%rip)). Even with the PCrel + // adjustment Darwin x86_64 uses, the offset is still negative and the + // linker has no way to recognize this. + // + // To work around this, Darwin uses several special relocation types + // to indicate the offsets. However, the specification or + // implementation of these seems to also be incomplete; they should + // adjust the addend as well based on the actual encoded instruction + // (the additional bias), but instead appear to just look at the final + // offset. + switch (-(Target.getConstant() + (1LL << Log2Size))) { + case 1: Type = macho::RIT_X86_64_Signed1; break; + case 2: Type = macho::RIT_X86_64_Signed2; break; + case 4: Type = macho::RIT_X86_64_Signed4; break; + } + } } else { - // The index is the section ordinal (1-based). - const MCSectionData &SymSD = Asm.getSectionData( - SD->getSymbol().getSection()); - Index = SymSD.getOrdinal() + 1; - FixedValue += getSectionAddress(&SymSD); - } - if (IsPCRel) - FixedValue -= getSectionAddress(Fragment->getParent()); + if (Modifier != MCSymbolRefExpr::VK_None) + report_fatal_error("unsupported symbol modifier in branch " + "relocation"); - Type = macho::RIT_Vanilla; + Type = macho::RIT_X86_64_Branch; + } + } else { + if (Modifier == MCSymbolRefExpr::VK_GOT) { + Type = macho::RIT_X86_64_GOT; + } else if (Modifier == MCSymbolRefExpr::VK_GOTPCREL) { + // GOTPCREL is allowed as a modifier on non-PCrel instructions, in which + // case all we do is set the PCrel bit in the relocation entry; this is + // used with exception handling, for example. The source is required to + // include any necessary offset directly. + Type = macho::RIT_X86_64_GOT; + IsPCRel = 1; + } else if (Modifier == MCSymbolRefExpr::VK_TLVP) { + report_fatal_error("TLVP symbol modifier should have been rip-rel"); + } else if (Modifier != MCSymbolRefExpr::VK_None) + report_fatal_error("unsupported symbol modifier in relocation"); + else + Type = macho::RIT_X86_64_Unsigned; } + } + + // x86_64 always writes custom values into the fixups. + FixedValue = Value; + + // struct relocation_info (8 bytes) + macho::RelocationEntry MRE; + MRE.Word0 = FixupOffset; + MRE.Word1 = ((Index << 0) | + (IsPCRel << 24) | + (Log2Size << 25) | + (IsExtern << 27) | + (Type << 28)); + Relocations[Fragment->getParent()].push_back(MRE); +} - // struct relocation_info (8 bytes) +void MachObjectWriter::RecordScatteredRelocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, + MCValue Target, + unsigned Log2Size, + uint64_t &FixedValue) { + uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); + unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); + unsigned Type = macho::RIT_Vanilla; + + // See . + const MCSymbol *A = &Target.getSymA()->getSymbol(); + MCSymbolData *A_SD = &Asm.getSymbolData(*A); + + if (!A_SD->getFragment()) + report_fatal_error("symbol '" + A->getName() + + "' can not be undefined in a subtraction expression"); + + uint32_t Value = getSymbolAddress(A_SD, Layout); + uint64_t SecAddr = getSectionAddress(A_SD->getFragment()->getParent()); + FixedValue += SecAddr; + uint32_t Value2 = 0; + + if (const MCSymbolRefExpr *B = Target.getSymB()) { + MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol()); + + if (!B_SD->getFragment()) + report_fatal_error("symbol '" + B->getSymbol().getName() + + "' can not be undefined in a subtraction expression"); + + // Select the appropriate difference relocation type. + // + // Note that there is no longer any semantic difference between these two + // relocation types from the linkers point of view, this is done solely for + // pedantic compatibility with 'as'. + Type = A_SD->isExternal() ? (unsigned)macho::RIT_Difference : + (unsigned)macho::RIT_Generic_LocalDifference; + Value2 = getSymbolAddress(B_SD, Layout); + FixedValue -= getSectionAddress(B_SD->getFragment()->getParent()); + } + + // Relocations are written out in reverse order, so the PAIR comes first. + if (Type == macho::RIT_Difference || + Type == macho::RIT_Generic_LocalDifference) { macho::RelocationEntry MRE; - MRE.Word0 = FixupOffset; - MRE.Word1 = ((Index << 0) | - (IsPCRel << 24) | - (Log2Size << 25) | - (IsExtern << 27) | - (Type << 28)); + MRE.Word0 = ((0 << 0) | + (macho::RIT_Pair << 24) | + (Log2Size << 28) | + (IsPCRel << 30) | + macho::RF_Scattered); + MRE.Word1 = Value2; Relocations[Fragment->getParent()].push_back(MRE); } - void BindIndirectSymbols(MCAssembler &Asm) { - // This is the point where 'as' creates actual symbols for indirect symbols - // (in the following two passes). It would be easier for us to do this - // sooner when we see the attribute, but that makes getting the order in the - // symbol table much more complicated than it is worth. - // - // FIXME: Revisit this when the dust settles. + macho::RelocationEntry MRE; + MRE.Word0 = ((FixupOffset << 0) | + (Type << 24) | + (Log2Size << 28) | + (IsPCRel << 30) | + macho::RF_Scattered); + MRE.Word1 = Value; + Relocations[Fragment->getParent()].push_back(MRE); +} - // Bind non lazy symbol pointers first. - unsigned IndirectIndex = 0; - for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), - ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) { - const MCSectionMachO &Section = - cast(it->SectionData->getSection()); +void MachObjectWriter::RecordARMScatteredRelocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, + MCValue Target, + unsigned Log2Size, + uint64_t &FixedValue) { + uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); + unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); + unsigned Type = macho::RIT_Vanilla; + + // See . + const MCSymbol *A = &Target.getSymA()->getSymbol(); + MCSymbolData *A_SD = &Asm.getSymbolData(*A); + + if (!A_SD->getFragment()) + report_fatal_error("symbol '" + A->getName() + + "' can not be undefined in a subtraction expression"); + + uint32_t Value = getSymbolAddress(A_SD, Layout); + uint64_t SecAddr = getSectionAddress(A_SD->getFragment()->getParent()); + FixedValue += SecAddr; + uint32_t Value2 = 0; + + if (const MCSymbolRefExpr *B = Target.getSymB()) { + MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol()); + + if (!B_SD->getFragment()) + report_fatal_error("symbol '" + B->getSymbol().getName() + + "' can not be undefined in a subtraction expression"); + + // Select the appropriate difference relocation type. + Type = macho::RIT_Difference; + Value2 = getSymbolAddress(B_SD, Layout); + FixedValue -= getSectionAddress(B_SD->getFragment()->getParent()); + } + + // Relocations are written out in reverse order, so the PAIR comes first. + if (Type == macho::RIT_Difference || + Type == macho::RIT_Generic_LocalDifference) { + macho::RelocationEntry MRE; + MRE.Word0 = ((0 << 0) | + (macho::RIT_Pair << 24) | + (Log2Size << 28) | + (IsPCRel << 30) | + macho::RF_Scattered); + MRE.Word1 = Value2; + Relocations[Fragment->getParent()].push_back(MRE); + } - if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) - continue; + macho::RelocationEntry MRE; + MRE.Word0 = ((FixupOffset << 0) | + (Type << 24) | + (Log2Size << 28) | + (IsPCRel << 30) | + macho::RF_Scattered); + MRE.Word1 = Value; + Relocations[Fragment->getParent()].push_back(MRE); +} - // Initialize the section indirect symbol base, if necessary. - if (!IndirectSymBase.count(it->SectionData)) - IndirectSymBase[it->SectionData] = IndirectIndex; +void MachObjectWriter::RecordARMMovwMovtRelocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, + MCValue Target, + uint64_t &FixedValue) { + uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); + unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); + unsigned Type = macho::RIT_ARM_Half; + + // See . + const MCSymbol *A = &Target.getSymA()->getSymbol(); + MCSymbolData *A_SD = &Asm.getSymbolData(*A); + + if (!A_SD->getFragment()) + report_fatal_error("symbol '" + A->getName() + + "' can not be undefined in a subtraction expression"); + + uint32_t Value = getSymbolAddress(A_SD, Layout); + uint32_t Value2 = 0; + uint64_t SecAddr = getSectionAddress(A_SD->getFragment()->getParent()); + FixedValue += SecAddr; + + if (const MCSymbolRefExpr *B = Target.getSymB()) { + MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol()); + + if (!B_SD->getFragment()) + report_fatal_error("symbol '" + B->getSymbol().getName() + + "' can not be undefined in a subtraction expression"); + + // Select the appropriate difference relocation type. + Type = macho::RIT_ARM_HalfDifference; + Value2 = getSymbolAddress(B_SD, Layout); + FixedValue -= getSectionAddress(B_SD->getFragment()->getParent()); + } - Asm.getOrCreateSymbolData(*it->Symbol); - } + // Relocations are written out in reverse order, so the PAIR comes first. + // ARM_RELOC_HALF and ARM_RELOC_HALF_SECTDIFF abuse the r_length field: + // + // For these two r_type relocations they always have a pair following them and + // the r_length bits are used differently. The encoding of the r_length is as + // follows: + // low bit of r_length: + // 0 - :lower16: for movw instructions + // 1 - :upper16: for movt instructions + // high bit of r_length: + // 0 - arm instructions + // 1 - thumb instructions + // the other half of the relocated expression is in the following pair + // relocation entry in the the low 16 bits of r_address field. + unsigned ThumbBit = 0; + unsigned MovtBit = 0; + switch ((unsigned)Fixup.getKind()) { + default: break; + case ARM::fixup_arm_movt_hi16: + case ARM::fixup_arm_movt_hi16_pcrel: + MovtBit = 1; + break; + case ARM::fixup_t2_movt_hi16: + case ARM::fixup_t2_movt_hi16_pcrel: + MovtBit = 1; + // Fallthrough + case ARM::fixup_t2_movw_lo16: + case ARM::fixup_t2_movw_lo16_pcrel: + ThumbBit = 1; + break; + } - // Then lazy symbol pointers and symbol stubs. - IndirectIndex = 0; - for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), - ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) { - const MCSectionMachO &Section = - cast(it->SectionData->getSection()); - if (Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS && - Section.getType() != MCSectionMachO::S_SYMBOL_STUBS) - continue; - - // Initialize the section indirect symbol base, if necessary. - if (!IndirectSymBase.count(it->SectionData)) - IndirectSymBase[it->SectionData] = IndirectIndex; - - // Set the symbol type to undefined lazy, but only on construction. - // - // FIXME: Do not hardcode. - bool Created; - MCSymbolData &Entry = Asm.getOrCreateSymbolData(*it->Symbol, &Created); - if (Created) - Entry.setFlags(Entry.getFlags() | 0x0001); - } + if (Type == macho::RIT_ARM_HalfDifference) { + uint32_t OtherHalf = MovtBit + ? (FixedValue & 0xffff) : ((FixedValue & 0xffff0000) >> 16); + + macho::RelocationEntry MRE; + MRE.Word0 = ((OtherHalf << 0) | + (macho::RIT_Pair << 24) | + (MovtBit << 28) | + (ThumbBit << 29) | + (IsPCRel << 30) | + macho::RF_Scattered); + MRE.Word1 = Value2; + Relocations[Fragment->getParent()].push_back(MRE); } - /// ComputeSymbolTable - Compute the symbol table data - /// - /// \param StringTable [out] - The string table data. - /// \param StringIndexMap [out] - Map from symbol names to offsets in the - /// string table. - void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, - std::vector &LocalSymbolData, - std::vector &ExternalSymbolData, - std::vector &UndefinedSymbolData) { - // Build section lookup table. - DenseMap SectionIndexMap; - unsigned Index = 1; - for (MCAssembler::iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it, ++Index) - SectionIndexMap[&it->getSection()] = Index; - assert(Index <= 256 && "Too many sections!"); + macho::RelocationEntry MRE; + MRE.Word0 = ((FixupOffset << 0) | + (Type << 24) | + (MovtBit << 28) | + (ThumbBit << 29) | + (IsPCRel << 30) | + macho::RF_Scattered); + MRE.Word1 = Value; + Relocations[Fragment->getParent()].push_back(MRE); +} - // Index 0 is always the empty string. - StringMap StringIndexMap; - StringTable += '\x00'; +void MachObjectWriter::RecordTLVPRelocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, + MCValue Target, + uint64_t &FixedValue) { + assert(Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP && + !is64Bit() && + "Should only be called with a 32-bit TLVP relocation!"); + + unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); + uint32_t Value = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); + unsigned IsPCRel = 0; + + // Get the symbol data. + MCSymbolData *SD_A = &Asm.getSymbolData(Target.getSymA()->getSymbol()); + unsigned Index = SD_A->getIndex(); + + // We're only going to have a second symbol in pic mode and it'll be a + // subtraction from the picbase. For 32-bit pic the addend is the difference + // between the picbase and the next address. For 32-bit static the addend is + // zero. + if (Target.getSymB()) { + // If this is a subtraction then we're pcrel. + uint32_t FixupAddress = + getFragmentAddress(Fragment, Layout) + Fixup.getOffset(); + MCSymbolData *SD_B = &Asm.getSymbolData(Target.getSymB()->getSymbol()); + IsPCRel = 1; + FixedValue = (FixupAddress - getSymbolAddress(SD_B, Layout) + + Target.getConstant()); + FixedValue += 1ULL << Log2Size; + } else { + FixedValue = 0; + } + + // struct relocation_info (8 bytes) + macho::RelocationEntry MRE; + MRE.Word0 = Value; + MRE.Word1 = ((Index << 0) | + (IsPCRel << 24) | + (Log2Size << 25) | + (1 << 27) | // Extern + (macho::RIT_Generic_TLV << 28)); // Type + Relocations[Fragment->getParent()].push_back(MRE); +} - // Build the symbol arrays and the string table, but only for non-local - // symbols. - // - // The particular order that we collect the symbols and create the string - // table, then sort the symbols is chosen to match 'as'. Even though it - // doesn't matter for correctness, this is important for letting us diff .o - // files. - for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), - ie = Asm.symbol_end(); it != ie; ++it) { - const MCSymbol &Symbol = it->getSymbol(); - - // Ignore non-linker visible symbols. - if (!Asm.isSymbolLinkerVisible(it->getSymbol())) - continue; - - if (!it->isExternal() && !Symbol.isUndefined()) - continue; - - uint64_t &Entry = StringIndexMap[Symbol.getName()]; - if (!Entry) { - Entry = StringTable.size(); - StringTable += Symbol.getName(); - StringTable += '\x00'; - } +bool MachObjectWriter::getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType, + unsigned &Log2Size) { + RelocType = unsigned(macho::RIT_Vanilla); + Log2Size = ~0U; - MachSymbolData MSD; - MSD.SymbolData = it; - MSD.StringIndex = Entry; - - if (Symbol.isUndefined()) { - MSD.SectionIndex = 0; - UndefinedSymbolData.push_back(MSD); - } else if (Symbol.isAbsolute()) { - MSD.SectionIndex = 0; - ExternalSymbolData.push_back(MSD); - } else { - MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); - assert(MSD.SectionIndex && "Invalid section index!"); - ExternalSymbolData.push_back(MSD); + switch (Kind) { + default: + return false; + + case FK_Data_1: + Log2Size = llvm::Log2_32(1); + return true; + case FK_Data_2: + Log2Size = llvm::Log2_32(2); + return true; + case FK_Data_4: + Log2Size = llvm::Log2_32(4); + return true; + case FK_Data_8: + Log2Size = llvm::Log2_32(8); + return true; + + // Handle 24-bit branch kinds. + case ARM::fixup_arm_ldst_pcrel_12: + case ARM::fixup_arm_pcrel_10: + case ARM::fixup_arm_adr_pcrel_12: + case ARM::fixup_arm_condbranch: + case ARM::fixup_arm_uncondbranch: + RelocType = unsigned(macho::RIT_ARM_Branch24Bit); + // Report as 'long', even though that is not quite accurate. + Log2Size = llvm::Log2_32(4); + return true; + + // Handle Thumb branches. + case ARM::fixup_arm_thumb_br: + RelocType = unsigned(macho::RIT_ARM_ThumbBranch22Bit); + Log2Size = llvm::Log2_32(2); + return true; + + case ARM::fixup_arm_thumb_bl: + case ARM::fixup_arm_thumb_blx: + RelocType = unsigned(macho::RIT_ARM_ThumbBranch22Bit); + Log2Size = llvm::Log2_32(4); + return true; + + case ARM::fixup_arm_movt_hi16: + case ARM::fixup_arm_movt_hi16_pcrel: + case ARM::fixup_t2_movt_hi16: + case ARM::fixup_t2_movt_hi16_pcrel: + RelocType = unsigned(macho::RIT_ARM_HalfDifference); + // Report as 'long', even though that is not quite accurate. + Log2Size = llvm::Log2_32(4); + return true; + + case ARM::fixup_arm_movw_lo16: + case ARM::fixup_arm_movw_lo16_pcrel: + case ARM::fixup_t2_movw_lo16: + case ARM::fixup_t2_movw_lo16_pcrel: + RelocType = unsigned(macho::RIT_ARM_Half); + // Report as 'long', even though that is not quite accurate. + Log2Size = llvm::Log2_32(4); + return true; + } +} +void MachObjectWriter::RecordARMRelocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, + MCValue Target, + uint64_t &FixedValue) { + unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); + unsigned Log2Size; + unsigned RelocType = macho::RIT_Vanilla; + if (!getARMFixupKindMachOInfo(Fixup.getKind(), RelocType, Log2Size)) { + report_fatal_error("unknown ARM fixup kind!"); + return; + } + + // If this is a difference or a defined symbol plus an offset, then we need a + // scattered relocation entry. Differences always require scattered + // relocations. + if (Target.getSymB()) { + if (RelocType == macho::RIT_ARM_Half || + RelocType == macho::RIT_ARM_HalfDifference) + return RecordARMMovwMovtRelocation(Asm, Layout, Fragment, Fixup, + Target, FixedValue); + return RecordARMScatteredRelocation(Asm, Layout, Fragment, Fixup, + Target, Log2Size, FixedValue); + } + + // Get the symbol data, if any. + MCSymbolData *SD = 0; + if (Target.getSymA()) + SD = &Asm.getSymbolData(Target.getSymA()->getSymbol()); + + // FIXME: For other platforms, we need to use scattered relocations for + // internal relocations with offsets. If this is an internal relocation with + // an offset, it also needs a scattered relocation entry. + // + // Is this right for ARM? + uint32_t Offset = Target.getConstant(); + if (IsPCRel && RelocType == macho::RIT_Vanilla) + Offset += 1 << Log2Size; + if (Offset && SD && !doesSymbolRequireExternRelocation(SD)) + return RecordARMScatteredRelocation(Asm, Layout, Fragment, Fixup, Target, + Log2Size, FixedValue); + + // See . + uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); + unsigned Index = 0; + unsigned IsExtern = 0; + unsigned Type = 0; + + if (Target.isAbsolute()) { // constant + // FIXME! + report_fatal_error("FIXME: relocations to absolute targets " + "not yet implemented"); + } else { + // Resolve constant variables. + if (SD->getSymbol().isVariable()) { + int64_t Res; + if (SD->getSymbol().getVariableValue()->EvaluateAsAbsolute( + Res, Layout, SectionAddress)) { + FixedValue = Res; + return; } } - // Now add the data for local symbols. - for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), - ie = Asm.symbol_end(); it != ie; ++it) { - const MCSymbol &Symbol = it->getSymbol(); - - // Ignore non-linker visible symbols. - if (!Asm.isSymbolLinkerVisible(it->getSymbol())) - continue; - - if (it->isExternal() || Symbol.isUndefined()) - continue; - - uint64_t &Entry = StringIndexMap[Symbol.getName()]; - if (!Entry) { - Entry = StringTable.size(); - StringTable += Symbol.getName(); - StringTable += '\x00'; - } + // Check whether we need an external or internal relocation. + if (doesSymbolRequireExternRelocation(SD)) { + IsExtern = 1; + Index = SD->getIndex(); + + // For external relocations, make sure to offset the fixup value to + // compensate for the addend of the symbol address, if it was + // undefined. This occurs with weak definitions, for example. + if (!SD->Symbol->isUndefined()) + FixedValue -= Layout.getSymbolOffset(SD); + } else { + // The index is the section ordinal (1-based). + const MCSectionData &SymSD = Asm.getSectionData( + SD->getSymbol().getSection()); + Index = SymSD.getOrdinal() + 1; + FixedValue += getSectionAddress(&SymSD); + } + if (IsPCRel) + FixedValue -= getSectionAddress(Fragment->getParent()); - MachSymbolData MSD; - MSD.SymbolData = it; - MSD.StringIndex = Entry; - - if (Symbol.isAbsolute()) { - MSD.SectionIndex = 0; - LocalSymbolData.push_back(MSD); - } else { - MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); - assert(MSD.SectionIndex && "Invalid section index!"); - LocalSymbolData.push_back(MSD); + // The type is determined by the fixup kind. + Type = RelocType; + } + + // struct relocation_info (8 bytes) + macho::RelocationEntry MRE; + MRE.Word0 = FixupOffset; + MRE.Word1 = ((Index << 0) | + (IsPCRel << 24) | + (Log2Size << 25) | + (IsExtern << 27) | + (Type << 28)); + Relocations[Fragment->getParent()].push_back(MRE); +} + +void MachObjectWriter::RecordRelocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, + MCValue Target, + uint64_t &FixedValue) { + // FIXME: These needs to be factored into the target Mach-O writer. + if (isARM()) { + RecordARMRelocation(Asm, Layout, Fragment, Fixup, Target, FixedValue); + return; + } + if (is64Bit()) { + RecordX86_64Relocation(Asm, Layout, Fragment, Fixup, Target, FixedValue); + return; + } + + unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); + unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); + + // If this is a 32-bit TLVP reloc it's handled a bit differently. + if (Target.getSymA() && + Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP) { + RecordTLVPRelocation(Asm, Layout, Fragment, Fixup, Target, FixedValue); + return; + } + + // If this is a difference or a defined symbol plus an offset, then we need a + // scattered relocation entry. Differences always require scattered + // relocations. + if (Target.getSymB()) + return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup, + Target, Log2Size, FixedValue); + + // Get the symbol data, if any. + MCSymbolData *SD = 0; + if (Target.getSymA()) + SD = &Asm.getSymbolData(Target.getSymA()->getSymbol()); + + // If this is an internal relocation with an offset, it also needs a scattered + // relocation entry. + uint32_t Offset = Target.getConstant(); + if (IsPCRel) + Offset += 1 << Log2Size; + if (Offset && SD && !doesSymbolRequireExternRelocation(SD)) + return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup, + Target, Log2Size, FixedValue); + + // See . + uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); + unsigned Index = 0; + unsigned IsExtern = 0; + unsigned Type = 0; + + if (Target.isAbsolute()) { // constant + // SymbolNum of 0 indicates the absolute section. + // + // FIXME: Currently, these are never generated (see code below). I cannot + // find a case where they are actually emitted. + Type = macho::RIT_Vanilla; + } else { + // Resolve constant variables. + if (SD->getSymbol().isVariable()) { + int64_t Res; + if (SD->getSymbol().getVariableValue()->EvaluateAsAbsolute( + Res, Layout, SectionAddress)) { + FixedValue = Res; + return; } } - // External and undefined symbols are required to be in lexicographic order. - std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); - std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); + // Check whether we need an external or internal relocation. + if (doesSymbolRequireExternRelocation(SD)) { + IsExtern = 1; + Index = SD->getIndex(); + // For external relocations, make sure to offset the fixup value to + // compensate for the addend of the symbol address, if it was + // undefined. This occurs with weak definitions, for example. + if (!SD->Symbol->isUndefined()) + FixedValue -= Layout.getSymbolOffset(SD); + } else { + // The index is the section ordinal (1-based). + const MCSectionData &SymSD = Asm.getSectionData( + SD->getSymbol().getSection()); + Index = SymSD.getOrdinal() + 1; + FixedValue += getSectionAddress(&SymSD); + } + if (IsPCRel) + FixedValue -= getSectionAddress(Fragment->getParent()); - // Set the symbol indices. - Index = 0; - for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) - LocalSymbolData[i].SymbolData->setIndex(Index++); - for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) - ExternalSymbolData[i].SymbolData->setIndex(Index++); - for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) - UndefinedSymbolData[i].SymbolData->setIndex(Index++); + Type = macho::RIT_Vanilla; + } - // The string table is padded to a multiple of 4. - while (StringTable.size() % 4) - StringTable += '\x00'; + // struct relocation_info (8 bytes) + macho::RelocationEntry MRE; + MRE.Word0 = FixupOffset; + MRE.Word1 = ((Index << 0) | + (IsPCRel << 24) | + (Log2Size << 25) | + (IsExtern << 27) | + (Type << 28)); + Relocations[Fragment->getParent()].push_back(MRE); +} + +void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) { + // This is the point where 'as' creates actual symbols for indirect symbols + // (in the following two passes). It would be easier for us to do this sooner + // when we see the attribute, but that makes getting the order in the symbol + // table much more complicated than it is worth. + // + // FIXME: Revisit this when the dust settles. + + // Bind non lazy symbol pointers first. + unsigned IndirectIndex = 0; + for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), + ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) { + const MCSectionMachO &Section = + cast(it->SectionData->getSection()); + + if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) + continue; + + // Initialize the section indirect symbol base, if necessary. + if (!IndirectSymBase.count(it->SectionData)) + IndirectSymBase[it->SectionData] = IndirectIndex; + + Asm.getOrCreateSymbolData(*it->Symbol); } - void computeSectionAddresses(const MCAssembler &Asm, - const MCAsmLayout &Layout) { - uint64_t StartAddress = 0; - const SmallVectorImpl &Order = Layout.getSectionOrder(); - for (int i = 0, n = Order.size(); i != n ; ++i) { - const MCSectionData *SD = Order[i]; - StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment()); - SectionAddress[SD] = StartAddress; - StartAddress += Layout.getSectionAddressSize(SD); - // Explicitly pad the section to match the alignment requirements of the - // following one. This is for 'gas' compatibility, it shouldn't - /// strictly be necessary. - StartAddress += getPaddingSize(SD, Layout); - } + // Then lazy symbol pointers and symbol stubs. + IndirectIndex = 0; + for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), + ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) { + const MCSectionMachO &Section = + cast(it->SectionData->getSection()); + + if (Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS && + Section.getType() != MCSectionMachO::S_SYMBOL_STUBS) + continue; + + // Initialize the section indirect symbol base, if necessary. + if (!IndirectSymBase.count(it->SectionData)) + IndirectSymBase[it->SectionData] = IndirectIndex; + + // Set the symbol type to undefined lazy, but only on construction. + // + // FIXME: Do not hardcode. + bool Created; + MCSymbolData &Entry = Asm.getOrCreateSymbolData(*it->Symbol, &Created); + if (Created) + Entry.setFlags(Entry.getFlags() | 0x0001); } +} + +/// ComputeSymbolTable - Compute the symbol table data +/// +/// \param StringTable [out] - The string table data. +/// \param StringIndexMap [out] - Map from symbol names to offsets in the +/// string table. +void MachObjectWriter::ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, + std::vector &LocalSymbolData, + std::vector &ExternalSymbolData, + std::vector &UndefinedSymbolData) { + // Build section lookup table. + DenseMap SectionIndexMap; + unsigned Index = 1; + for (MCAssembler::iterator it = Asm.begin(), + ie = Asm.end(); it != ie; ++it, ++Index) + SectionIndexMap[&it->getSection()] = Index; + assert(Index <= 256 && "Too many sections!"); + + // Index 0 is always the empty string. + StringMap StringIndexMap; + StringTable += '\x00'; + + // Build the symbol arrays and the string table, but only for non-local + // symbols. + // + // The particular order that we collect the symbols and create the string + // table, then sort the symbols is chosen to match 'as'. Even though it + // doesn't matter for correctness, this is important for letting us diff .o + // files. + for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), + ie = Asm.symbol_end(); it != ie; ++it) { + const MCSymbol &Symbol = it->getSymbol(); + + // Ignore non-linker visible symbols. + if (!Asm.isSymbolLinkerVisible(it->getSymbol())) + continue; + + if (!it->isExternal() && !Symbol.isUndefined()) + continue; + + uint64_t &Entry = StringIndexMap[Symbol.getName()]; + if (!Entry) { + Entry = StringTable.size(); + StringTable += Symbol.getName(); + StringTable += '\x00'; + } - void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) { - computeSectionAddresses(Asm, Layout); - - // Create symbol data for any indirect symbols. - BindIndirectSymbols(Asm); - - // Compute symbol table information and bind symbol indices. - ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData, - UndefinedSymbolData); + MachSymbolData MSD; + MSD.SymbolData = it; + MSD.StringIndex = Entry; + + if (Symbol.isUndefined()) { + MSD.SectionIndex = 0; + UndefinedSymbolData.push_back(MSD); + } else if (Symbol.isAbsolute()) { + MSD.SectionIndex = 0; + ExternalSymbolData.push_back(MSD); + } else { + MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); + assert(MSD.SectionIndex && "Invalid section index!"); + ExternalSymbolData.push_back(MSD); + } } - virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, - const MCSymbolData &DataA, - const MCFragment &FB, - bool InSet, - bool IsPCRel) const { - if (InSet) - return true; + // Now add the data for local symbols. + for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), + ie = Asm.symbol_end(); it != ie; ++it) { + const MCSymbol &Symbol = it->getSymbol(); - // The effective address is - // addr(atom(A)) + offset(A) - // - addr(atom(B)) - offset(B) - // and the offsets are not relocatable, so the fixup is fully resolved when - // addr(atom(A)) - addr(atom(B)) == 0. - const MCSymbolData *A_Base = 0, *B_Base = 0; - - const MCSymbol &SA = DataA.getSymbol().AliasedSymbol(); - const MCSection &SecA = SA.getSection(); - const MCSection &SecB = FB.getParent()->getSection(); + // Ignore non-linker visible symbols. + if (!Asm.isSymbolLinkerVisible(it->getSymbol())) + continue; - if (IsPCRel) { - // The simple (Darwin, except on x86_64) way of dealing with this was to - // assume that any reference to a temporary symbol *must* be a temporary - // symbol in the same atom, unless the sections differ. Therefore, any - // PCrel relocation to a temporary symbol (in the same section) is fully - // resolved. This also works in conjunction with absolutized .set, which - // requires the compiler to use .set to absolutize the differences between - // symbols which the compiler knows to be assembly time constants, so we - // don't need to worry about considering symbol differences fully - // resolved. - - if (!Asm.getBackend().hasReliableSymbolDifference()) { - if (!SA.isTemporary() || !SA.isInSection() || &SecA != &SecB) - return false; - return true; - } + if (it->isExternal() || Symbol.isUndefined()) + continue; + + uint64_t &Entry = StringIndexMap[Symbol.getName()]; + if (!Entry) { + Entry = StringTable.size(); + StringTable += Symbol.getName(); + StringTable += '\x00'; + } + + MachSymbolData MSD; + MSD.SymbolData = it; + MSD.StringIndex = Entry; + + if (Symbol.isAbsolute()) { + MSD.SectionIndex = 0; + LocalSymbolData.push_back(MSD); } else { - if (!TargetObjectWriter->useAggressiveSymbolFolding()) - return false; + MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); + assert(MSD.SectionIndex && "Invalid section index!"); + LocalSymbolData.push_back(MSD); } + } - const MCFragment &FA = *Asm.getSymbolData(SA).getFragment(); + // External and undefined symbols are required to be in lexicographic order. + std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); + std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); + + // Set the symbol indices. + Index = 0; + for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) + LocalSymbolData[i].SymbolData->setIndex(Index++); + for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) + ExternalSymbolData[i].SymbolData->setIndex(Index++); + for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) + UndefinedSymbolData[i].SymbolData->setIndex(Index++); - A_Base = FA.getAtom(); - if (!A_Base) - return false; + // The string table is padded to a multiple of 4. + while (StringTable.size() % 4) + StringTable += '\x00'; +} - B_Base = FB.getAtom(); - if (!B_Base) - return false; +void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm, + const MCAsmLayout &Layout) { + uint64_t StartAddress = 0; + const SmallVectorImpl &Order = Layout.getSectionOrder(); + for (int i = 0, n = Order.size(); i != n ; ++i) { + const MCSectionData *SD = Order[i]; + StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment()); + SectionAddress[SD] = StartAddress; + StartAddress += Layout.getSectionAddressSize(SD); + + // Explicitly pad the section to match the alignment requirements of the + // following one. This is for 'gas' compatibility, it shouldn't + /// strictly be necessary. + StartAddress += getPaddingSize(SD, Layout); + } +} + +void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) { + computeSectionAddresses(Asm, Layout); + + // Create symbol data for any indirect symbols. + BindIndirectSymbols(Asm); + + // Compute symbol table information and bind symbol indices. + ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData, + UndefinedSymbolData); +} + +bool MachObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const { + if (InSet) + return true; + + // The effective address is + // addr(atom(A)) + offset(A) + // - addr(atom(B)) - offset(B) + // and the offsets are not relocatable, so the fixup is fully resolved when + // addr(atom(A)) - addr(atom(B)) == 0. + const MCSymbolData *A_Base = 0, *B_Base = 0; + + const MCSymbol &SA = DataA.getSymbol().AliasedSymbol(); + const MCSection &SecA = SA.getSection(); + const MCSection &SecB = FB.getParent()->getSection(); + + if (IsPCRel) { + // The simple (Darwin, except on x86_64) way of dealing with this was to + // assume that any reference to a temporary symbol *must* be a temporary + // symbol in the same atom, unless the sections differ. Therefore, any PCrel + // relocation to a temporary symbol (in the same section) is fully + // resolved. This also works in conjunction with absolutized .set, which + // requires the compiler to use .set to absolutize the differences between + // symbols which the compiler knows to be assembly time constants, so we + // don't need to worry about considering symbol differences fully resolved. - // If the atoms are the same, they are guaranteed to have the same address. - if (A_Base == B_Base) + if (!Asm.getBackend().hasReliableSymbolDifference()) { + if (!SA.isTemporary() || !SA.isInSection() || &SecA != &SecB) + return false; return true; + } + } else { + if (!TargetObjectWriter->useAggressiveSymbolFolding()) + return false; + } + + const MCFragment &FA = *Asm.getSymbolData(SA).getFragment(); - // Otherwise, we can't prove this is fully resolved. + A_Base = FA.getAtom(); + if (!A_Base) return false; - } - void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) { - unsigned NumSections = Asm.size(); + B_Base = FB.getAtom(); + if (!B_Base) + return false; - // The section data starts after the header, the segment load command (and - // section headers) and the symbol table. - unsigned NumLoadCommands = 1; - uint64_t LoadCommandsSize = is64Bit() ? - macho::SegmentLoadCommand64Size + NumSections * macho::Section64Size : - macho::SegmentLoadCommand32Size + NumSections * macho::Section32Size; - - // Add the symbol table load command sizes, if used. - unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() + - UndefinedSymbolData.size(); - if (NumSymbols) { - NumLoadCommands += 2; - LoadCommandsSize += (macho::SymtabLoadCommandSize + - macho::DysymtabLoadCommandSize); - } - - // Compute the total size of the section data, as well as its file size and - // vm size. - uint64_t SectionDataStart = (is64Bit() ? macho::Header64Size : - macho::Header32Size) + LoadCommandsSize; - uint64_t SectionDataSize = 0; - uint64_t SectionDataFileSize = 0; - uint64_t VMSize = 0; - for (MCAssembler::const_iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it) { - const MCSectionData &SD = *it; - uint64_t Address = getSectionAddress(&SD); - uint64_t Size = Layout.getSectionAddressSize(&SD); - uint64_t FileSize = Layout.getSectionFileSize(&SD); - FileSize += getPaddingSize(&SD, Layout); - - VMSize = std::max(VMSize, Address + Size); + // If the atoms are the same, they are guaranteed to have the same address. + if (A_Base == B_Base) + return true; - if (SD.getSection().isVirtualSection()) - continue; + // Otherwise, we can't prove this is fully resolved. + return false; +} - SectionDataSize = std::max(SectionDataSize, Address + Size); - SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize); - } +void MachObjectWriter::WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) { + unsigned NumSections = Asm.size(); - // The section data is padded to 4 bytes. - // - // FIXME: Is this machine dependent? - unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4); - SectionDataFileSize += SectionDataPadding; - - // Write the prolog, starting with the header and load command... - WriteHeader(NumLoadCommands, LoadCommandsSize, - Asm.getSubsectionsViaSymbols()); - WriteSegmentLoadCommand(NumSections, VMSize, - SectionDataStart, SectionDataSize); - - // ... and then the section headers. - uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize; - for (MCAssembler::const_iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it) { - std::vector &Relocs = Relocations[it]; - unsigned NumRelocs = Relocs.size(); - uint64_t SectionStart = SectionDataStart + getSectionAddress(it); - WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs); - RelocTableEnd += NumRelocs * macho::RelocationInfoSize; - } - - // Write the symbol table load command, if used. - if (NumSymbols) { - unsigned FirstLocalSymbol = 0; - unsigned NumLocalSymbols = LocalSymbolData.size(); - unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols; - unsigned NumExternalSymbols = ExternalSymbolData.size(); - unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols; - unsigned NumUndefinedSymbols = UndefinedSymbolData.size(); - unsigned NumIndirectSymbols = Asm.indirect_symbol_size(); - unsigned NumSymTabSymbols = - NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols; - uint64_t IndirectSymbolSize = NumIndirectSymbols * 4; - uint64_t IndirectSymbolOffset = 0; - - // If used, the indirect symbols are written after the section data. - if (NumIndirectSymbols) - IndirectSymbolOffset = RelocTableEnd; - - // The symbol table is written after the indirect symbol data. - uint64_t SymbolTableOffset = RelocTableEnd + IndirectSymbolSize; - - // The string table is written after symbol table. - uint64_t StringTableOffset = - SymbolTableOffset + NumSymTabSymbols * (is64Bit() ? macho::Nlist64Size : - macho::Nlist32Size); - WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols, - StringTableOffset, StringTable.size()); - - WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols, - FirstExternalSymbol, NumExternalSymbols, - FirstUndefinedSymbol, NumUndefinedSymbols, - IndirectSymbolOffset, NumIndirectSymbols); - } - - // Write the actual section data. - for (MCAssembler::const_iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it) { - Asm.WriteSectionData(it, Layout); - - uint64_t Pad = getPaddingSize(it, Layout); - for (unsigned int i = 0; i < Pad; ++i) - Write8(0); - } - - // Write the extra padding. - WriteZeros(SectionDataPadding); - - // Write the relocation entries. - for (MCAssembler::const_iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it) { - // Write the section relocation entries, in reverse order to match 'as' - // (approximately, the exact algorithm is more complicated than this). - std::vector &Relocs = Relocations[it]; - for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { - Write32(Relocs[e - i - 1].Word0); - Write32(Relocs[e - i - 1].Word1); - } - } + // The section data starts after the header, the segment load command (and + // section headers) and the symbol table. + unsigned NumLoadCommands = 1; + uint64_t LoadCommandsSize = is64Bit() ? + macho::SegmentLoadCommand64Size + NumSections * macho::Section64Size : + macho::SegmentLoadCommand32Size + NumSections * macho::Section32Size; + + // Add the symbol table load command sizes, if used. + unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() + + UndefinedSymbolData.size(); + if (NumSymbols) { + NumLoadCommands += 2; + LoadCommandsSize += (macho::SymtabLoadCommandSize + + macho::DysymtabLoadCommandSize); + } + + // Compute the total size of the section data, as well as its file size and vm + // size. + uint64_t SectionDataStart = (is64Bit() ? macho::Header64Size : + macho::Header32Size) + LoadCommandsSize; + uint64_t SectionDataSize = 0; + uint64_t SectionDataFileSize = 0; + uint64_t VMSize = 0; + for (MCAssembler::const_iterator it = Asm.begin(), + ie = Asm.end(); it != ie; ++it) { + const MCSectionData &SD = *it; + uint64_t Address = getSectionAddress(&SD); + uint64_t Size = Layout.getSectionAddressSize(&SD); + uint64_t FileSize = Layout.getSectionFileSize(&SD); + FileSize += getPaddingSize(&SD, Layout); + + VMSize = std::max(VMSize, Address + Size); - // Write the symbol table data, if used. - if (NumSymbols) { - // Write the indirect symbol entries. - for (MCAssembler::const_indirect_symbol_iterator - it = Asm.indirect_symbol_begin(), - ie = Asm.indirect_symbol_end(); it != ie; ++it) { - // Indirect symbols in the non lazy symbol pointer section have some - // special handling. - const MCSectionMachO &Section = - static_cast(it->SectionData->getSection()); - if (Section.getType() == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) { - // If this symbol is defined and internal, mark it as such. - if (it->Symbol->isDefined() && - !Asm.getSymbolData(*it->Symbol).isExternal()) { - uint32_t Flags = macho::ISF_Local; - if (it->Symbol->isAbsolute()) - Flags |= macho::ISF_Absolute; - Write32(Flags); - continue; - } - } + if (SD.getSection().isVirtualSection()) + continue; + + SectionDataSize = std::max(SectionDataSize, Address + Size); + SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize); + } - Write32(Asm.getSymbolData(*it->Symbol).getIndex()); + // The section data is padded to 4 bytes. + // + // FIXME: Is this machine dependent? + unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4); + SectionDataFileSize += SectionDataPadding; + + // Write the prolog, starting with the header and load command... + WriteHeader(NumLoadCommands, LoadCommandsSize, + Asm.getSubsectionsViaSymbols()); + WriteSegmentLoadCommand(NumSections, VMSize, + SectionDataStart, SectionDataSize); + + // ... and then the section headers. + uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize; + for (MCAssembler::const_iterator it = Asm.begin(), + ie = Asm.end(); it != ie; ++it) { + std::vector &Relocs = Relocations[it]; + unsigned NumRelocs = Relocs.size(); + uint64_t SectionStart = SectionDataStart + getSectionAddress(it); + WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs); + RelocTableEnd += NumRelocs * macho::RelocationInfoSize; + } + + // Write the symbol table load command, if used. + if (NumSymbols) { + unsigned FirstLocalSymbol = 0; + unsigned NumLocalSymbols = LocalSymbolData.size(); + unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols; + unsigned NumExternalSymbols = ExternalSymbolData.size(); + unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols; + unsigned NumUndefinedSymbols = UndefinedSymbolData.size(); + unsigned NumIndirectSymbols = Asm.indirect_symbol_size(); + unsigned NumSymTabSymbols = + NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols; + uint64_t IndirectSymbolSize = NumIndirectSymbols * 4; + uint64_t IndirectSymbolOffset = 0; + + // If used, the indirect symbols are written after the section data. + if (NumIndirectSymbols) + IndirectSymbolOffset = RelocTableEnd; + + // The symbol table is written after the indirect symbol data. + uint64_t SymbolTableOffset = RelocTableEnd + IndirectSymbolSize; + + // The string table is written after symbol table. + uint64_t StringTableOffset = + SymbolTableOffset + NumSymTabSymbols * (is64Bit() ? macho::Nlist64Size : + macho::Nlist32Size); + WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols, + StringTableOffset, StringTable.size()); + + WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols, + FirstExternalSymbol, NumExternalSymbols, + FirstUndefinedSymbol, NumUndefinedSymbols, + IndirectSymbolOffset, NumIndirectSymbols); + } + + // Write the actual section data. + for (MCAssembler::const_iterator it = Asm.begin(), + ie = Asm.end(); it != ie; ++it) { + Asm.WriteSectionData(it, Layout); + + uint64_t Pad = getPaddingSize(it, Layout); + for (unsigned int i = 0; i < Pad; ++i) + Write8(0); + } + + // Write the extra padding. + WriteZeros(SectionDataPadding); + + // Write the relocation entries. + for (MCAssembler::const_iterator it = Asm.begin(), + ie = Asm.end(); it != ie; ++it) { + // Write the section relocation entries, in reverse order to match 'as' + // (approximately, the exact algorithm is more complicated than this). + std::vector &Relocs = Relocations[it]; + for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { + Write32(Relocs[e - i - 1].Word0); + Write32(Relocs[e - i - 1].Word1); + } + } + + // Write the symbol table data, if used. + if (NumSymbols) { + // Write the indirect symbol entries. + for (MCAssembler::const_indirect_symbol_iterator + it = Asm.indirect_symbol_begin(), + ie = Asm.indirect_symbol_end(); it != ie; ++it) { + // Indirect symbols in the non lazy symbol pointer section have some + // special handling. + const MCSectionMachO &Section = + static_cast(it->SectionData->getSection()); + if (Section.getType() == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) { + // If this symbol is defined and internal, mark it as such. + if (it->Symbol->isDefined() && + !Asm.getSymbolData(*it->Symbol).isExternal()) { + uint32_t Flags = macho::ISF_Local; + if (it->Symbol->isAbsolute()) + Flags |= macho::ISF_Absolute; + Write32(Flags); + continue; + } } - // FIXME: Check that offsets match computed ones. + Write32(Asm.getSymbolData(*it->Symbol).getIndex()); + } - // Write the symbol table entries. - for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) - WriteNlist(LocalSymbolData[i], Layout); - for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) - WriteNlist(ExternalSymbolData[i], Layout); - for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) - WriteNlist(UndefinedSymbolData[i], Layout); + // FIXME: Check that offsets match computed ones. - // Write the string table. - OS << StringTable.str(); - } - } -}; + // Write the symbol table entries. + for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) + WriteNlist(LocalSymbolData[i], Layout); + for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) + WriteNlist(ExternalSymbolData[i], Layout); + for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) + WriteNlist(UndefinedSymbolData[i], Layout); + // Write the string table. + OS << StringTable.str(); + } } MCObjectWriter *llvm::createMachObjectWriter(MCMachObjectTargetWriter *MOTW, From mcrosier at apple.com Wed Jun 22 16:13:23 2011 From: mcrosier at apple.com (Chad Rosier) Date: Wed, 22 Jun 2011 21:13:23 -0000 Subject: [llvm-commits] [llvm] r133646 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp Message-ID: <20110622211323.62F8C2A6C12C@llvm.org> Author: mcrosier Date: Wed Jun 22 16:13:23 2011 New Revision: 133646 URL: http://llvm.org/viewvc/llvm-project?rev=133646&view=rev Log: Revert r133607. This is causing failures in the Clang gccTestSuite. Specifically, gcc.c-torture/compile/pr21356.c. Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=133646&r1=133645&r2=133646&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Wed Jun 22 16:13:23 2011 @@ -568,9 +568,9 @@ TailDuplicatePass::isSimpleBB(MachineBasicBlock *TailBB) { if (TailBB->succ_size() != 1) return false; - MachineBasicBlock::iterator I = TailBB->begin(); + MachineBasicBlock::iterator I = TailBB->getFirstNonPHI(); MachineBasicBlock::iterator E = TailBB->end(); - while (I != E && I->isDebugValue()) + while (I->isDebugValue() && I != E) ++I; if (I == E) return true; @@ -712,7 +712,7 @@ DenseSet UsedByPhi; getRegsUsedByPHIs(*TailBB, &UsedByPhi); - if (isSimpleBB(TailBB)) + if (0 && isSimpleBB(TailBB)) return duplicateSimpleBB(TailBB, TDBBs, UsedByPhi, Copies); // Iterate through all the unique predecessors and tail-duplicate this From nicholas at mxc.ca Wed Jun 22 16:13:46 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 22 Jun 2011 21:13:46 -0000 Subject: [llvm-commits] [llvm] r133648 - in /llvm/trunk: lib/Support/ConstantRange.cpp unittests/Support/ConstantRangeTest.cpp Message-ID: <20110622211346.4EB992A6C12C@llvm.org> Author: nicholas Date: Wed Jun 22 16:13:46 2011 New Revision: 133648 URL: http://llvm.org/viewvc/llvm-project?rev=133648&view=rev Log: Fix the implementation of ConstantRange::sub(ConstantRange). Patch by Xi Wang! Modified: llvm/trunk/lib/Support/ConstantRange.cpp llvm/trunk/unittests/Support/ConstantRangeTest.cpp Modified: llvm/trunk/lib/Support/ConstantRange.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ConstantRange.cpp?rev=133648&r1=133647&r2=133648&view=diff ============================================================================== --- llvm/trunk/lib/Support/ConstantRange.cpp (original) +++ llvm/trunk/lib/Support/ConstantRange.cpp Wed Jun 22 16:13:46 2011 @@ -529,8 +529,8 @@ return ConstantRange(getBitWidth(), /*isFullSet=*/true); APInt Spread_X = getSetSize(), Spread_Y = Other.getSetSize(); - APInt NewLower = getLower() - Other.getLower(); - APInt NewUpper = getUpper() - Other.getUpper() + 1; + APInt NewLower = getLower() - Other.getUpper() + 1; + APInt NewUpper = getUpper() - Other.getLower(); if (NewLower == NewUpper) return ConstantRange(getBitWidth(), /*isFullSet=*/true); Modified: llvm/trunk/unittests/Support/ConstantRangeTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ConstantRangeTest.cpp?rev=133648&r1=133647&r2=133648&view=diff ============================================================================== --- llvm/trunk/unittests/Support/ConstantRangeTest.cpp (original) +++ llvm/trunk/unittests/Support/ConstantRangeTest.cpp Wed Jun 22 16:13:46 2011 @@ -299,6 +299,8 @@ EXPECT_EQ(Empty.sub(APInt(16, 4)), Empty); EXPECT_EQ(Some.sub(APInt(16, 4)), ConstantRange(APInt(16, 0x6), APInt(16, 0xaa6))); + EXPECT_EQ(Some.sub(Some), + ConstantRange(APInt(16, 0xf561), APInt(16, 0xaa0))); EXPECT_EQ(Wrap.sub(APInt(16, 4)), ConstantRange(APInt(16, 0xaa6), APInt(16, 0x6))); EXPECT_EQ(One.sub(APInt(16, 4)), From nlewycky at google.com Wed Jun 22 16:19:38 2011 From: nlewycky at google.com (Nick Lewycky) Date: Wed, 22 Jun 2011 14:19:38 -0700 Subject: [llvm-commits] [PATCH] ConstantRange::sub In-Reply-To: References: <01F9FA28-E4FB-4D8A-9A67-C445041842B9@gmail.com> <4B12B5B1-CFC3-40CA-9F02-D3D7D5378F5B@gmail.com> Message-ID: On 22 June 2011 14:09, Xi Wang wrote: > Here goes the patch along with a test for ConstantRange::sub. Thanks. > Thanks! Committed as r133648. Nick > > > > On Jun 22, 2011, at 3:57 PM, Nick Lewycky wrote: > > > On 22 June 2011 12:51, Xi Wang wrote: > > Sure. I will submit a patch. > > > > BTW, what's the difference between the bounds I was expecting > > > > APInt NewLower = getLower() - Other.getUpper() + 1; > > APInt NewUpper = getUpper() - Other.getLower(); > > > > and the two you mentioned > > > > NewLower = Lower - (Upper-1) > > NewUpper = (Upper-1) - Lower + 1 > > > > They look equivalent to me. Did I miss anything? Thanks. > > > > ... they are. Sorry, I was just surprised to see the +1 on the NewLower > (it always goes on the NewUpper instead, right), but I didn't actually > simplify the expressions. > > > > It sounds to me like you've got this one handled. :-) > > > > Nick > > > > > > - xi > > > > On Jun 22, 2011, at 2:39 PM, Nick Lewycky wrote: > > > > > Thanks, I think you've found a serious bug! > > > > > > Would you be willing to fix it? Please add a test to > unittests/Support/ConstantRangeTest.cpp and then mail llvm-commits with the > patch to fix it and add the test. > > > > > > On 20 June 2011 23:09, Xi Wang wrote: > > > Hi, > > > > > > I have a question about ConstantRange::sub(const ConstantRange &Other) > at lib/Support/ConstantRange.cpp:524. The code computes the new bounds as > follows. > > > > > > APInt NewLower = getLower() - Other.getLower(); > > > APInt NewUpper = getUpper() - Other.getUpper() + 1; > > > > > > Could someone explain this to me? I was expecting something like > > > > > > APInt NewLower = getLower() - Other.getUpper() + 1; > > > APInt NewUpper = getUpper() - Other.getLower(); > > > > > > These aren't quite right, I think it should be: > > > > > > NewLower = Lower - (Upper-1) > > > NewUpper = (Upper-1) - Lower + 1 > > > > > > Constant ranges are stored half-open, [lower, upper) which means that > the upper value is one past the end of the range. I often think of the > formula as newmax = max - min --> newupper - 1 = ((getUpper() - 1) - > Other.getLower(). min = lower, while max = upper - 1. > > > > > > Nick > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110622/1b7ceec3/attachment.html From aggarwa4 at illinois.edu Wed Jun 22 16:17:19 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Wed, 22 Jun 2011 21:17:19 -0000 Subject: [llvm-commits] [poolalloc] r133650 - in /poolalloc/trunk: lib/AssistDS/TypeChecks.cpp runtime/DynamicTypeChecks/TypeRuntime.cpp Message-ID: <20110622211719.49B7B2A6C12C@llvm.org> Author: aggarwa4 Date: Wed Jun 22 16:17:19 2011 New Revision: 133650 URL: http://llvm.org/viewvc/llvm-project?rev=133650&view=rev Log: Create a separate TypeTagTy, to make it more flexible. Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=133650&r1=133649&r2=133650&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Wed Jun 22 16:17:19 2011 @@ -60,6 +60,10 @@ static const Type *Int32Ty = 0; static const Type *Int64Ty = 0; static const PointerType *VoidPtrTy = 0; + +static const Type *TypeTagTy = 0; +static const Type *TypeTagPtrTy = 0; + static Constant *One = 0; static Constant *Zero = 0; static Constant *RegisterArgv; @@ -112,11 +116,11 @@ } Constant *TypeChecks::getTypeMarkerConstant(Value * V) { - return ConstantInt::get(Int8Ty, getTypeMarker(V)); + return ConstantInt::get(TypeTagTy, getTypeMarker(V)); } Constant *TypeChecks::getTypeMarkerConstant(const Type *T) { - return ConstantInt::get(Int8Ty, getTypeMarker(T)); + return ConstantInt::get(TypeTagTy, getTypeMarker(T)); } bool TypeChecks::runOnModule(Module &M) { @@ -131,6 +135,10 @@ Int32Ty = IntegerType::getInt32Ty(M.getContext()); Int64Ty = IntegerType::getInt64Ty(M.getContext()); VoidPtrTy = PointerType::getUnqual(Int8Ty); + + TypeTagTy = Int8Ty; + TypeTagPtrTy = PointerType::getUnqual(TypeTagTy); + One = ConstantInt::get(Int64Ty, 1); Zero = ConstantInt::get(Int64Ty, 0); @@ -146,7 +154,7 @@ trackGlobal = M.getOrInsertFunction("trackGlobal", VoidTy, VoidPtrTy,/*ptr*/ - Int8Ty,/*type*/ + TypeTagTy,/*type*/ Int64Ty,/*size*/ Int32Ty,/*tag*/ NULL); @@ -172,7 +180,7 @@ trackStoreInst = M.getOrInsertFunction("trackStoreInst", VoidTy, VoidPtrTy,/*ptr*/ - Int8Ty,/*type*/ + TypeTagTy,/*type*/ Int64Ty,/*size*/ Int32Ty,/*tag*/ NULL); @@ -180,20 +188,20 @@ VoidTy, VoidPtrTy, /*ptr*/ Int64Ty, /*size*/ - VoidPtrTy, /*dest for type tag*/ + TypeTagPtrTy, /*dest for type tag*/ NULL); checkTypeInst = M.getOrInsertFunction("checkType", VoidTy, - Int8Ty,/*type*/ + TypeTagTy,/*type*/ Int64Ty,/*size*/ - VoidPtrTy, + TypeTagPtrTy,/*ptr to metadata*/ VoidPtrTy,/*ptr*/ Int32Ty,/*tag*/ NULL); setTypeInfo = M.getOrInsertFunction("setTypeInfo", VoidTy, VoidPtrTy,/*dest ptr*/ - VoidPtrTy,/*metadata*/ + TypeTagPtrTy,/*metadata*/ Int64Ty,/*size*/ Int32Ty,/*tag*/ NULL); @@ -213,7 +221,7 @@ VoidTy, VoidPtrTy,/*va_list ptr*/ Int64Ty,/*total num of elements in va_list */ - VoidPtrTy,/*ptr to metadta*/ + TypeTagPtrTy,/*ptr to metadta*/ Int32Ty,/*tag*/ NULL); copyVAInfo = M.getOrInsertFunction("copyVAInfo", @@ -225,7 +233,7 @@ checkVAArg = M.getOrInsertFunction("checkVAArgType", VoidTy, VoidPtrTy,/*va_list ptr*/ - Int8Ty,/*type*/ + TypeTagTy,/*type*/ Int32Ty,/*tag*/ NULL); @@ -527,7 +535,7 @@ unsigned int NumArgs = CI->getNumOperands() - 1; inst_iterator InsPt = inst_begin(CI->getParent()->getParent()); Value *NumArgsVal = ConstantInt::get(Int32Ty, NumArgs); - AllocaInst *AI = new AllocaInst(Int8Ty, NumArgsVal, "", &*InsPt); + AllocaInst *AI = new AllocaInst(TypeTagTy, NumArgsVal, "", &*InsPt); // set the metadata for the varargs in AI for(i = 1; i getNumOperands(); i++) { Value *Idx[2]; @@ -599,7 +607,7 @@ // 1. Create the new argument types vector std::vector TP; TP.push_back(Int64Ty); // for count - TP.push_back(VoidPtrTy); // for MD + TP.push_back(TypeTagPtrTy); // for MD for(Function::arg_iterator I = F.arg_begin(); I !=F.arg_end(); ++I) { TP.push_back(I->getType()); } @@ -719,7 +727,7 @@ unsigned int i; unsigned int NumArgs = II->getNumOperands() - 3; Value *NumArgsVal = ConstantInt::get(Int32Ty, NumArgs); - AllocaInst *AI = new AllocaInst(Int8Ty, NumArgsVal, "", &*InsPt); + AllocaInst *AI = new AllocaInst(TypeTagTy, NumArgsVal, "", &*InsPt); // set the metadata for the varargs in AI for(i = 3; i getNumOperands(); i++) { Value *Idx[2]; @@ -755,7 +763,7 @@ unsigned int i; unsigned int NumArgs = CI->getNumOperands() - 1; Value *NumArgsVal = ConstantInt::get(Int32Ty, NumArgs); - AllocaInst *AI = new AllocaInst(Int8Ty, NumArgsVal, "", &*InsPt); + AllocaInst *AI = new AllocaInst(TypeTagTy, NumArgsVal, "", &*InsPt); // set the metadata for the varargs in AI for(i = 1; i getNumOperands(); i++) { Value *Idx[2]; @@ -1122,30 +1130,30 @@ return true; } - bool TypeChecks::visitMain(Module &M, Function &MainFunc) { - if(MainFunc.arg_size() < 2) - // No need to register - return false; - - Function::arg_iterator AI = MainFunc.arg_begin(); - Value *Argc = AI; - Value *Argv = ++AI; - - Instruction *InsertPt = MainFunc.front().begin(); - std::vector fargs; - fargs.push_back (Argc); - fargs.push_back (Argv); - CallInst::Create (RegisterArgv, fargs.begin(), fargs.end(), "", InsertPt); +bool TypeChecks::visitMain(Module &M, Function &MainFunc) { + if(MainFunc.arg_size() < 2) + // No need to register + return false; - if(MainFunc.arg_size() < 3) - return true; + Function::arg_iterator AI = MainFunc.arg_begin(); + Value *Argc = AI; + Value *Argv = ++AI; + + Instruction *InsertPt = MainFunc.front().begin(); + std::vector fargs; + fargs.push_back (Argc); + fargs.push_back (Argv); + CallInst::Create (RegisterArgv, fargs.begin(), fargs.end(), "", InsertPt); - Value *Envp = ++AI; - std::vector Args; - Args.push_back(Envp); - CallInst::Create(RegisterEnvp, Args.begin(), Args.end(), "", InsertPt); + if(MainFunc.arg_size() < 3) return true; - } + + Value *Envp = ++AI; + std::vector Args; + Args.push_back(Envp); + CallInst::Create(RegisterEnvp, Args.begin(), Args.end(), "", InsertPt); + return true; +} bool TypeChecks::visitGlobal(Module &M, GlobalVariable &GV, Constant *C, Instruction &I, SmallVector Indices) { @@ -1240,17 +1248,17 @@ } return true; } -bool TypeChecks::visitVAArgInst(Module &M, VAArgInst &VI) { - if(!VI.getParent()->getParent()->hasInternalLinkage()) + bool TypeChecks::visitVAArgInst(Module &M, VAArgInst &VI) { + if(!VI.getParent()->getParent()->hasInternalLinkage()) + return false; + CastInst *BCI = BitCastInst::CreatePointerCast(VI.getOperand(0), VoidPtrTy, "", &VI); + std::vectorArgs; + Args.push_back(BCI); + Args.push_back(getTypeMarkerConstant(&VI)); + Args.push_back(getTagCounter()); + CallInst::Create(checkVAArg, Args.begin(), Args.end(), "", &VI); return false; - CastInst *BCI = BitCastInst::CreatePointerCast(VI.getOperand(0), VoidPtrTy, "", &VI); - std::vectorArgs; - Args.push_back(BCI); - Args.push_back(getTypeMarkerConstant(&VI)); - Args.push_back(getTagCounter()); - CallInst::Create(checkVAArg, Args.begin(), Args.end(), "", &VI); - return false; -} + } // Insert code to initialize meta data to bottom // Insert code to set objects to 0 @@ -1630,7 +1638,7 @@ const FunctionType *FOldType = cast((cast(OrigType))->getElementType()); std::vectorTP; TP.push_back(Int64Ty); - TP.push_back(VoidPtrTy); + TP.push_back(TypeTagPtrTy); for(llvm::FunctionType::param_iterator ArgI = FOldType->param_begin(); ArgI != FOldType->param_end(); ++ArgI) TP.push_back(*ArgI); @@ -1640,14 +1648,11 @@ inst_iterator InsPt = inst_begin(I->getParent()->getParent()); - - - if(isa(I)) { unsigned int NumArgs = I->getNumOperands() - 1; Value *NumArgsVal = ConstantInt::get(Int32Ty, NumArgs); - AllocaInst *AI = new AllocaInst(Int8Ty, NumArgsVal, "", &*InsPt); + AllocaInst *AI = new AllocaInst(TypeTagTy, NumArgsVal, "", &*InsPt); for(unsigned int i = 1; i < I->getNumOperands(); i++) { Value *Idx[2]; Idx[0] = ConstantInt::get(Int32Ty, i-1); @@ -1675,7 +1680,7 @@ unsigned int NumArgs = I->getNumOperands() - 3; Value *NumArgsVal = ConstantInt::get(Int32Ty, NumArgs); - AllocaInst *AI = new AllocaInst(Int8Ty, NumArgsVal, "", &*InsPt); + AllocaInst *AI = new AllocaInst(TypeTagTy, NumArgsVal, "", &*InsPt); for(unsigned int i = 3; i < I->getNumOperands(); i++) { Value *Idx[2]; Idx[0] = ConstantInt::get(Int32Ty, i-3); @@ -1746,7 +1751,7 @@ CastInst *BCI = BitCastInst::CreatePointerCast(LI.getPointerOperand(), VoidPtrTy, "", &LI); Value *Size = ConstantInt::get(Int32Ty, getSize(LI.getType())); - AllocaInst *AI = new AllocaInst(Int8Ty, Size, "", &*InsPt); + AllocaInst *AI = new AllocaInst(TypeTagTy, Size, "", &*InsPt); CastInst *BCI_MD = BitCastInst::CreatePointerCast(AI, VoidPtrTy, "", &*InsPt); std::vectorArgs1; @@ -1801,7 +1806,6 @@ getTypeCall->eraseFromParent(); } - // Create the call to the runtime check and place it before the load instruction. numLoadChecks++; return true; Modified: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp?rev=133650&r1=133649&r2=133650&view=diff ============================================================================== --- poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp (original) +++ poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Wed Jun 22 16:17:19 2011 @@ -25,7 +25,7 @@ * For now, run a version of the tool without the base fixed, and * choose address. */ -#define BASE ((uint8_t *)(0x2aaaab88c000)) +#define BASE ((TypeTagTy *)(0x2aaaab88c000)) /* * Do some macro magic to get mmap macros defined properly on all platforms. */ @@ -33,17 +33,19 @@ # define MAP_ANONYMOUS MAP_ANON #endif /* defined(MAP_ANON) && !defined(MAP_ANONYMOUS) */ +typedef uint8_t TypeTagTy ; + struct va_info { uint64_t numElements; uint64_t counter; - uint8_t *metadata; + TypeTagTy *metadata; }; // Map to store info about va lists std::map VA_InfoMap; // Pointer to the shadow_memory -uint8_t * const shadow_begin = BASE; +TypeTagTy * const shadow_begin = BASE; // Map from type numbers to type names. extern char* typeNames[]; @@ -53,22 +55,22 @@ void shadowInit(); void trackArgvType(int argc, char **argv) ; void trackEnvpType(char **envp) ; - void trackGlobal(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) ; + void trackGlobal(void *ptr, TypeTagTy typeNumber, uint64_t size, uint32_t tag) ; void trackArray(void *ptr, uint64_t size, uint64_t count, uint32_t tag) ; - void trackStoreInst(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) ; + void trackStoreInst(void *ptr, TypeTagTy typeNumber, uint64_t size, uint32_t tag) ; void trackStringInput(void *ptr, uint32_t tag) ; - void compareTypes(uint8_t typeNumberSrc, uint8_t typeNumberDest, uint32_t tag) ; + void compareTypes(TypeTagTy typeNumberSrc, TypeTagTy typeNumberDest, uint32_t tag) ; void compareNumber(uint64_t NumArgsPassed, uint64_t ArgAccessed, uint32_t tag); void compareTypeAndNumber(uint64_t NumArgsPassed, uint64_t ArgAccessed, uint8_t TypeAccessed, void *MD, uint32_t tag) ; - void checkVAArgType(void *va_list, uint8_t TypeAccessed, uint32_t tag) ; - void getTypeTag(void *ptr, uint64_t size, uint8_t *dest) ; - void checkType(uint8_t typeNumber, uint64_t size, uint8_t *metadata, void *ptr, uint32_t tag); + void checkVAArgType(void *va_list, TypeTagTy TypeAccessed, uint32_t tag) ; + void getTypeTag(void *ptr, uint64_t size, TypeTagTy *dest) ; + void checkType(TypeTagTy typeNumber, uint64_t size, TypeTagTy *metadata, void *ptr, uint32_t tag); void trackInitInst(void *ptr, uint64_t size, uint32_t tag) ; void trackUnInitInst(void *ptr, uint64_t size, uint32_t tag) ; void copyTypeInfo(void *dstptr, void *srcptr, uint64_t size, uint32_t tag) ; void setTypeInfo(void *dstptr, void *metadata, uint64_t size, uint32_t tag) ; - void setVAInfo(void *va_list, uint64_t totalCount, uint8_t *metadata_ptr) ; - void copyVAInfo(void *va_list_dst, uint8_t *va_list_src) ; + void setVAInfo(void *va_list, uint64_t totalCount, TypeTagTy *metadata_ptr) ; + void copyVAInfo(void *va_list_dst, void *va_list_src) ; void trackctype(void *ptr, uint32_t tag) ; void trackctype_32(void *ptr, uint32_t tag) ; void trackStrncpyInst(void *dst, void *src, uint64_t size, uint32_t tag) ; @@ -131,7 +133,7 @@ /** * Record the global type and address in the shadow memory. */ -void trackGlobal(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) { +void trackGlobal(void *ptr, TypeTagTy typeNumber, uint64_t size, uint32_t tag) { uintptr_t p = maskAddress(ptr); shadow_begin[p] = typeNumber; memset(&shadow_begin[p + 1], 0, size - 1); @@ -157,7 +159,7 @@ /** * Record the stored type and address in the shadow memory. */ -void trackStoreInst(void *ptr, uint8_t typeNumber, uint64_t size, uint32_t tag) { +void trackStoreInst(void *ptr, TypeTagTy typeNumber, uint64_t size, uint32_t tag) { uintptr_t p = maskAddress(ptr); shadow_begin[p] = typeNumber; memset(&shadow_begin[p + 1], 0, size - 1); @@ -177,7 +179,7 @@ /** * Check that the two types match */ -void compareTypes(uint8_t typeNumberSrc, uint8_t typeNumberDest, uint32_t tag) { +void compareTypes(TypeTagTy typeNumberSrc, TypeTagTy typeNumberDest, uint32_t tag) { if(typeNumberSrc != typeNumberDest) { printf("Type mismatch(%u): expecting %s, found %s! \n", tag, typeNames[typeNumberDest], typeNames[typeNumberSrc]); } @@ -197,7 +199,7 @@ * Check that no. of arguments is less than passed * Check that the type being accessed is correct */ -void checkVAArgType(void *va_list, uint8_t TypeAccessed, uint32_t tag) { +void checkVAArgType(void *va_list, TypeTagTy TypeAccessed, uint32_t tag) { va_info v = VA_InfoMap[va_list]; compareNumber(v.numElements, v.counter, tag); compareTypes(TypeAccessed, v.metadata[v.counter], tag); @@ -209,7 +211,7 @@ * For loads, return the metadata(for size bytes) stored at the ptr * Store it in dest */ -void getTypeTag(void *ptr, uint64_t size, uint8_t *dest) { +void getTypeTag(void *ptr, uint64_t size, TypeTagTy *dest) { uintptr_t p = maskAddress(ptr); assert(p + size < SIZE); @@ -221,7 +223,7 @@ * ptr and tag are for debugging */ void __attribute__((always_inline)) -checkType(uint8_t typeNumber, uint64_t size, uint8_t *metadata, void *ptr, uint32_t tag) { +checkType(TypeTagTy typeNumber, uint64_t size, TypeTagTy *metadata, void *ptr, uint32_t tag) { /* Check if this an initialized but untyped memory.*/ if (typeNumber != metadata[0]) { if (metadata[0] != 0xFF) { @@ -295,7 +297,7 @@ /** * Initialize the metadata for a given VAList */ -void setVAInfo(void *va_list, uint64_t totalCount, uint8_t *metadata_ptr, uint32_t tag) { +void setVAInfo(void *va_list, uint64_t totalCount, TypeTagTy *metadata_ptr, uint32_t tag) { struct va_info v = {totalCount, 0, metadata_ptr}; VA_InfoMap[va_list] = v; } @@ -303,7 +305,7 @@ /** * Copy va list metadata from one list to the other. */ -void copyVAInfo(void *va_list_dst, uint8_t *va_list_src, uint32_t tag) { +void copyVAInfo(void *va_list_dst, void *va_list_src, uint32_t tag) { VA_InfoMap[va_list_dst] = VA_InfoMap[va_list_src]; } From aggarwa4 at illinois.edu Wed Jun 22 16:31:41 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Wed, 22 Jun 2011 21:31:41 -0000 Subject: [llvm-commits] [poolalloc] r133651 - in /poolalloc/trunk: lib/AssistDS/TypeChecks.cpp test/TEST.types.Makefile Message-ID: <20110622213141.8DC502A6C12C@llvm.org> Author: aggarwa4 Date: Wed Jun 22 16:31:41 2011 New Revision: 133651 URL: http://llvm.org/viewvc/llvm-project?rev=133651&view=rev Log: Switch flag. Disable pointer type checks by default. Reflect change in makefile Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp poolalloc/trunk/test/TEST.types.Makefile Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=133651&r1=133650&r2=133651&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Wed Jun 22 16:31:41 2011 @@ -40,8 +40,8 @@ STATISTIC(numTypes, "Number of Types used in the module"); namespace { - static cl::opt DisablePointerTypeChecks("disable-ptr-type-checks", - cl::desc("DONT Distinguish pointer types"), + static cl::opt EnablePointerTypeChecks("enable-ptr-type-checks", + cl::desc("Distinguish pointer types in loads"), cl::Hidden, cl::init(false)); static cl::opt DisablePtrCmpChecks("no-ptr-cmp-checks", @@ -88,7 +88,7 @@ static Constant *checkVAArg; unsigned int TypeChecks::getTypeMarker(const Type * Ty) { - if(DisablePointerTypeChecks) { + if(!EnablePointerTypeChecks) { if(Ty->isPointerTy()) { Ty = VoidPtrTy; } Modified: poolalloc/trunk/test/TEST.types.Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/TEST.types.Makefile?rev=133651&r1=133650&r2=133651&view=diff ============================================================================== --- poolalloc/trunk/test/TEST.types.Makefile (original) +++ poolalloc/trunk/test/TEST.types.Makefile Wed Jun 22 16:31:41 2011 @@ -13,8 +13,6 @@ # Pathname to poolalloc object tree PADIR := $(LLVM_OBJ_ROOT)/projects/poolalloc -LLC := /localhome/aggarwa4/llvm29/llvm-obj/Debug+Asserts/bin/llc - # Pathame to the DSA pass dynamic library DSA_SO := $(PADIR)/$(CONFIGURATION)/lib/libLLVMDataStructure$(SHLIBEXT) ASSIST_SO := $(PADIR)/$(CONFIGURATION)/lib/libAssistDS$(SHLIBEXT) @@ -33,6 +31,8 @@ ANALYZE_OPTS += -instcount -disable-verify MEM := -track-memory -time-passes -disable-output +LDFLAGS += -lstdc++ + #SAFE_OPTS := -internalize -scalarrepl -deadargelim -globaldce -basiccg -inline SAFE_OPTS := -internalize -mem2reg -constprop -ipsccp -dce -deadargelim -globaldce -basiccg -inline SAFE_OPTS1 := -internalize -deadargelim -globaldce -basiccg -inline @@ -66,7 +66,7 @@ $(PROGRAMS_TO_TEST:%=Output/%.tcd.bc): \ Output/%.tcd.bc: Output/%.opt.bc $(LOPT) $(ASSIST_SO) - -$(RUNOPT) -load $(ASSIST_SO) -typechecks -disable-ptr-type-checks -dce -ipsccp -dce -stats -info-output-file=$(CURDIR)/$@.info $< -f -o $@.temp + -$(RUNOPT) -load $(ASSIST_SO) -typechecks -enable-ptr-type-checks -dce -ipsccp -dce -stats -info-output-file=$(CURDIR)/$@.info $< -f -o $@.temp -$(LLVMLD) -disable-opt -o $@.ld $@.temp $(TYPE_RT_BC) -$(LOPT) $(SAFE_OPTS) $@.ld.bc -o $@ -f #-$(RUNOPT) -load $(ASSIST_SO) $(SAFE_OPTS) -typechecks-runtime-opt $@.ld.bc -o $@ -f @@ -87,7 +87,7 @@ $(PROGRAMS_TO_TEST:%=Output/%.tcoo1.bc): \ Output/%.tcoo1.bc: Output/%.opt.bc $(LOPT) $(ASSIST_SO) - -$(RUNOPT) -load $(ASSIST_SO) -typechecks -enable-type-inference-opts -dsa-stdlib-no-fold -typechecks-opt -typechecks-cmp-opt -dce -ipsccp -dce -stats -info-output-file=$(CURDIR)/$@.info $< -f -o $@.temp + -$(RUNOPT) -load $(ASSIST_SO) -typechecks -no-ptr-cmp-checks -enable-type-inference-opts -dsa-stdlib-no-fold -typechecks-opt -dce -ipsccp -dce -stats -info-output-file=$(CURDIR)/$@.info $< -f -o $@.temp -$(LLVMLD) -disable-opt -o $@.ld $@.temp $(TYPE_RT_BC) -$(LOPT) $(SAFE_OPTS) $@.ld.bc -o $@ -f #-$(RUNOPT) -load $(ASSIST_SO) $(SAFE_OPTS) -typechecks-runtime-opt $@.ld.bc -o $@ -f @@ -288,7 +288,7 @@ $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ -Output/%.$(TEST).report.txt: Output/%.opt.bc Output/%.LOC.txt $(LOPT) Output/%.out-nat Output/%.diff-llvm1 Output/%.diff-opt Output/%.diff-tc Output/%.diff-tco Output/%.diff-tcoo Output/%.diff-tcd Output/%.diff-count Output/%.diff-count1 +Output/%.$(TEST).report.txt: Output/%.opt.bc Output/%.LOC.txt $(LOPT) Output/%.out-nat Output/%.diff-llvm1 Output/%.diff-opt Output/%.diff-tc Output/%.diff-tco Output/%.diff-tcoo Output/%.diff-tcd Output/%.diff-count Output/%.diff-count1 Output/%.diff-tcoo1 @# Gather data -($(RUNOPT) -dsa-$(PASS) -enable-type-inference-opts -dsa-stdlib-no-fold $(ANALYZE_OPTS) $<)> $@.time.1 2>&1 -($(RUNOPT) -dsa-$(PASS) $(ANALYZE_OPTS) $<)> $@.time.2 2>&1 From jstaszak at apple.com Wed Jun 22 16:39:56 2011 From: jstaszak at apple.com (Jakub Staszak) Date: Wed, 22 Jun 2011 14:39:56 -0700 Subject: [llvm-commits] BlockFrequency for BasicBlocks In-Reply-To: References: <1E9CE6F5-A2AC-4A81-A001-D19DAB65255B@apple.com> <98818310-FEB0-4E4D-8B38-E14698BFD9BE@apple.com> Message-ID: <51D0DA66-26B3-44D5-8384-A31CC30E14EB@apple.com> On Jun 21, 2011, at 8:21 PM, Andrew Trick wrote: > > Yes, by "1" I meant literal 1, not scaled 1. I think this could happen inside getEdgeFreq() when (N * getBlockFreq(Src)) < D. You should probably check for that case and return the smallest nonzero frequency. > > You actually shouldn't have a problem in divBlockFreq, but somewhere you should assert that the input BranchProbability is well-formed (N < D). The bug was in the complete different place. Instead of using backedge probability info (probability of getting to DST block through SRC block) i used edge probability. It caused some problem in very rare cases (only during benchmarking). > -Andy > > -------------- next part -------------- A non-text attachment was scrubbed... Name: bf4bb.5.patch Type: application/octet-stream Size: 20597 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110622/9b184e86/attachment.obj From aggarwa4 at illinois.edu Wed Jun 22 16:42:19 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Wed, 22 Jun 2011 21:42:19 -0000 Subject: [llvm-commits] [poolalloc] r133652 - /poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Message-ID: <20110622214219.D89872A6C12C@llvm.org> Author: aggarwa4 Date: Wed Jun 22 16:42:19 2011 New Revision: 133652 URL: http://llvm.org/viewvc/llvm-project?rev=133652&view=rev Log: Fix some prototypes. Modified: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Modified: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp?rev=133652&r1=133651&r2=133652&view=diff ============================================================================== --- poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp (original) +++ poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Wed Jun 22 16:42:19 2011 @@ -69,8 +69,8 @@ void trackUnInitInst(void *ptr, uint64_t size, uint32_t tag) ; void copyTypeInfo(void *dstptr, void *srcptr, uint64_t size, uint32_t tag) ; void setTypeInfo(void *dstptr, void *metadata, uint64_t size, uint32_t tag) ; - void setVAInfo(void *va_list, uint64_t totalCount, TypeTagTy *metadata_ptr) ; - void copyVAInfo(void *va_list_dst, void *va_list_src) ; + void setVAInfo(void *va_list, uint64_t totalCount, TypeTagTy *metadata_ptr, uint32_t tag) ; + void copyVAInfo(void *va_list_dst, void *va_list_src, uint32_t tag) ; void trackctype(void *ptr, uint32_t tag) ; void trackctype_32(void *ptr, uint32_t tag) ; void trackStrncpyInst(void *dst, void *src, uint64_t size, uint32_t tag) ; From isanbard at gmail.com Wed Jun 22 17:22:25 2011 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 22 Jun 2011 22:22:25 -0000 Subject: [llvm-commits] [llvm] r133658 - in /llvm/trunk: include/llvm/Target/TargetLoweringObjectFile.h lib/CodeGen/TargetLoweringObjectFileImpl.cpp lib/Target/TargetLoweringObjectFile.cpp Message-ID: <20110622222225.128862A6C12C@llvm.org> Author: void Date: Wed Jun 22 17:22:24 2011 New Revision: 133658 URL: http://llvm.org/viewvc/llvm-project?rev=133658&view=rev Log: Add a __LD,__compact_unwind section. If the linker supports it, this will hold the CIE and FDE information in a compact format. The implementation of the compact unwinding emission is coming soon. Modified: llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp Modified: llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h?rev=133658&r1=133657&r2=133658&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h (original) +++ llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h Wed Jun 22 17:22:24 2011 @@ -68,6 +68,11 @@ /// LSDASection - If exception handling is supported by the target, this is /// the section the Language Specific Data Area information is emitted to. const MCSection *LSDASection; + + /// CompactUnwindSection - If exception handling is supported by the target + /// and the target can support a compact representation of the CIE and FDE, + /// this is the section to emit them into. + const MCSection *CompactUnwindSection; // Dwarf sections for debug info. If a target supports debug info, these must // be set. @@ -132,6 +137,7 @@ const MCSection *getStaticCtorSection() const { return StaticCtorSection; } const MCSection *getStaticDtorSection() const { return StaticDtorSection; } const MCSection *getLSDASection() const { return LSDASection; } + const MCSection *getCompactUnwindSection() const{return CompactUnwindSection;} virtual const MCSection *getEHFrameSection() const = 0; virtual void emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=133658&r1=133657&r2=133658&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original) +++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Wed Jun 22 17:22:24 2011 @@ -605,6 +605,12 @@ // Exception Handling. LSDASection = getContext().getMachOSection("__TEXT", "__gcc_except_tab", 0, SectionKind::getReadOnlyWithRel()); + + CompactUnwindSection = + getContext().getMachOSection("__LD", "__compact_unwind", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getReadOnly()); + // Debug Information. DwarfAbbrevSection = getContext().getMachOSection("__DWARF", "__debug_abbrev", Modified: llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp?rev=133658&r1=133657&r2=133658&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp (original) +++ llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp Wed Jun 22 17:22:24 2011 @@ -43,6 +43,7 @@ StaticCtorSection = 0; StaticDtorSection = 0; LSDASection = 0; + CompactUnwindSection = 0; CommDirectiveSupportsAlignment = true; DwarfAbbrevSection = 0; From rafael.espindola at gmail.com Wed Jun 22 17:31:57 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 22 Jun 2011 22:31:57 -0000 Subject: [llvm-commits] [llvm] r133659 - in /llvm/trunk: lib/CodeGen/TailDuplication.cpp test/CodeGen/X86/tail-dup-addr.ll Message-ID: <20110622223157.B82D62A6C12C@llvm.org> Author: rafael Date: Wed Jun 22 17:31:57 2011 New Revision: 133659 URL: http://llvm.org/viewvc/llvm-project?rev=133659&view=rev Log: Reenable tail duplication of bb with just an unconditional jump, but don't remove blocks that have their address taken. Added: llvm/trunk/test/CodeGen/X86/tail-dup-addr.ll Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=133659&r1=133658&r2=133659&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Wed Jun 22 17:31:57 2011 @@ -207,7 +207,7 @@ // TailBB's immediate successors are now successors of those predecessors // which duplicated TailBB. Add the predecessors as sources to the PHI // instructions. - bool isDead = MBB->pred_empty(); + bool isDead = MBB->pred_empty() && !MBB->hasAddressTaken(); if (PreRegAlloc) UpdateSuccessorsPHIs(MBB, isDead, TDBBs, Succs); @@ -568,9 +568,9 @@ TailDuplicatePass::isSimpleBB(MachineBasicBlock *TailBB) { if (TailBB->succ_size() != 1) return false; - MachineBasicBlock::iterator I = TailBB->getFirstNonPHI(); + MachineBasicBlock::iterator I = TailBB->begin(); MachineBasicBlock::iterator E = TailBB->end(); - while (I->isDebugValue() && I != E) + while (I != E && I->isDebugValue()) ++I; if (I == E) return true; @@ -712,7 +712,7 @@ DenseSet UsedByPhi; getRegsUsedByPHIs(*TailBB, &UsedByPhi); - if (0 && isSimpleBB(TailBB)) + if (isSimpleBB(TailBB)) return duplicateSimpleBB(TailBB, TDBBs, UsedByPhi, Copies); // Iterate through all the unique predecessors and tail-duplicate this Added: llvm/trunk/test/CodeGen/X86/tail-dup-addr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tail-dup-addr.ll?rev=133659&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/tail-dup-addr.ll (added) +++ llvm/trunk/test/CodeGen/X86/tail-dup-addr.ll Wed Jun 22 17:31:57 2011 @@ -0,0 +1,28 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s + +; Test that we don't drop a block that has its address taken. + +; CHECK: Ltmp1: ## Block address taken +; CHECK: Ltmp2: ## Block address taken + + at a = common global i32 0, align 4 + at p = common global i8* null, align 8 + +define void @foo() noreturn nounwind uwtable ssp { +entry: + %tmp = load i32* @a, align 4 + %foo = icmp eq i32 0, %tmp + br i1 %foo, label %sw.bb, label %sw.default + +sw.bb: ; preds = %entry + store i8* blockaddress(@foo, %sw.bb1), i8** @p, align 8 + br label %sw.bb1 + +sw.bb1: ; preds = %sw.default, %sw.bb, %entry + store i8* blockaddress(@foo, %sw.default), i8** @p, align 8 + br label %sw.default + +sw.default: ; preds = %sw.bb1, %entry + store i8* blockaddress(@foo, %sw.bb1), i8** @p, align 8 + br label %sw.bb1 +} From mttjwl at gmail.com Wed Jun 22 17:57:27 2011 From: mttjwl at gmail.com (Matthew Wala) Date: Wed, 22 Jun 2011 22:57:27 -0000 Subject: [llvm-commits] [poolalloc] r133661 - /poolalloc/trunk/lib/DSA/StdLibPass.cpp Message-ID: <20110622225727.573FB2A6C12C@llvm.org> Author: wala1 Date: Wed Jun 22 17:57:27 2011 New Revision: 133661 URL: http://llvm.org/viewvc/llvm-project?rev=133661&view=rev Log: Allow DSA to recognize pool_fprintf(), pool_sprintf(), pool_snprintf(). 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=133661&r1=133660&r2=133661&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original) +++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Wed Jun 22 17:57:27 2011 @@ -302,6 +302,9 @@ {"sc.fsparameter", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, {"sc.fscallinfo", {NRET_YARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, {"pool_printf", {NRET_YARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, + {"pool_fprintf", {NRET_YARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, + {"pool_sprintf", {NRET_YARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, + {"pool_snprintf", {NRET_YARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, // Type Checks {"trackGlobal", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}}, From xi.wang at gmail.com Wed Jun 22 16:09:00 2011 From: xi.wang at gmail.com (Xi Wang) Date: Wed, 22 Jun 2011 17:09:00 -0400 Subject: [llvm-commits] [PATCH] ConstantRange::sub In-Reply-To: References: <01F9FA28-E4FB-4D8A-9A67-C445041842B9@gmail.com> <4B12B5B1-CFC3-40CA-9F02-D3D7D5378F5B@gmail.com> Message-ID: Here goes the patch along with a test for ConstantRange::sub. Thanks. -------------- next part -------------- A non-text attachment was scrubbed... Name: crsub.patch Type: application/octet-stream Size: 1293 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110622/bf6f65b9/attachment.obj -------------- next part -------------- On Jun 22, 2011, at 3:57 PM, Nick Lewycky wrote: > On 22 June 2011 12:51, Xi Wang wrote: > Sure. I will submit a patch. > > BTW, what's the difference between the bounds I was expecting > > APInt NewLower = getLower() - Other.getUpper() + 1; > APInt NewUpper = getUpper() - Other.getLower(); > > and the two you mentioned > > NewLower = Lower - (Upper-1) > NewUpper = (Upper-1) - Lower + 1 > > They look equivalent to me. Did I miss anything? Thanks. > > ... they are. Sorry, I was just surprised to see the +1 on the NewLower (it always goes on the NewUpper instead, right), but I didn't actually simplify the expressions. > > It sounds to me like you've got this one handled. :-) > > Nick > > > - xi > > On Jun 22, 2011, at 2:39 PM, Nick Lewycky wrote: > > > Thanks, I think you've found a serious bug! > > > > Would you be willing to fix it? Please add a test to unittests/Support/ConstantRangeTest.cpp and then mail llvm-commits with the patch to fix it and add the test. > > > > On 20 June 2011 23:09, Xi Wang wrote: > > Hi, > > > > I have a question about ConstantRange::sub(const ConstantRange &Other) at lib/Support/ConstantRange.cpp:524. The code computes the new bounds as follows. > > > > APInt NewLower = getLower() - Other.getLower(); > > APInt NewUpper = getUpper() - Other.getUpper() + 1; > > > > Could someone explain this to me? I was expecting something like > > > > APInt NewLower = getLower() - Other.getUpper() + 1; > > APInt NewUpper = getUpper() - Other.getLower(); > > > > These aren't quite right, I think it should be: > > > > NewLower = Lower - (Upper-1) > > NewUpper = (Upper-1) - Lower + 1 > > > > Constant ranges are stored half-open, [lower, upper) which means that the upper value is one past the end of the range. I often think of the formula as newmax = max - min --> newupper - 1 = ((getUpper() - 1) - Other.getLower(). min = lower, while max = upper - 1. > > > > Nick > > From isanbard at gmail.com Wed Jun 22 18:16:51 2011 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 22 Jun 2011 23:16:51 -0000 Subject: [llvm-commits] [llvm] r133662 - in /llvm/trunk: include/llvm/Target/TargetLoweringObjectFile.h lib/CodeGen/TargetLoweringObjectFileImpl.cpp lib/Target/TargetLoweringObjectFile.cpp Message-ID: <20110622231651.3840E2A6C12C@llvm.org> Author: void Date: Wed Jun 22 18:16:51 2011 New Revision: 133662 URL: http://llvm.org/viewvc/llvm-project?rev=133662&view=rev Log: Add a flag that indicates whether a target supports compact unwind info or not. Modified: llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp Modified: llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h?rev=133662&r1=133661&r2=133662&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h (original) +++ llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h Wed Jun 22 18:16:51 2011 @@ -107,8 +107,12 @@ /// private linkage, aka an L or .L label) or false if it should be a normal /// non-.globl label. This defaults to true. bool IsFunctionEHFrameSymbolPrivate; + + /// SupportsCompactUnwindInfo - This flag is set to true if the CIE and FDE + /// information should be emitted in a compact form. + bool SupportsCompactUnwindInfo; + public: - MCContext &getContext() const { return *Ctx; } virtual ~TargetLoweringObjectFile(); @@ -126,10 +130,12 @@ bool getSupportsWeakOmittedEHFrame() const { return SupportsWeakOmittedEHFrame; } - bool getCommDirectiveSupportsAlignment() const { return CommDirectiveSupportsAlignment; } + bool getSupportsCompactUnwindInfo() const { + return SupportsCompactUnwindInfo; + } const MCSection *getTextSection() const { return TextSection; } const MCSection *getDataSection() const { return DataSection; } Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=133662&r1=133661&r2=133662&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original) +++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Wed Jun 22 18:16:51 2011 @@ -487,8 +487,12 @@ // .comm doesn't support alignment before Leopard. Triple T(((LLVMTargetMachine&)TM).getTargetTriple()); - if (T.isMacOSX() && T.isMacOSXVersionLT(10, 5)) - CommDirectiveSupportsAlignment = false; + if (T.isMacOSX()) { + if (T.isMacOSXVersionLT(10, 5)) + CommDirectiveSupportsAlignment = false; + if (!T.isMacOSXVersionLT(10, 6)) + SupportsCompactUnwindInfo = true; + } TargetLoweringObjectFile::Initialize(Ctx, TM); Modified: llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp?rev=133662&r1=133661&r2=133662&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp (original) +++ llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp Wed Jun 22 18:16:51 2011 @@ -61,6 +61,7 @@ IsFunctionEHFrameSymbolPrivate = true; SupportsWeakOmittedEHFrame = true; + SupportsCompactUnwindInfo = false; } TargetLoweringObjectFile::~TargetLoweringObjectFile() { From atrick at apple.com Wed Jun 22 18:23:19 2011 From: atrick at apple.com (Andrew Trick) Date: Wed, 22 Jun 2011 23:23:19 -0000 Subject: [llvm-commits] [llvm] r133664 - in /llvm/trunk: cmake/modules/HandleLLVMOptions.cmake test/CodeGen/X86/2011-06-14-PreschedRegalias.ll test/Makefile test/lit.cfg test/lit.site.cfg.in utils/lit/lit/TestRunner.py utils/lit/lit/TestingConfig.py Message-ID: <20110622232319.9B2BE2A6C12C@llvm.org> Author: atrick Date: Wed Jun 22 18:23:19 2011 New Revision: 133664 URL: http://llvm.org/viewvc/llvm-project?rev=133664&view=rev Log: lit support for REQUIRES: asserts. Take #2. Don't piggyback on the existing config.build_mode. Instead, define a new lit feature for each build feature we need (currently just "asserts"). Teach both autoconf'd and cmake'd Makefiles to define this feature within test/lit.site.cfg. This doesn't require any lit harness changes and should be more robust across build systems. Modified: llvm/trunk/cmake/modules/HandleLLVMOptions.cmake llvm/trunk/test/CodeGen/X86/2011-06-14-PreschedRegalias.ll llvm/trunk/test/Makefile llvm/trunk/test/lit.cfg llvm/trunk/test/lit.site.cfg.in llvm/trunk/utils/lit/lit/TestRunner.py llvm/trunk/utils/lit/lit/TestingConfig.py Modified: llvm/trunk/cmake/modules/HandleLLVMOptions.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/HandleLLVMOptions.cmake?rev=133664&r1=133663&r2=133664&view=diff ============================================================================== --- llvm/trunk/cmake/modules/HandleLLVMOptions.cmake (original) +++ llvm/trunk/cmake/modules/HandleLLVMOptions.cmake Wed Jun 22 18:23:19 2011 @@ -36,13 +36,8 @@ # explicitly undefine it: if( uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) add_definitions( -UNDEBUG ) - set(LLVM_BUILD_MODE "Release") - else() - set(LLVM_BUILD_MODE "Debug") endif() - set(LLVM_BUILD_MODE "${LLVM_BUILD_MODE}+Asserts") else() - set(LLVM_BUILD_MODE "Release") if( NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) if( NOT MSVC_IDE AND NOT XCODE ) add_definitions( -DNDEBUG ) Modified: llvm/trunk/test/CodeGen/X86/2011-06-14-PreschedRegalias.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2011-06-14-PreschedRegalias.ll?rev=133664&r1=133663&r2=133664&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2011-06-14-PreschedRegalias.ll (original) +++ llvm/trunk/test/CodeGen/X86/2011-06-14-PreschedRegalias.ll Wed Jun 22 18:23:19 2011 @@ -1,5 +1,5 @@ ; RUN: llc < %s -march=x86-64 -stress-sched | FileCheck %s -; REQUIRES: Asserts +; REQUIRES: asserts ; Test interference between physreg aliases during preRAsched. ; mul wants an operand in AL, but call clobbers it. Modified: llvm/trunk/test/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Makefile?rev=133664&r1=133663&r2=133664&view=diff ============================================================================== --- llvm/trunk/test/Makefile (original) +++ llvm/trunk/test/Makefile Wed Jun 22 18:23:19 2011 @@ -171,15 +171,21 @@ @test ! -f site.exp || mv site.exp site.bak @mv site.tmp site.exp +ifeq ($(DISABLE_ASSERTIONS),1) +ENABLE_ASSERTIONS=0 +else +ENABLE_ASSERTIONS=1 +endif + lit.site.cfg: site.exp @echo "Making LLVM 'lit.site.cfg' file..." @$(ECHOPATH) s=@LLVM_SOURCE_DIR@=$(LLVM_SRC_ROOT)=g > lit.tmp @$(ECHOPATH) s=@LLVM_BINARY_DIR@=$(LLVM_OBJ_ROOT)=g >> lit.tmp @$(ECHOPATH) s=@LLVM_TOOLS_DIR@=$(ToolDir)=g >> lit.tmp - @$(ECHOPATH) s=@LLVM_BUILD_MODE@=$(BuildMode)=g >> lit.tmp @$(ECHOPATH) s=@LLVMGCCDIR@=$(LLVMGCCDIR)=g >> lit.tmp @$(ECHOPATH) s=@PYTHON_EXECUTABLE@=python=g >> lit.tmp @$(ECHOPATH) s=@ENABLE_SHARED@=$(ENABLE_SHARED)=g >> lit.tmp + @$(ECHOPATH) s=@LLVM_ENABLE_ASSERTIONS@=$(ENABLE_ASSERTIONS)=g >> lit.tmp @sed -f lit.tmp $(PROJ_SRC_DIR)/lit.site.cfg.in > $@ @-rm -f lit.tmp Modified: llvm/trunk/test/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=133664&r1=133663&r2=133664&view=diff ============================================================================== --- llvm/trunk/test/lit.cfg (original) +++ llvm/trunk/test/lit.cfg Wed Jun 22 18:23:19 2011 @@ -306,3 +306,6 @@ if loadable_module: config.available_features.add('loadable_module') + +if config.enable_assertions: + config.available_features.add('asserts') Modified: llvm/trunk/test/lit.site.cfg.in URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.site.cfg.in?rev=133664&r1=133663&r2=133664&view=diff ============================================================================== --- llvm/trunk/test/lit.site.cfg.in (original) +++ llvm/trunk/test/lit.site.cfg.in Wed Jun 22 18:23:19 2011 @@ -5,9 +5,9 @@ config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" config.llvmgcc_dir = "@LLVMGCCDIR@" config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" -config.llvm_build_modes = "@LLVM_BUILD_MODE@".split('+') config.python_executable = "@PYTHON_EXECUTABLE@" config.enable_shared = @ENABLE_SHARED@ +config.enable_assertions = @LLVM_ENABLE_ASSERTIONS@ # Support substitution of the tools_dir with user parameters. This is # used when we can't determine the tool dir at configuration time. Modified: llvm/trunk/utils/lit/lit/TestRunner.py URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/TestRunner.py?rev=133664&r1=133663&r2=133664&view=diff ============================================================================== --- llvm/trunk/utils/lit/lit/TestRunner.py (original) +++ llvm/trunk/utils/lit/lit/TestRunner.py Wed Jun 22 18:23:19 2011 @@ -473,11 +473,9 @@ if script[-1][-1] == '\\': return (Test.UNRESOLVED, "Test has unterminated run lines (with '\\')") - # Check that we have the required features or build modes: + # Check that we have the required features: missing_required_features = [f for f in requires - if f not in test.config.available_features - and f not in test.config.llvm_build_modes] - + if f not in test.config.available_features] if missing_required_features: msg = ', '.join(missing_required_features) return (Test.UNSUPPORTED, Modified: llvm/trunk/utils/lit/lit/TestingConfig.py URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/TestingConfig.py?rev=133664&r1=133663&r2=133664&view=diff ============================================================================== --- llvm/trunk/utils/lit/lit/TestingConfig.py (original) +++ llvm/trunk/utils/lit/lit/TestingConfig.py Wed Jun 22 18:23:19 2011 @@ -74,7 +74,6 @@ def clone(self, path): # FIXME: Chain implementations? - # See attribute chaining in finish() # # FIXME: Allow extra parameters? cfg = TestingConfig(self, self.name, self.suffixes, self.test_format, @@ -102,9 +101,3 @@ # files. Should we distinguish them? self.test_source_root = str(self.test_source_root) self.excludes = set(self.excludes) - - # chain attributes by copying them - if self.parent: - for k,v in vars(self.parent).items(): - if not hasattr(self, k): - setattr(self, k, v) From isanbard at gmail.com Wed Jun 22 19:09:43 2011 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 23 Jun 2011 00:09:43 -0000 Subject: [llvm-commits] [llvm] r133668 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20110623000943.9F9C12A6C12C@llvm.org> Author: void Date: Wed Jun 22 19:09:43 2011 New Revision: 133668 URL: http://llvm.org/viewvc/llvm-project?rev=133668&view=rev Log: 80-column violations. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=133668&r1=133667&r2=133668&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Jun 22 19:09:43 2011 @@ -490,7 +490,8 @@ assert(OS.tell() - Start == macho::DysymtabLoadCommandSize); } -void MachObjectWriter::WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout) { +void MachObjectWriter::WriteNlist(MachSymbolData &MSD, + const MCAsmLayout &Layout) { MCSymbolData &Data = *MSD.SymbolData; const MCSymbol &Symbol = Data.getSymbol(); uint8_t Type = 0; @@ -1058,7 +1059,8 @@ Relocations[Fragment->getParent()].push_back(MRE); } -bool MachObjectWriter::getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType, +bool MachObjectWriter::getARMFixupKindMachOInfo(unsigned Kind, + unsigned &RelocType, unsigned &Log2Size) { RelocType = unsigned(macho::RIT_Vanilla); Log2Size = ~0U; @@ -1379,10 +1381,11 @@ /// \param StringTable [out] - The string table data. /// \param StringIndexMap [out] - Map from symbol names to offsets in the /// string table. -void MachObjectWriter::ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, - std::vector &LocalSymbolData, - std::vector &ExternalSymbolData, - std::vector &UndefinedSymbolData) { +void MachObjectWriter:: +ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, + std::vector &LocalSymbolData, + std::vector &ExternalSymbolData, + std::vector &UndefinedSymbolData) { // Build section lookup table. DenseMap SectionIndexMap; unsigned Index = 1; @@ -1505,7 +1508,8 @@ } } -void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) { +void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, + const MCAsmLayout &Layout) { computeSectionAddresses(Asm, Layout); // Create symbol data for any indirect symbols. @@ -1516,11 +1520,12 @@ UndefinedSymbolData); } -bool MachObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, - const MCSymbolData &DataA, - const MCFragment &FB, - bool InSet, - bool IsPCRel) const { +bool MachObjectWriter:: +IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const { if (InSet) return true; From isanbard at gmail.com Wed Jun 22 19:12:58 2011 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 23 Jun 2011 00:12:58 -0000 Subject: [llvm-commits] [llvm] r133669 - /llvm/trunk/include/llvm/Target/TargetAsmInfo.h Message-ID: <20110623001258.50ACE2A6C12C@llvm.org> Author: void Date: Wed Jun 22 19:12:58 2011 New Revision: 133669 URL: http://llvm.org/viewvc/llvm-project?rev=133669&view=rev Log: Allow the AsmInfo to query the TLOF to see if it supports compact unwind. Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmInfo.h?rev=133669&r1=133668&r2=133669&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetAsmInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetAsmInfo.h Wed Jun 22 19:12:58 2011 @@ -79,6 +79,10 @@ return TLOF->isFunctionEHFrameSymbolPrivate(); } + bool getSupportsCompactUnwindInfo() const { + return TLOF->getSupportsCompactUnwindInfo(); + } + const unsigned *getCalleeSavedRegs(MachineFunction *MF = 0) const { return TRI->getCalleeSavedRegs(MF); } From isanbard at gmail.com Wed Jun 22 19:23:04 2011 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 23 Jun 2011 00:23:04 -0000 Subject: [llvm-commits] [llvm] r133670 - /llvm/trunk/include/llvm/Target/TargetAsmInfo.h Message-ID: <20110623002304.CBDD92A6C12C@llvm.org> Author: void Date: Wed Jun 22 19:23:04 2011 New Revision: 133670 URL: http://llvm.org/viewvc/llvm-project?rev=133670&view=rev Log: Allow the AsmInfo to query for the compact unwind section. Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmInfo.h?rev=133670&r1=133669&r2=133670&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetAsmInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetAsmInfo.h Wed Jun 22 19:23:04 2011 @@ -59,6 +59,10 @@ return TLOF->getEHFrameSection(); } + const MCSection *getCompactUnwindSection() const { + return TLOF->getCompactUnwindSection(); + } + const MCSection *getDwarfFrameSection() const { return TLOF->getDwarfFrameSection(); } From atrick at apple.com Wed Jun 22 19:47:08 2011 From: atrick at apple.com (Andrew Trick) Date: Wed, 22 Jun 2011 17:47:08 -0700 Subject: [llvm-commits] BlockFrequency for BasicBlocks In-Reply-To: <51D0DA66-26B3-44D5-8384-A31CC30E14EB@apple.com> References: <1E9CE6F5-A2AC-4A81-A001-D19DAB65255B@apple.com> <98818310-FEB0-4E4D-8B38-E14698BFD9BE@apple.com> <51D0DA66-26B3-44D5-8384-A31CC30E14EB@apple.com> Message-ID: <6926F677-27AA-4488-8AD8-E1ACE86A2E2A@apple.com> Where do you check underflow of block frequency? It seems that 10 sequential branches with default weights would result in getEdgeFreq() returning zero. I'm not sure what getBackSumForBlock() means. The previous code looks correct to me. Can you explain the problem that you're solving? Thanks. -Andy On Jun 22, 2011, at 2:39 PM, Jakub Staszak wrote: > > On Jun 21, 2011, at 8:21 PM, Andrew Trick wrote: > >> >> Yes, by "1" I meant literal 1, not scaled 1. I think this could happen inside getEdgeFreq() when (N * getBlockFreq(Src)) < D. You should probably check for that case and return the smallest nonzero frequency. >> >> You actually shouldn't have a problem in divBlockFreq, but somewhere you should assert that the input BranchProbability is well-formed (N < D). > > The bug was in the complete different place. Instead of using backedge probability info (probability of getting to DST block through SRC block) i used edge probability. It caused some problem in very rare cases (only during benchmarking). > > >> -Andy >> >> > From aggarwa4 at illinois.edu Wed Jun 22 19:57:30 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 23 Jun 2011 00:57:30 -0000 Subject: [llvm-commits] [poolalloc] r133675 - /poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp Message-ID: <20110623005731.0B1E52A6C12C@llvm.org> Author: aggarwa4 Date: Wed Jun 22 19:57:30 2011 New Revision: 133675 URL: http://llvm.org/viewvc/llvm-project?rev=133675&view=rev Log: Use TypeTagTy Modified: poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp Modified: poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp?rev=133675&r1=133674&r2=133675&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp Wed Jun 22 19:57:30 2011 @@ -41,6 +41,8 @@ static const Type *Int32Ty = 0; static const Type *Int64Ty = 0; static const PointerType *VoidPtrTy = 0; +static const Type *TypeTagTy = 0; +static const Type *TypeTagPtrTy = 0; static Constant *trackGlobal; static Constant *trackStringInput; static Constant *trackInitInst; @@ -60,11 +62,13 @@ Int32Ty = IntegerType::getInt32Ty(M.getContext()); Int64Ty = IntegerType::getInt64Ty(M.getContext()); VoidPtrTy = PointerType::getUnqual(Int8Ty); + TypeTagTy = Int8Ty; + TypeTagPtrTy = PointerType::getUnqual(TypeTagTy); trackGlobal = M.getOrInsertFunction("trackGlobal", VoidTy, VoidPtrTy,/*ptr*/ - Int8Ty,/*type*/ + TypeTagTy,/*type*/ Int64Ty,/*size*/ Int32Ty,/*tag*/ NULL); @@ -83,13 +87,13 @@ trackStoreInst = M.getOrInsertFunction("trackStoreInst", VoidTy, VoidPtrTy,/*ptr*/ - Int8Ty,/*type*/ + TypeTagTy,/*type*/ Int64Ty,/*size*/ Int32Ty,/*tag*/ NULL); checkTypeInst = M.getOrInsertFunction("checkType", VoidTy, - Int8Ty,/*type*/ + TypeTagTy,/*type*/ Int64Ty,/*size*/ VoidPtrTy, VoidPtrTy,/*ptr*/ @@ -105,7 +109,7 @@ setTypeInfo = M.getOrInsertFunction("setTypeInfo", VoidTy, VoidPtrTy,/*dest ptr*/ - VoidPtrTy,/*metadata*/ + TypeTagPtrTy,/*metadata*/ Int64Ty,/*size*/ Int32Ty,/*tag*/ NULL); From isanbard at gmail.com Wed Jun 22 20:06:23 2011 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 23 Jun 2011 01:06:23 -0000 Subject: [llvm-commits] [llvm] r133676 - /llvm/trunk/lib/MC/MCDwarf.cpp Message-ID: <20110623010623.3DFB42A6C12C@llvm.org> Author: void Date: Wed Jun 22 20:06:23 2011 New Revision: 133676 URL: http://llvm.org/viewvc/llvm-project?rev=133676&view=rev Log: Some skeleton code to emit the compact unwind. If the information is unable to be emitted in a compact way, we then default to emitting a CIE and FDE. Modified: llvm/trunk/lib/MC/MCDwarf.cpp Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=133676&r1=133675&r2=133676&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Wed Jun 22 20:06:23 2011 @@ -507,6 +507,12 @@ SectionStart(sectionStart) { } + /// EmitCompactUnwind - Emit the unwind information in a compact way. If + /// we're successful, return 'true'. Otherwise, return 'false' and it will + /// emit the normal CIE and FDE. + bool EmitCompactUnwind(MCStreamer &streamer, + const MCDwarfFrameInfo &frame); + const MCSymbol &EmitCIE(MCStreamer &streamer, const MCSymbol *personality, unsigned personalityEncoding, @@ -620,6 +626,55 @@ } } +/// EmitCompactUnwind - Emit the unwind information in a compact way. If we're +/// successful, return 'true'. Otherwise, return 'false' and it will emit the +/// normal CIE and FDE. +bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, + const MCDwarfFrameInfo &Frame) { +#if 1 + return false; +#else + MCContext &Context = Streamer.getContext(); + const TargetAsmInfo &TAI = Context.getTargetAsmInfo(); + Streamer.SwitchSection(TAI.getCompactUnwindSection()); + + unsigned FDEEncoding = TAI.getFDEEncoding(UsingCFI); + unsigned Size = getSizeForEncoding(Streamer, FDEEncoding); + + // range-start range-length compact-unwind-enc personality-func lsda + // _foo LfooEnd-_foo 0x00000023 0 0 + // _bar LbarEnd-_bar 0x00000025 __gxx_personality except_tab1 + // + // .section __LD,__compact_unwind,regular,debug + // + // # compact unwind for _foo + // .quad _foo + // .set L1,LfooEnd-_foo + // .long L1 + // .long 0x01010001 + // .quad 0 + // .quad 0 + // + // # compact unwind for _bar + // .quad _bar + // .set L2,LbarEnd-_bar + // .long L2 + // .long 0x01020011 + // .quad __gxx_personality + // .quad except_tab1 + + // Range Start + EmitSymbol(Streamer, *Frame.Begin, FDEEncoding); + + // Range Length + const MCExpr *Range = MakeStartMinusEndExpr(Streamer, *Frame.Begin, + *Frame.End, 0); + Streamer.EmitAbsValue(Range, Size); + + return true; +#endif +} + const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, const MCSymbol *personality, unsigned personalityEncoding, @@ -846,7 +901,8 @@ MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); const MCSection §ion = isEH ? - *asmInfo.getEHFrameSection() : *asmInfo.getDwarfFrameSection(); + *asmInfo.getEHFrameSection() : + *asmInfo.getDwarfFrameSection(); streamer.SwitchSection(§ion); MCSymbol *SectionStart = context.CreateTempSymbol(); streamer.EmitLabel(SectionStart); @@ -861,11 +917,17 @@ CIEKey key(frame.Personality, frame.PersonalityEncoding, frame.LsdaEncoding); const MCSymbol *&cieStart = isEH ? CIEStarts[key] : DummyDebugKey; + if (isEH && asmInfo.getSupportsCompactUnwindInfo() && + Emitter.EmitCompactUnwind(streamer, frame)) + continue; + if (!cieStart) cieStart = &Emitter.EmitCIE(streamer, frame.Personality, frame.PersonalityEncoding, frame.Lsda, frame.LsdaEncoding); + fdeEnd = Emitter.EmitFDE(streamer, *cieStart, frame); + if (i != n - 1) streamer.EmitLabel(fdeEnd); } From jstaszak at apple.com Wed Jun 22 20:16:13 2011 From: jstaszak at apple.com (Jakub Staszak) Date: Wed, 22 Jun 2011 18:16:13 -0700 Subject: [llvm-commits] BlockFrequency for BasicBlocks In-Reply-To: <6926F677-27AA-4488-8AD8-E1ACE86A2E2A@apple.com> References: <1E9CE6F5-A2AC-4A81-A001-D19DAB65255B@apple.com> <98818310-FEB0-4E4D-8B38-E14698BFD9BE@apple.com> <51D0DA66-26B3-44D5-8384-A31CC30E14EB@apple.com> <6926F677-27AA-4488-8AD8-E1ACE86A2E2A@apple.com> Message-ID: To the cyclic_probability we have to add backedge probability, it is probability of getting to the DST block through the SRC block. In the original algorithm we used floating point numbers, but here we use integers with START_FREQ = 1024, thus we have to "normalize" the value and look at it as a probability where 1024 is equal to 1.0. Previously we used getEdgeFreq which is wrong, because sum of them for some BB from all its predecessors might be greater than START_FREQ. BTW: I forgot to delete DSE.cpp part, which is use for the testing purpose. -Kuba On Jun 22, 2011, at 5:47 PM, Andrew Trick wrote: > Where do you check underflow of block frequency? It seems that 10 sequential branches with default weights would result in getEdgeFreq() returning zero. > > I'm not sure what getBackSumForBlock() means. The previous code looks correct to me. Can you explain the problem that you're solving? > > Thanks. > > -Andy > > On Jun 22, 2011, at 2:39 PM, Jakub Staszak wrote: > >> >> On Jun 21, 2011, at 8:21 PM, Andrew Trick wrote: >> >>> >>> Yes, by "1" I meant literal 1, not scaled 1. I think this could happen inside getEdgeFreq() when (N * getBlockFreq(Src)) < D. You should probably check for that case and return the smallest nonzero frequency. >>> >>> You actually shouldn't have a problem in divBlockFreq, but somewhere you should assert that the input BranchProbability is well-formed (N < D). >> >> The bug was in the complete different place. Instead of using backedge probability info (probability of getting to DST block through SRC block) i used edge probability. It caused some problem in very rare cases (only during benchmarking). >> >> >>> -Andy >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110622/fe3b958c/attachment.html From rafael.espindola at gmail.com Wed Jun 22 20:31:19 2011 From: rafael.espindola at gmail.com (=?ISO-8859-1?Q?Rafael_=C1vila_de_Esp=EDndola?=) Date: Wed, 22 Jun 2011 21:31:19 -0400 Subject: [llvm-commits] [llvm] r133240 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp In-Reply-To: References: <20110617055451.24CFF2A6C12C@llvm.org> Message-ID: <4E029767.9060606@gmail.com> > This commit appears to be causing a significant performance regression > on a couple tests in the test-suite for x86-32; > test-suite/SingleSource/Benchmarks/Shootout-C++/matrix.cpp is a good > example (3.3s before, 4.1s after). Would you mind taking a look to > see if anything unexpected is happening? It looks like a register allocation issue. On this benchmark, the hot bb is not duplicated (or duplicated into), but gets a new phi node. After register allocation, the start of the block goes from %ECX = MOV32rm %EDI, 4, %EBX, 0, %noreg; mem:LD4[%scevgep9](tbaa=!"any pointer") %ECX = MOV32rm %ECX, 4, %ESI, 0, %noreg; mem:LD4[%scevgep12](tbaa=!"int") %ECX = IMUL32rm %ECX, %EDX, 4, %EBX, 0, %noreg, %EFLAGS; mem:LD4[%scevgep10](tbaa=!"int") to %EDI = MOV32rm , 1, %noreg, 0, %noreg; mem:LD4[FixedStack2] %EDI = MOV32rm %EDI, 4, %EBX, 0, %noreg; mem:LD4[%scevgep9](tbaa=!"any pointer") %EDI = MOV32rm %EDI, 4, %EAX, 0, %noreg; mem:LD4[%scevgep12](tbaa=!"int") %EDI = IMUL32rm %EDI, %EDX, 4, %EBX, 0, %noreg, %EFLAGS; mem:LD4[%scevgep10](tbaa=!"int") Note that the value that before was in EDI at the start of the loop is now in fi#2. I have placed the files (test.bc, no-tail-dup.log, tail-dup.log) in http://people.mozilla.com/~respindola if you are interested. I will check if I can make the early tail duplication a bit more conservative. > -Eli Cheers, Rafael From atrick at apple.com Wed Jun 22 20:57:57 2011 From: atrick at apple.com (Andrew Trick) Date: Wed, 22 Jun 2011 18:57:57 -0700 Subject: [llvm-commits] BlockFrequency for BasicBlocks In-Reply-To: References: <1E9CE6F5-A2AC-4A81-A001-D19DAB65255B@apple.com> <98818310-FEB0-4E4D-8B38-E14698BFD9BE@apple.com> <51D0DA66-26B3-44D5-8384-A31CC30E14EB@apple.com> <6926F677-27AA-4488-8AD8-E1ACE86A2E2A@apple.com> Message-ID: On Jun 22, 2011, at 6:16 PM, Jakub Staszak wrote: > Previously we used getEdgeFreq which is wrong, because sum of them for some BB from all its predecessors might be greater than START_FREQ. The algorithm assumes that will never happen when BB is the loop head currently being processed. If it does happen (irreducible inner loops?) then I don't know how to calculate cyclic probability. I would just pick a reasonably high value. BTW: this problem could be solved by converted the irreducible graph to a reducible one, but you shouldn't worry about that for now. -Andy From evan.cheng at apple.com Wed Jun 22 20:53:43 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 23 Jun 2011 01:53:43 -0000 Subject: [llvm-commits] [llvm] r133679 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.cpp X86RegisterInfo.cpp X86RegisterInfo.h Message-ID: <20110623015343.B7EEB2A6C12C@llvm.org> Author: evancheng Date: Wed Jun 22 20:53:43 2011 New Revision: 133679 URL: http://llvm.org/viewvc/llvm-project?rev=133679&view=rev Log: Get rid of one getStackAlignment(). RegisterInfo shouldn't need to know about stack alignment. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp llvm/trunk/lib/Target/X86/X86RegisterInfo.h Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=133679&r1=133678&r2=133679&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Wed Jun 22 20:53:43 2011 @@ -2082,7 +2082,8 @@ const MachineFunction &MF = *MBB.getParent(); assert(MF.getFrameInfo()->getObjectSize(FrameIdx) >= RC->getSize() && "Stack slot too small for store"); - bool isAligned = (RI.getStackAlignment() >= 16) || RI.canRealignStack(MF); + bool isAligned = (TM.getFrameLowering()->getStackAlignment() >= 16) || + RI.canRealignStack(MF); unsigned Opc = getStoreRegOpcode(SrcReg, RC, isAligned, TM); DebugLoc DL = MBB.findDebugLoc(MI); addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIdx) @@ -2114,7 +2115,8 @@ const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const { const MachineFunction &MF = *MBB.getParent(); - bool isAligned = (RI.getStackAlignment() >= 16) || RI.canRealignStack(MF); + bool isAligned = (TM.getFrameLowering()->getStackAlignment() >= 16) || + RI.canRealignStack(MF); unsigned Opc = getLoadRegOpcode(DestReg, RC, isAligned, TM); DebugLoc DL = MBB.findDebugLoc(MI); addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DestReg), FrameIdx); Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=133679&r1=133678&r2=133679&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Wed Jun 22 20:53:43 2011 @@ -60,7 +60,6 @@ const X86Subtarget *Subtarget = &TM.getSubtarget(); Is64Bit = Subtarget->is64Bit(); IsWin64 = Subtarget->isTargetWin64(); - StackAlign = TM.getFrameLowering()->getStackAlignment(); if (Is64Bit) { SlotSize = 8; @@ -557,6 +556,7 @@ bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); const Function *F = MF.getFunction(); + unsigned StackAlign = TM.getFrameLowering()->getStackAlignment(); bool requiresRealignment = ((MFI->getMaxAlignment() > StackAlign) || F->hasFnAttr(Attribute::StackAlignment)); @@ -632,6 +632,7 @@ // We need to keep the stack aligned properly. To do this, we round the // amount of space needed for the outgoing arguments up to the next // alignment boundary. + unsigned StackAlign = TM.getFrameLowering()->getStackAlignment(); Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign; MachineInstr *New = 0; @@ -927,10 +928,10 @@ virtual bool runOnMachineFunction(MachineFunction &MF) { const X86TargetMachine *TM = static_cast(&MF.getTarget()); - const X86RegisterInfo *X86RI = TM->getRegisterInfo(); + const TargetFrameLowering *TFI = TM->getFrameLowering(); MachineRegisterInfo &RI = MF.getRegInfo(); X86MachineFunctionInfo *FuncInfo = MF.getInfo(); - unsigned StackAlignment = X86RI->getStackAlignment(); + unsigned StackAlignment = TFI->getStackAlignment(); // Be over-conservative: scan over all vreg defs and find whether vector // registers are used. If yes, there is a possibility that vector register Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.h?rev=133679&r1=133678&r2=133679&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.h Wed Jun 22 20:53:43 2011 @@ -56,10 +56,6 @@ /// unsigned SlotSize; - /// StackAlign - Default stack alignment. - /// - unsigned StackAlign; - /// StackPtr - X86 physical register used as stack ptr. /// unsigned StackPtr; @@ -75,8 +71,6 @@ /// register identifier. static unsigned getX86RegNum(unsigned RegNo); - unsigned getStackAlignment() const { return StackAlign; } - /// getDwarfRegNum - allows modification of X86GenRegisterInfo::getDwarfRegNum /// (created by TableGen) for target dependencies. int getDwarfRegNum(unsigned RegNum, bool isEH) const; From jstaszak at apple.com Wed Jun 22 21:42:30 2011 From: jstaszak at apple.com (Jakub Staszak) Date: Wed, 22 Jun 2011 19:42:30 -0700 Subject: [llvm-commits] BlockFrequency for BasicBlocks In-Reply-To: References: <1E9CE6F5-A2AC-4A81-A001-D19DAB65255B@apple.com> <98818310-FEB0-4E4D-8B38-E14698BFD9BE@apple.com> <51D0DA66-26B3-44D5-8384-A31CC30E14EB@apple.com> <6926F677-27AA-4488-8AD8-E1ACE86A2E2A@apple.com> Message-ID: On Jun 22, 2011, at 6:57 PM, Andrew Trick wrote: > On Jun 22, 2011, at 6:16 PM, Jakub Staszak wrote: > >> Previously we used getEdgeFreq which is wrong, because sum of them for some BB from all its predecessors might be greater than START_FREQ. > > The algorithm assumes that will never happen when BB is the loop head currently being processed. If it does happen (irreducible inner loops?) then I don't know how to calculate cyclic probability. I would just pick a reasonably high value. The previous version of the patch used to do this. We divided by pretty small number, but I think we didn't like it, did we? I don't know which version you prefer, I think I like the current one. - Kuba From aggarwa4 at illinois.edu Wed Jun 22 22:24:32 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 23 Jun 2011 03:24:32 -0000 Subject: [llvm-commits] [poolalloc] r133680 - /poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Message-ID: <20110623032432.3D1982A6C12C@llvm.org> Author: aggarwa4 Date: Wed Jun 22 22:24:32 2011 New Revision: 133680 URL: http://llvm.org/viewvc/llvm-project?rev=133680&view=rev Log: Add a few more functions, needed by newer version of sqlite. Fix printing in VAArgCheck. Modified: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Modified: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp?rev=133680&r1=133679&r2=133680&view=diff ============================================================================== --- poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp (original) +++ poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Wed Jun 22 22:24:32 2011 @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,7 @@ void trackStrcpyInst(void *dst, void *src, uint32_t tag) ; void trackStrcatInst(void *dst, void *src, uint32_t tag) ; void trackgetcwd(void *ptr, uint32_t tag) ; + void trackgetpwuid(void *ptr, uint32_t tag) ; void trackgethostname(void *ptr, uint32_t tag) ; void trackgetaddrinfo(void *ptr, uint32_t tag) ; void trackaccept(void *ptr, uint32_t tag) ; @@ -166,7 +168,6 @@ #if DEBUG printf("Store(%d): %p, %p = %u | %lu bytes | \n", tag, ptr, (void *)p, typeNumber, size); #endif - } /** @@ -181,7 +182,7 @@ */ void compareTypes(TypeTagTy typeNumberSrc, TypeTagTy typeNumberDest, uint32_t tag) { if(typeNumberSrc != typeNumberDest) { - printf("Type mismatch(%u): expecting %s, found %s! \n", tag, typeNames[typeNumberDest], typeNames[typeNumberSrc]); + printf("Type mismatch(%u): expecting %s, found %s! \n", tag, typeNames[typeNumberSrc], typeNames[typeNumberDest]); } } @@ -222,7 +223,7 @@ * Compare the typeNumber with the type info(for given size) stored at the metadata ptr. * ptr and tag are for debugging */ -void __attribute__((always_inline)) +void checkType(TypeTagTy typeNumber, uint64_t size, TypeTagTy *metadata, void *ptr, uint32_t tag) { /* Check if this an initialized but untyped memory.*/ if (typeNumber != metadata[0]) { @@ -362,6 +363,14 @@ trackInitInst(ptr, strlen((const char *)ptr) + 1, tag); } +void trackgetpwuid(void *ptr, uint32_t tag) { + struct passwd *p = (struct passwd *)ptr; + trackInitInst(p->pw_name, strlen(p->pw_name) + 1, tag); + trackInitInst(p->pw_dir, strlen(p->pw_dir) + 1, tag); + trackInitInst(p->pw_shell, strlen(p->pw_shell) + 1, tag); + trackInitInst(p, sizeof(struct passwd), tag); +} + void trackgethostname(void *ptr, uint32_t tag) { trackInitInst(ptr, strlen((const char *)ptr) + 1, tag); } From aggarwa4 at illinois.edu Wed Jun 22 22:25:37 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 23 Jun 2011 03:25:37 -0000 Subject: [llvm-commits] [poolalloc] r133681 - /poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Message-ID: <20110623032537.510322A6C12C@llvm.org> Author: aggarwa4 Date: Wed Jun 22 22:25:37 2011 New Revision: 133681 URL: http://llvm.org/viewvc/llvm-project?rev=133681&view=rev Log: Add instrumentation for __errno_location. Give getpwuid a separate function, which instruments the pointers in its fields too. Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=133681&r1=133680&r2=133681&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Wed Jun 22 22:25:37 2011 @@ -1401,10 +1401,19 @@ Args.push_back(AllocSize); Args.push_back(getTagCounter()); CallInst::Create(trackInitInst, Args.begin(), Args.end(), "", I); - } else if (F->getNameStr() == std::string("getpwuid") || - F->getNameStr() == std::string("getgruid") || + } else if (F->getNameStr() == std::string("getpwuid")) { + CastInst *BCI = BitCastInst::CreatePointerCast(I, VoidPtrTy); + BCI->insertAfter(I); + std::vectorArgs; + Args.push_back(BCI); + Args.push_back(getTagCounter()); + Constant *F = M.getOrInsertFunction("trackgetpwuid", VoidTy, VoidPtrTy, Int32Ty, NULL); + CallInst *CI = CallInst::Create(F, Args.begin(), Args.end()); + CI->insertAfter(BCI); + } else if (F->getNameStr() == std::string("getgruid") || F->getNameStr() == std::string("getgrnam") || - F->getNameStr() == std::string("getpwnam")) { + F->getNameStr() == std::string("getpwnam") || + F->getNameStr() == std::string("__errno_location")) { CastInst *BCI = BitCastInst::CreatePointerCast(I, VoidPtrTy); assert (isa(I->getType())); const PointerType * PT = cast(I->getType()); From rafael.espindola at gmail.com Wed Jun 22 22:41:29 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Thu, 23 Jun 2011 03:41:29 -0000 Subject: [llvm-commits] [llvm] r133682 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp Message-ID: <20110623034130.0384B2A6C12C@llvm.org> Author: rafael Date: Wed Jun 22 22:41:29 2011 New Revision: 133682 URL: http://llvm.org/viewvc/llvm-project?rev=133682&view=rev Log: Move more logic to shouldTailDuplicate and only duplicate regular bb before register allocation if it has a indirectbr or if we can duplicate it to every predecessor. This fixes the SingleSource/Benchmarks/Shootout-C++/matrix.cpp regression but keeps the previous improvements to sunspider. Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=133682&r1=133681&r2=133682&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Wed Jun 22 22:41:29 2011 @@ -95,10 +95,10 @@ SmallSetVector &Succs); bool TailDuplicateBlocks(MachineFunction &MF); bool shouldTailDuplicate(const MachineFunction &MF, - MachineBasicBlock &TailBB); + bool IsSimple, MachineBasicBlock &TailBB); bool isSimpleBB(MachineBasicBlock *TailBB); - bool canCompletelyDuplicateSimpleBB(MachineBasicBlock &BB); - bool duplicateSimpleBB(MachineBasicBlock *TailBB, + bool canCompletelyDuplicateBB(MachineBasicBlock &BB, bool IsSimple); + void duplicateSimpleBB(MachineBasicBlock *TailBB, SmallVector &TDBBs, const DenseSet &RegsUsedByPhi, SmallVector &Copies); @@ -501,6 +501,7 @@ /// shouldTailDuplicate - Determine if it is profitable to duplicate this block. bool TailDuplicatePass::shouldTailDuplicate(const MachineFunction &MF, + bool IsSimple, MachineBasicBlock &TailBB) { // Only duplicate blocks that end with unconditional branches. if (TailBB.canFallThrough()) @@ -526,10 +527,13 @@ // to allow undoing the effects of tail merging and other optimizations // that rearrange the predecessors of the indirect branch. + bool hasIndirectBR = false; if (PreRegAlloc && !TailBB.empty()) { const TargetInstrDesc &TID = TailBB.back().getDesc(); - if (TID.isIndirectBranch()) + if (TID.isIndirectBranch()) { MaxDuplicateCount = 20; + hasIndirectBR = true; + } } // Check the instructions in the block to determine whether tail-duplication @@ -560,7 +564,16 @@ return false; } - return true; + if (hasIndirectBR) + return true; + + if (IsSimple) + return canCompletelyDuplicateBB(TailBB, IsSimple); + + if (!PreRegAlloc) + return true; + + return canCompletelyDuplicateBB(TailBB, IsSimple); } /// isSimpleBB - True if this BB has only one unconditional jump. @@ -568,6 +581,8 @@ TailDuplicatePass::isSimpleBB(MachineBasicBlock *TailBB) { if (TailBB->succ_size() != 1) return false; + if (TailBB->pred_empty()) + return false; MachineBasicBlock::iterator I = TailBB->begin(); MachineBasicBlock::iterator E = TailBB->end(); while (I != E && I->isDebugValue()) @@ -591,33 +606,40 @@ } bool -TailDuplicatePass::canCompletelyDuplicateSimpleBB(MachineBasicBlock &BB) { +TailDuplicatePass::canCompletelyDuplicateBB(MachineBasicBlock &BB, + bool isSimple) { SmallPtrSet Succs(BB.succ_begin(), BB.succ_end()); for (MachineBasicBlock::pred_iterator PI = BB.pred_begin(), PE = BB.pred_end(); PI != PE; ++PI) { MachineBasicBlock *PredBB = *PI; - if (PredBB->getLandingPadSuccessor()) - return false; - if (bothUsedInPHI(*PredBB, Succs)) - return false; + + if (isSimple) { + if (PredBB->getLandingPadSuccessor()) + return false; + if (bothUsedInPHI(*PredBB, Succs)) + return false; + } else { + if (PredBB->succ_size() > 1) + return false; + } + MachineBasicBlock *PredTBB = NULL, *PredFBB = NULL; SmallVector PredCond; if (TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond, true)) return false; + + if (!isSimple && !PredCond.empty()) + return false; } return true; } -bool +void TailDuplicatePass::duplicateSimpleBB(MachineBasicBlock *TailBB, SmallVector &TDBBs, const DenseSet &UsedByPhi, SmallVector &Copies) { - if (!canCompletelyDuplicateSimpleBB(*TailBB)) - return false; - - bool Changed = false; SmallVector Preds(TailBB->pred_begin(), TailBB->pred_end()); for (SmallSetVector::iterator PI = Preds.begin(), @@ -692,10 +714,7 @@ PredBB->addSuccessor(NewTarget); TDBBs.push_back(PredBB); - - Changed = true; } - return Changed; } /// TailDuplicate - If it is profitable, duplicate TailBB's contents in each @@ -704,7 +723,9 @@ TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF, SmallVector &TDBBs, SmallVector &Copies) { - if (!shouldTailDuplicate(MF, *TailBB)) + bool IsSimple = isSimpleBB(TailBB); + + if (!shouldTailDuplicate(MF, IsSimple, *TailBB)) return false; DEBUG(dbgs() << "\n*** Tail-duplicating BB#" << TailBB->getNumber() << '\n'); @@ -712,8 +733,11 @@ DenseSet UsedByPhi; getRegsUsedByPHIs(*TailBB, &UsedByPhi); - if (isSimpleBB(TailBB)) - return duplicateSimpleBB(TailBB, TDBBs, UsedByPhi, Copies); + if (IsSimple) { + duplicateSimpleBB(TailBB, TDBBs, UsedByPhi, Copies); + return true; + } + // Iterate through all the unique predecessors and tail-duplicate this // block into them, if possible. Copying the list ahead of time also From aggarwa4 at illinois.edu Wed Jun 22 23:14:27 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 23 Jun 2011 04:14:27 -0000 Subject: [llvm-commits] [poolalloc] r133683 - in /poolalloc/trunk: lib/AssistDS/TypeChecks.cpp runtime/DynamicTypeChecks/TypeRuntime.cpp Message-ID: <20110623041427.AE7072A6C12C@llvm.org> Author: aggarwa4 Date: Wed Jun 22 23:14:27 2011 New Revision: 133683 URL: http://llvm.org/viewvc/llvm-project?rev=133683&view=rev Log: Fix prototypes/arguments to be of the correct type Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=133683&r1=133682&r2=133683&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Wed Jun 22 23:14:27 2011 @@ -1761,18 +1761,17 @@ Value *Size = ConstantInt::get(Int32Ty, getSize(LI.getType())); AllocaInst *AI = new AllocaInst(TypeTagTy, Size, "", &*InsPt); - CastInst *BCI_MD = BitCastInst::CreatePointerCast(AI, VoidPtrTy, "", &*InsPt); std::vectorArgs1; Args1.push_back(BCI); Args1.push_back(getSizeConstant(LI.getType())); - Args1.push_back(BCI_MD); + Args1.push_back(AI); CallInst *getTypeCall = CallInst::Create(getTypeTag, Args1.begin(), Args1.end(), "", &LI); if(TrackAllLoads) { std::vector Args; Args.push_back(getTypeMarkerConstant(&LI)); Args.push_back(getSizeConstant(LI.getType())); - Args.push_back(BCI_MD); + Args.push_back(AI); Args.push_back(BCI); Args.push_back(getTagCounter()); CallInst::Create(checkTypeInst, Args.begin(), Args.end(), "", &LI); @@ -1788,7 +1787,7 @@ std::vector Args; Args.push_back(getTypeMarkerConstant(&LI)); Args.push_back(getSizeConstant(LI.getType())); - Args.push_back(BCI_MD); + Args.push_back(AI); Args.push_back(BCI); Args.push_back(getTagCounter()); if(StoreInst *SI = dyn_cast(II)) { @@ -1797,7 +1796,7 @@ std::vector Args; Args.push_back(BCI_Dest); - Args.push_back(BCI_MD); + Args.push_back(AI); Args.push_back(getSizeConstant(SI->getOperand(0)->getType())); Args.push_back(getTagCounter()); // Create the call to the runtime check and place it before the copying store instruction. @@ -1810,7 +1809,7 @@ CallInst::Create(checkTypeInst, Args.begin(), Args.end(), "", cast(II.getUse().getUser())); } } - if(BCI_MD->getNumUses() == 1) { + if(AI->getNumUses() == 1) { // No uses needed checks getTypeCall->eraseFromParent(); } Modified: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp?rev=133683&r1=133682&r2=133683&view=diff ============================================================================== --- poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp (original) +++ poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Wed Jun 22 23:14:27 2011 @@ -69,7 +69,7 @@ void trackInitInst(void *ptr, uint64_t size, uint32_t tag) ; void trackUnInitInst(void *ptr, uint64_t size, uint32_t tag) ; void copyTypeInfo(void *dstptr, void *srcptr, uint64_t size, uint32_t tag) ; - void setTypeInfo(void *dstptr, void *metadata, uint64_t size, uint32_t tag) ; + void setTypeInfo(void *dstptr, TypeTagTy *metadata, uint64_t size, uint32_t tag) ; void setVAInfo(void *va_list, uint64_t totalCount, TypeTagTy *metadata_ptr, uint32_t tag) ; void copyVAInfo(void *va_list_dst, void *va_list_src, uint32_t tag) ; void trackctype(void *ptr, uint32_t tag) ; @@ -290,7 +290,7 @@ /** * Copy size bytes of metadata from metadata to dest ptr */ -void setTypeInfo(void *dstptr, void *metadata, uint64_t size, uint32_t tag) { +void setTypeInfo(void *dstptr, TypeTagTy *metadata, uint64_t size, uint32_t tag) { uintptr_t d = maskAddress(dstptr); memcpy(&shadow_begin[d], metadata, size); } From clattner at apple.com Wed Jun 22 23:39:31 2011 From: clattner at apple.com (Chris Lattner) Date: Wed, 22 Jun 2011 21:39:31 -0700 Subject: [llvm-commits] [llvm] r133669 - /llvm/trunk/include/llvm/Target/TargetAsmInfo.h In-Reply-To: <20110623001258.50ACE2A6C12C@llvm.org> References: <20110623001258.50ACE2A6C12C@llvm.org> Message-ID: On Jun 22, 2011, at 5:12 PM, Bill Wendling wrote: > Author: void > Date: Wed Jun 22 19:12:58 2011 > New Revision: 133669 > > URL: http://llvm.org/viewvc/llvm-project?rev=133669&view=rev > Log: > Allow the AsmInfo to query the TLOF to see if it supports compact unwind. Hi Bill, Why have this *and* getCompactUnwindSection? Can't getCompactUnwindSection just return null if there is no support? If we need the predicate, it would be better to name this just "supportsCompactUnwindInfo() or better yet "hasCompactUnwindInfoSupport()" -Chris > > Modified: > llvm/trunk/include/llvm/Target/TargetAsmInfo.h > > Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmInfo.h?rev=133669&r1=133668&r2=133669&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Target/TargetAsmInfo.h (original) > +++ llvm/trunk/include/llvm/Target/TargetAsmInfo.h Wed Jun 22 19:12:58 2011 > @@ -79,6 +79,10 @@ > return TLOF->isFunctionEHFrameSymbolPrivate(); > } > > + bool getSupportsCompactUnwindInfo() const { > + return TLOF->getSupportsCompactUnwindInfo(); > + } > + > const unsigned *getCalleeSavedRegs(MachineFunction *MF = 0) const { > return TRI->getCalleeSavedRegs(MF); > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Wed Jun 22 23:58:57 2011 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 22 Jun 2011 21:58:57 -0700 Subject: [llvm-commits] [llvm] r133669 - /llvm/trunk/include/llvm/Target/TargetAsmInfo.h In-Reply-To: References: <20110623001258.50ACE2A6C12C@llvm.org> Message-ID: <84C2641A-D017-4061-99B5-2357EB0172DD@gmail.com> On Jun 22, 2011, at 9:39 PM, Chris Lattner wrote: > On Jun 22, 2011, at 5:12 PM, Bill Wendling wrote: > >> Author: void >> Date: Wed Jun 22 19:12:58 2011 >> New Revision: 133669 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=133669&view=rev >> Log: >> Allow the AsmInfo to query the TLOF to see if it supports compact unwind. > > Hi Bill, > > Why have this *and* getCompactUnwindSection? Can't getCompactUnwindSection just return null if there is no support? I was thinking of that. I can't think of a reason to have both of them, so I'll opt for returning the MCSection pointer one. If it turns out that we need a predicate, it'll be easy to add later. :-) > If we need the predicate, it would be better to name this just "supportsCompactUnwindInfo() or better yet "hasCompactUnwindInfoSupport()" -bw From isanbard at gmail.com Thu Jun 23 00:13:28 2011 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 23 Jun 2011 05:13:28 -0000 Subject: [llvm-commits] [llvm] r133685 - in /llvm/trunk: include/llvm/Target/TargetAsmInfo.h include/llvm/Target/TargetLoweringObjectFile.h lib/CodeGen/TargetLoweringObjectFileImpl.cpp lib/MC/MCDwarf.cpp lib/Target/TargetLoweringObjectFile.cpp Message-ID: <20110623051328.8265A2A6C12C@llvm.org> Author: void Date: Thu Jun 23 00:13:28 2011 New Revision: 133685 URL: http://llvm.org/viewvc/llvm-project?rev=133685&view=rev Log: Use the presence of the __compact_unwind section to indicate that a target supports compact unwind info instead of having a separate flag indicating this. Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/trunk/lib/MC/MCDwarf.cpp llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmInfo.h?rev=133685&r1=133684&r2=133685&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetAsmInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetAsmInfo.h Thu Jun 23 00:13:28 2011 @@ -83,10 +83,6 @@ return TLOF->isFunctionEHFrameSymbolPrivate(); } - bool getSupportsCompactUnwindInfo() const { - return TLOF->getSupportsCompactUnwindInfo(); - } - const unsigned *getCalleeSavedRegs(MachineFunction *MF = 0) const { return TRI->getCalleeSavedRegs(MF); } Modified: llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h?rev=133685&r1=133684&r2=133685&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h (original) +++ llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h Thu Jun 23 00:13:28 2011 @@ -108,10 +108,6 @@ /// non-.globl label. This defaults to true. bool IsFunctionEHFrameSymbolPrivate; - /// SupportsCompactUnwindInfo - This flag is set to true if the CIE and FDE - /// information should be emitted in a compact form. - bool SupportsCompactUnwindInfo; - public: MCContext &getContext() const { return *Ctx; } @@ -133,9 +129,6 @@ bool getCommDirectiveSupportsAlignment() const { return CommDirectiveSupportsAlignment; } - bool getSupportsCompactUnwindInfo() const { - return SupportsCompactUnwindInfo; - } const MCSection *getTextSection() const { return TextSection; } const MCSection *getDataSection() const { return DataSection; } Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=133685&r1=133684&r2=133685&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original) +++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Thu Jun 23 00:13:28 2011 @@ -487,12 +487,8 @@ // .comm doesn't support alignment before Leopard. Triple T(((LLVMTargetMachine&)TM).getTargetTriple()); - if (T.isMacOSX()) { - if (T.isMacOSXVersionLT(10, 5)) - CommDirectiveSupportsAlignment = false; - if (!T.isMacOSXVersionLT(10, 6)) - SupportsCompactUnwindInfo = true; - } + if (T.isMacOSX() && T.isMacOSXVersionLT(10, 5)) + CommDirectiveSupportsAlignment = false; TargetLoweringObjectFile::Initialize(Ctx, TM); @@ -610,10 +606,11 @@ LSDASection = getContext().getMachOSection("__TEXT", "__gcc_except_tab", 0, SectionKind::getReadOnlyWithRel()); - CompactUnwindSection = - getContext().getMachOSection("__LD", "__compact_unwind", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getReadOnly()); + if (T.isMacOSX() && !T.isMacOSXVersionLT(10, 6)) + CompactUnwindSection = + getContext().getMachOSection("__LD", "__compact_unwind", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getReadOnly()); // Debug Information. DwarfAbbrevSection = Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=133685&r1=133684&r2=133685&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Thu Jun 23 00:13:28 2011 @@ -917,7 +917,7 @@ CIEKey key(frame.Personality, frame.PersonalityEncoding, frame.LsdaEncoding); const MCSymbol *&cieStart = isEH ? CIEStarts[key] : DummyDebugKey; - if (isEH && asmInfo.getSupportsCompactUnwindInfo() && + if (isEH && asmInfo.getCompactUnwindSection() && Emitter.EmitCompactUnwind(streamer, frame)) continue; Modified: llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp?rev=133685&r1=133684&r2=133685&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp (original) +++ llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp Thu Jun 23 00:13:28 2011 @@ -61,7 +61,6 @@ IsFunctionEHFrameSymbolPrivate = true; SupportsWeakOmittedEHFrame = true; - SupportsCompactUnwindInfo = false; } TargetLoweringObjectFile::~TargetLoweringObjectFile() { From aggarwa4 at illinois.edu Thu Jun 23 00:28:17 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 23 Jun 2011 05:28:17 -0000 Subject: [llvm-commits] [poolalloc] r133686 - in /poolalloc/trunk: lib/AssistDS/TypeChecks.cpp runtime/DynamicTypeChecks/TypeRuntime.cpp Message-ID: <20110623052817.DA8D12A6C12C@llvm.org> Author: aggarwa4 Date: Thu Jun 23 00:28:17 2011 New Revision: 133686 URL: http://llvm.org/viewvc/llvm-project?rev=133686&view=rev Log: Add a tag to getTypeTag. Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=133686&r1=133685&r2=133686&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Thu Jun 23 00:28:17 2011 @@ -189,6 +189,7 @@ VoidPtrTy, /*ptr*/ Int64Ty, /*size*/ TypeTagPtrTy, /*dest for type tag*/ + Int32Ty, /*tag*/ NULL); checkTypeInst = M.getOrInsertFunction("checkType", VoidTy, @@ -1766,6 +1767,7 @@ Args1.push_back(BCI); Args1.push_back(getSizeConstant(LI.getType())); Args1.push_back(AI); + Args1.push_back(getTagCounter()); CallInst *getTypeCall = CallInst::Create(getTypeTag, Args1.begin(), Args1.end(), "", &LI); if(TrackAllLoads) { std::vector Args; Modified: poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp?rev=133686&r1=133685&r2=133686&view=diff ============================================================================== --- poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp (original) +++ poolalloc/trunk/runtime/DynamicTypeChecks/TypeRuntime.cpp Thu Jun 23 00:28:17 2011 @@ -64,7 +64,7 @@ void compareNumber(uint64_t NumArgsPassed, uint64_t ArgAccessed, uint32_t tag); void compareTypeAndNumber(uint64_t NumArgsPassed, uint64_t ArgAccessed, uint8_t TypeAccessed, void *MD, uint32_t tag) ; void checkVAArgType(void *va_list, TypeTagTy TypeAccessed, uint32_t tag) ; - void getTypeTag(void *ptr, uint64_t size, TypeTagTy *dest) ; + void getTypeTag(void *ptr, uint64_t size, TypeTagTy *dest, uint32_t tag) ; void checkType(TypeTagTy typeNumber, uint64_t size, TypeTagTy *metadata, void *ptr, uint32_t tag); void trackInitInst(void *ptr, uint64_t size, uint32_t tag) ; void trackUnInitInst(void *ptr, uint64_t size, uint32_t tag) ; @@ -212,7 +212,7 @@ * For loads, return the metadata(for size bytes) stored at the ptr * Store it in dest */ -void getTypeTag(void *ptr, uint64_t size, TypeTagTy *dest) { +void getTypeTag(void *ptr, uint64_t size, TypeTagTy *dest, uint32_t tag) { uintptr_t p = maskAddress(ptr); assert(p + size < SIZE); From aggarwa4 at illinois.edu Thu Jun 23 00:29:26 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Thu, 23 Jun 2011 05:29:26 -0000 Subject: [llvm-commits] [poolalloc] r133687 - /poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp Message-ID: <20110623052926.C5E3E2A6C12C@llvm.org> Author: aggarwa4 Date: Thu Jun 23 00:29:26 2011 New Revision: 133687 URL: http://llvm.org/viewvc/llvm-project?rev=133687&view=rev Log: Remove calls to getTagType on optimization. Modified: poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp Modified: poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp?rev=133687&r1=133686&r2=133687&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp (original) +++ poolalloc/trunk/lib/AssistDS/TypeChecksOpt.cpp Thu Jun 23 00:29:26 2011 @@ -51,6 +51,7 @@ static Constant *copyTypeInfo; static Constant *setTypeInfo; static Constant *checkTypeInst; +static Constant *getTypeTag; static Constant *MallocFunc; bool TypeChecksOpt::runOnModule(Module &M) { @@ -118,6 +119,12 @@ VoidPtrTy, Int32Ty, NULL); + getTypeTag = M.getOrInsertFunction("getTypeTag", + VoidTy, + VoidPtrTy, /*ptr*/ + Int64Ty, /*size*/ + TypeTagPtrTy, /*dest for type tag*/ + NULL); MallocFunc = M.getFunction("malloc"); for(Value::use_iterator User = trackGlobal->use_begin(); User != trackGlobal->use_end(); ++User) { @@ -214,6 +221,14 @@ } } + for(Value::use_iterator User = getTypeTag->use_begin(); User != getTypeTag->use_end(); ++User) { + CallInst *CI = dyn_cast(User); + assert(CI); + if(TS->isTypeSafe(CI->getOperand(1)->stripPointerCasts(), CI->getParent()->getParent())) { + toDelete.push_back(CI); + } + } + numSafe += toDelete.size(); while(!toDelete.empty()) { From echristo at apple.com Thu Jun 23 01:24:53 2011 From: echristo at apple.com (Eric Christopher) Date: Thu, 23 Jun 2011 06:24:53 -0000 Subject: [llvm-commits] [llvm] r133700 - in /llvm/trunk: include/llvm/ include/llvm/Support/ lib/MC/ lib/Target/CppBackend/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ Message-ID: <20110623062453.6C8DB2A6C12C@llvm.org> Author: echristo Date: Thu Jun 23 01:24:52 2011 New Revision: 133700 URL: http://llvm.org/viewvc/llvm-project?rev=133700&view=rev Log: Revert r133513: "Reinstate r133435 and r133449 (reverted in r133499) now that the clang self-hosted build failure has been fixed (r133512)." Due to some additional warnings. Modified: llvm/trunk/include/llvm/BasicBlock.h llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/Support/CFG.h llvm/trunk/include/llvm/Use.h llvm/trunk/lib/MC/MCAsmStreamer.cpp llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp llvm/trunk/lib/VMCore/BasicBlock.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/lib/VMCore/User.cpp llvm/trunk/lib/VMCore/Value.cpp llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/include/llvm/BasicBlock.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BasicBlock.h?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/include/llvm/BasicBlock.h (original) +++ llvm/trunk/include/llvm/BasicBlock.h Thu Jun 23 01:24:52 2011 @@ -110,7 +110,7 @@ Function *getParent() { return Parent; } /// use_back - Specialize the methods defined in Value, as we know that an - /// BasicBlock can only be used by Users (specifically terminators + /// BasicBlock can only be used by Users (specifically PHI nodes, terminators, /// and BlockAddress's). User *use_back() { return cast(*use_begin());} const User *use_back() const { return cast(*use_begin());} @@ -248,10 +248,6 @@ /// other than direct branches, switches, etc. to it. bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; } - /// replaceSuccessorsPhiUsesWith - Update all phi nodes in all our successors - /// to refer to basic block New instead of to us. - void replaceSuccessorsPhiUsesWith(BasicBlock *New); - private: /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress /// objects using it. This is almost always 0, sometimes one, possibly but Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Thu Jun 23 01:24:52 2011 @@ -1814,7 +1814,7 @@ explicit PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr = "", Instruction *InsertBefore = 0) : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), - ReservedSpace(NumReservedValues) { + ReservedSpace(NumReservedValues * 2) { setName(NameStr); OperandList = allocHungoffUses(ReservedSpace); } @@ -1822,16 +1822,11 @@ PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), - ReservedSpace(NumReservedValues) { + ReservedSpace(NumReservedValues * 2) { setName(NameStr); OperandList = allocHungoffUses(ReservedSpace); } protected: - // allocHungoffUses - this is more complicated than the generic - // User::allocHungoffUses, because we have to allocate Uses for the incoming - // values and pointers to the incoming blocks, all in one allocation. - Use *allocHungoffUses(unsigned) const; - virtual PHINode *clone_impl() const; public: /// Constructors - NumReservedValues is a hint for the number of incoming @@ -1850,55 +1845,32 @@ /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - // Block iterator interface. This provides access to the list of incoming - // basic blocks, which parallels the list of incoming values. - - typedef BasicBlock **block_iterator; - typedef BasicBlock * const *const_block_iterator; - - block_iterator block_begin() { - Use::UserRef *ref = - reinterpret_cast(op_begin() + ReservedSpace); - return reinterpret_cast(ref + 1); - } - - const_block_iterator block_begin() const { - const Use::UserRef *ref = - reinterpret_cast(op_begin() + ReservedSpace); - return reinterpret_cast(ref + 1); - } - - block_iterator block_end() { - return block_begin() + getNumOperands(); - } - - const_block_iterator block_end() const { - return block_begin() + getNumOperands(); - } - /// getNumIncomingValues - Return the number of incoming edges /// - unsigned getNumIncomingValues() const { return getNumOperands(); } + unsigned getNumIncomingValues() const { return getNumOperands()/2; } /// getIncomingValue - Return incoming value number x /// Value *getIncomingValue(unsigned i) const { - return getOperand(i); + assert(i*2 < getNumOperands() && "Invalid value number!"); + return getOperand(i*2); } void setIncomingValue(unsigned i, Value *V) { - setOperand(i, V); + assert(i*2 < getNumOperands() && "Invalid value number!"); + setOperand(i*2, V); } static unsigned getOperandNumForIncomingValue(unsigned i) { - return i; + return i*2; } static unsigned getIncomingValueNumForOperand(unsigned i) { - return i; + assert(i % 2 == 0 && "Invalid incoming-value operand index!"); + return i/2; } /// getIncomingBlock - Return incoming basic block number @p i. /// BasicBlock *getIncomingBlock(unsigned i) const { - return block_begin()[i]; + return cast(getOperand(i*2+1)); } /// getIncomingBlock - Return incoming basic block corresponding @@ -1906,7 +1878,7 @@ /// BasicBlock *getIncomingBlock(const Use &U) const { assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?"); - return getIncomingBlock(&U - op_begin()); + return cast((&U + 1)->get()); } /// getIncomingBlock - Return incoming basic block corresponding @@ -1917,8 +1889,16 @@ return getIncomingBlock(I.getUse()); } + void setIncomingBlock(unsigned i, BasicBlock *BB) { - block_begin()[i] = BB; + setOperand(i*2+1, (Value*)BB); + } + static unsigned getOperandNumForIncomingBlock(unsigned i) { + return i*2+1; + } + static unsigned getIncomingBlockNumForOperand(unsigned i) { + assert(i % 2 == 1 && "Invalid incoming-block operand index!"); + return i/2; } /// addIncoming - Add an incoming value to the end of the PHI list @@ -1928,12 +1908,13 @@ assert(BB && "PHI node got a null basic block!"); assert(getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"); - if (NumOperands == ReservedSpace) + unsigned OpNo = NumOperands; + if (OpNo+2 > ReservedSpace) growOperands(); // Get more space! // Initialize some new operands. - ++NumOperands; - setIncomingValue(NumOperands - 1, V); - setIncomingBlock(NumOperands - 1, BB); + NumOperands = OpNo+2; + OperandList[OpNo] = V; + OperandList[OpNo+1] = (Value*)BB; } /// removeIncomingValue - Remove an incoming value. This is useful if a @@ -1956,16 +1937,14 @@ /// block in the value list for this PHI. Returns -1 if no instance. /// int getBasicBlockIndex(const BasicBlock *BB) const { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (block_begin()[i] == BB) - return i; + Use *OL = OperandList; + for (unsigned i = 0, e = getNumOperands(); i != e; i += 2) + if (OL[i+1].get() == (const Value*)BB) return i/2; return -1; } Value *getIncomingValueForBlock(const BasicBlock *BB) const { - int Idx = getBasicBlockIndex(BB); - assert(Idx >= 0 && "Invalid basic block argument!"); - return getIncomingValue(Idx); + return getIncomingValue(getBasicBlockIndex(BB)); } /// hasConstantValue - If the specified PHI node always merges together the Modified: llvm/trunk/include/llvm/Support/CFG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CFG.h?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CFG.h (original) +++ llvm/trunk/include/llvm/Support/CFG.h Thu Jun 23 01:24:52 2011 @@ -33,7 +33,7 @@ USE_iterator It; inline void advancePastNonTerminators() { - // Loop to ignore non terminator uses (for example BlockAddresses). + // Loop to ignore non terminator uses (for example PHI nodes). while (!It.atEnd() && !isa(*It)) ++It; } Modified: llvm/trunk/include/llvm/Use.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Use.h?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/include/llvm/Use.h (original) +++ llvm/trunk/include/llvm/Use.h Thu Jun 23 01:24:52 2011 @@ -112,16 +112,13 @@ Use *getNext() const { return Next; } - /// initTags - initialize the waymarking tags on an array of Uses, so that - /// getUser() can find the User from any of those Uses. - static Use *initTags(Use *Start, Use *Stop); - /// zap - This is used to destroy Use operands when the number of operands of /// a User changes. static void zap(Use *Start, const Use *Stop, bool del = false); private: const Use* getImpliedUser() const; + static Use *initTags(Use *Start, Use *Stop); Value *Val; Use *Next; @@ -143,6 +140,7 @@ } friend class Value; + friend class User; }; // simplify_type - Allow clients to treat uses just like values when using Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Thu Jun 23 01:24:52 2011 @@ -1119,7 +1119,7 @@ } else { // Otherwise, write out in binary. OS << "0b"; - for (unsigned j = 8; j--;) { + for (int j = 7; j >= 0; j--) { unsigned Bit = (Code[i] >> j) & 1; unsigned FixupBit; @@ -1128,9 +1128,9 @@ else FixupBit = i * 8 + (7-j); - if (uint8_t MapEntry = FixupMap[FixupBit]) { - assert(Bit == 0 && "Encoder wrote into fixed up bit!"); - OS << char('A' + MapEntry - 1); + if (uint8_t FixupMapEntry = FixupMap[FixupBit]) { + //assert(Bit == 0 && "Encoder wrote into fixed up bit!"); + OS << char('A' + FixupMapEntry - 1); } else OS << Bit; } Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Thu Jun 23 01:24:52 2011 @@ -1356,7 +1356,7 @@ for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) { Out << iName << "->addIncoming(" << opNames[PHINode::getOperandNumForIncomingValue(i)] << ", " - << getOpName(phi->getIncomingBlock(i)) << ");"; + << opNames[PHINode::getOperandNumForIncomingBlock(i)] << ");"; nl(Out); } break; Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Thu Jun 23 01:24:52 2011 @@ -1021,10 +1021,6 @@ while (PHINode *PN = dyn_cast(Succ->begin())) ReplaceUsesOfWith(PN, PN->getIncomingValue(0), Worklist, L, LPM); - // If Succ has any successors with PHI nodes, update them to have - // entries coming from Pred instead of Succ. - Succ->replaceAllUsesWith(Pred); - // Move all of the successor contents from Succ to Pred. Pred->getInstList().splice(BI, Succ->getInstList(), Succ->begin(), Succ->end()); @@ -1032,6 +1028,10 @@ BI->eraseFromParent(); RemoveFromWorklist(BI, Worklist); + // If Succ has any successors with PHI nodes, update them to have + // entries coming from Pred instead of Succ. + Succ->replaceAllUsesWith(Pred); + // Remove Succ from the loop tree. LI->removeBlock(Succ); LPM->deleteSimpleAnalysisValue(Succ, L); Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Thu Jun 23 01:24:52 2011 @@ -153,13 +153,13 @@ // Delete the unconditional branch from the predecessor... PredBB->getInstList().pop_back(); + // Move all definitions in the successor to the predecessor... + PredBB->getInstList().splice(PredBB->end(), BB->getInstList()); + // Make all PHI nodes that referred to BB now refer to Pred as their // source... BB->replaceAllUsesWith(PredBB); - // Move all definitions in the successor to the predecessor... - PredBB->getInstList().splice(PredBB->end(), BB->getInstList()); - // Inherit predecessors name if it exists. if (!PredBB->hasName()) PredBB->takeName(BB); Modified: llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp Thu Jun 23 01:24:52 2011 @@ -193,22 +193,44 @@ // If there are any PHI nodes in DestBB, we need to update them so that they // merge incoming values from NewBB instead of from TIBB. - { - unsigned BBIdx = 0; - for (BasicBlock::iterator I = DestBB->begin(); isa(I); ++I) { - // We no longer enter through TIBB, now we come in through NewBB. - // Revector exactly one entry in the PHI node that used to come from - // TIBB to come from NewBB. - PHINode *PN = cast(I); - - // Reuse the previous value of BBIdx if it lines up. In cases where we - // have multiple phi nodes with *lots* of predecessors, this is a speed - // win because we don't have to scan the PHI looking for TIBB. This - // happens because the BB list of PHI nodes are usually in the same - // order. - if (PN->getIncomingBlock(BBIdx) != TIBB) - BBIdx = PN->getBasicBlockIndex(TIBB); - PN->setIncomingBlock(BBIdx, NewBB); + if (PHINode *APHI = dyn_cast(DestBB->begin())) { + // This conceptually does: + // foreach (PHINode *PN in DestBB) + // PN->setIncomingBlock(PN->getIncomingBlock(TIBB), NewBB); + // but is optimized for two cases. + + if (APHI->getNumIncomingValues() <= 8) { // Small # preds case. + unsigned BBIdx = 0; + for (BasicBlock::iterator I = DestBB->begin(); isa(I); ++I) { + // We no longer enter through TIBB, now we come in through NewBB. + // Revector exactly one entry in the PHI node that used to come from + // TIBB to come from NewBB. + PHINode *PN = cast(I); + + // Reuse the previous value of BBIdx if it lines up. In cases where we + // have multiple phi nodes with *lots* of predecessors, this is a speed + // win because we don't have to scan the PHI looking for TIBB. This + // happens because the BB list of PHI nodes are usually in the same + // order. + if (PN->getIncomingBlock(BBIdx) != TIBB) + BBIdx = PN->getBasicBlockIndex(TIBB); + PN->setIncomingBlock(BBIdx, NewBB); + } + } else { + // However, the foreach loop is slow for blocks with lots of predecessors + // because PHINode::getIncomingBlock is O(n) in # preds. Instead, walk + // the user list of TIBB to find the PHI nodes. + SmallPtrSet UpdatedPHIs; + + for (Value::use_iterator UI = TIBB->use_begin(), E = TIBB->use_end(); + UI != E; ) { + Value::use_iterator Use = UI++; + if (PHINode *PN = dyn_cast(*Use)) { + // Remove one entry from each PHI. + if (PN->getParent() == DestBB && UpdatedPHIs.insert(PN)) + PN->setOperand(Use.getOperandNo(), NewBB); + } + } } } Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Thu Jun 23 01:24:52 2011 @@ -572,12 +572,12 @@ // removed, so we just need to splice the blocks. BI->eraseFromParent(); - // Make all PHI nodes that referred to Dest now refer to I as their source. - Dest->replaceAllUsesWith(I); - // Move all the instructions in the succ to the pred. I->getInstList().splice(I->end(), Dest->getInstList()); + // Make all PHI nodes that referred to Dest now refer to I as their source. + Dest->replaceAllUsesWith(I); + // Remove the dest block. Dest->eraseFromParent(); Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Thu Jun 23 01:24:52 2011 @@ -1097,15 +1097,15 @@ TheCall->replaceAllUsesWith(Returns[0]->getReturnValue()); } - // Update PHI nodes that use the ReturnBB to use the AfterCallBB. - BasicBlock *ReturnBB = Returns[0]->getParent(); - ReturnBB->replaceAllUsesWith(AfterCallBB); - // Splice the code from the return block into the block that it will return // to, which contains the code that was after the call. + BasicBlock *ReturnBB = Returns[0]->getParent(); AfterCallBB->getInstList().splice(AfterCallBB->begin(), ReturnBB->getInstList()); + // Update PHI nodes that use the ReturnBB to use the AfterCallBB. + ReturnBB->replaceAllUsesWith(AfterCallBB); + // Delete the return instruction now and empty ReturnBB now. Returns[0]->eraseFromParent(); ReturnBB->eraseFromParent(); @@ -1125,8 +1125,8 @@ // Splice the code entry block into calling block, right before the // unconditional branch. - CalleeEntry->replaceAllUsesWith(OrigBB); // Update PHI nodes OrigBB->getInstList().splice(Br, CalleeEntry->getInstList()); + CalleeEntry->replaceAllUsesWith(OrigBB); // Update PHI nodes // Remove the unconditional branch. OrigBB->getInstList().erase(Br); Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Jun 23 01:24:52 2011 @@ -427,6 +427,10 @@ BasicBlock *PredBB = DestBB->getSinglePredecessor(); assert(PredBB && "Block doesn't have a single predecessor!"); + // Splice all the instructions from PredBB to DestBB. + PredBB->getTerminator()->eraseFromParent(); + DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList()); + // Zap anything that took the address of DestBB. Not doing this will give the // address an invalid value. if (DestBB->hasAddressTaken()) { @@ -441,10 +445,6 @@ // Anything that branched to PredBB now branches to DestBB. PredBB->replaceAllUsesWith(DestBB); - // Splice all the instructions from PredBB to DestBB. - PredBB->getTerminator()->eraseFromParent(); - DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList()); - if (P) { DominatorTree *DT = P->getAnalysisIfAvailable(); if (DT) { @@ -660,17 +660,12 @@ // them, which helps expose duplicates, but we have to check all the // operands to be safe in case instcombine hasn't run. uintptr_t Hash = 0; - // This hash algorithm is quite weak as hash functions go, but it seems - // to do a good enough job for this particular purpose, and is very quick. for (User::op_iterator I = PN->op_begin(), E = PN->op_end(); I != E; ++I) { + // This hash algorithm is quite weak as hash functions go, but it seems + // to do a good enough job for this particular purpose, and is very quick. Hash ^= reinterpret_cast(static_cast(*I)); Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7)); } - for (PHINode::block_iterator I = PN->block_begin(), E = PN->block_end(); - I != E; ++I) { - Hash ^= reinterpret_cast(static_cast(*I)); - Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7)); - } // Avoid colliding with the DenseMap sentinels ~0 and ~0-1. Hash >>= 1; // If we've never seen this hash value before, it's a unique PHI. Modified: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Thu Jun 23 01:24:52 2011 @@ -47,14 +47,6 @@ if (It != VMap.end()) I->setOperand(op, It->second); } - - if (PHINode *PN = dyn_cast(I)) { - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { - ValueToValueMapTy::iterator It = VMap.find(PN->getIncomingBlock(i)); - if (It != VMap.end()) - PN->setIncomingBlock(i, cast(It->second)); - } - } } /// FoldBlockIntoPredecessor - Folds a basic block into its predecessor if it @@ -83,13 +75,13 @@ // Delete the unconditional branch from the predecessor... OnlyPred->getInstList().pop_back(); + // Move all definitions in the successor to the predecessor... + OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList()); + // Make all PHI nodes that referred to BB now refer to Pred as their // source... BB->replaceAllUsesWith(OnlyPred); - // Move all definitions in the successor to the predecessor... - OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList()); - std::string OldName = BB->getName(); // Erase basic block from the function... @@ -129,14 +121,14 @@ BasicBlock *Header = L->getHeader(); BranchInst *BI = dyn_cast(LatchBlock->getTerminator()); - + if (!BI || BI->isUnconditional()) { // The loop-rotate pass can be helpful to avoid this in many cases. DEBUG(dbgs() << " Can't unroll; loop not terminated by a conditional branch.\n"); return false; } - + if (Header->hasAddressTaken()) { // The loop-rotate pass can be helpful to avoid this in many cases. DEBUG(dbgs() << @@ -210,7 +202,7 @@ for (BasicBlock::iterator I = Header->begin(); isa(I); ++I) { PHINode *PN = cast(I); OrigPHINode.push_back(PN); - if (Instruction *I = + if (Instruction *I = dyn_cast(PN->getIncomingValueForBlock(LatchBlock))) if (L->contains(I)) LastValueMap[I] = I; @@ -223,7 +215,7 @@ for (unsigned It = 1; It != Count; ++It) { std::vector NewBlocks; - + for (std::vector::iterator BB = LoopBlocks.begin(), E = LoopBlocks.end(); BB != E; ++BB) { ValueToValueMapTy VMap; @@ -255,14 +247,16 @@ // the successor of the latch block. The successor of the exit block will // be updated specially after unrolling all the way. if (*BB != LatchBlock) - for (succ_iterator SI = succ_begin(*BB), SE = succ_end(*BB); SI != SE; - ++SI) - if (!L->contains(*SI)) - for (BasicBlock::iterator BBI = (*SI)->begin(); - PHINode *phi = dyn_cast(BBI); ++BBI) { - Value *Incoming = phi->getIncomingValueForBlock(*BB); - phi->addIncoming(Incoming, New); - } + for (Value::use_iterator UI = (*BB)->use_begin(), UE = (*BB)->use_end(); + UI != UE;) { + Instruction *UseInst = cast(*UI); + ++UI; + if (isa(UseInst) && !L->contains(UseInst)) { + PHINode *phi = cast(UseInst); + Value *Incoming = phi->getIncomingValueForBlock(*BB); + phi->addIncoming(Incoming, New); + } + } // Keep track of new headers and latches as we create them, so that // we can insert the proper branches later. @@ -282,32 +276,36 @@ NewBlocks.push_back(New); } - + // Remap all instructions in the most recent iteration for (unsigned i = 0; i < NewBlocks.size(); ++i) for (BasicBlock::iterator I = NewBlocks[i]->begin(), E = NewBlocks[i]->end(); I != E; ++I) ::RemapInstruction(I, LastValueMap); } - + // The latch block exits the loop. If there are any PHI nodes in the // successor blocks, update them to use the appropriate values computed as the // last iteration of the loop. if (Count != 1) { + SmallPtrSet Users; + for (Value::use_iterator UI = LatchBlock->use_begin(), + UE = LatchBlock->use_end(); UI != UE; ++UI) + if (PHINode *phi = dyn_cast(*UI)) + Users.insert(phi); + BasicBlock *LastIterationBB = cast(LastValueMap[LatchBlock]); - for (succ_iterator SI = succ_begin(LatchBlock), SE = succ_end(LatchBlock); + for (SmallPtrSet::iterator SI = Users.begin(), SE = Users.end(); SI != SE; ++SI) { - for (BasicBlock::iterator BBI = (*SI)->begin(); - PHINode *PN = dyn_cast(BBI); ++BBI) { - Value *InVal = PN->removeIncomingValue(LatchBlock, false); - // If this value was defined in the loop, take the value defined by the - // last iteration of the loop. - if (Instruction *InValI = dyn_cast(InVal)) { - if (L->contains(InValI)) - InVal = LastValueMap[InVal]; - } - PN->addIncoming(InVal, LastIterationBB); + PHINode *PN = *SI; + Value *InVal = PN->removeIncomingValue(LatchBlock, false); + // If this value was defined in the loop, take the value defined by the + // last iteration of the loop. + if (Instruction *InValI = dyn_cast(InVal)) { + if (L->contains(InValI)) + InVal = LastValueMap[InVal]; } + PN->addIncoming(InVal, LastIterationBB); } } @@ -354,19 +352,14 @@ // Replace the conditional branch with an unconditional one. BranchInst::Create(Dest, Term); Term->eraseFromParent(); - } - } - - // Merge adjacent basic blocks, if possible. - for (unsigned i = 0, e = Latches.size(); i != e; ++i) { - BranchInst *Term = cast(Latches[i]->getTerminator()); - if (Term->isUnconditional()) { - BasicBlock *Dest = Term->getSuccessor(0); - if (BasicBlock *Fold = FoldBlockIntoPredecessor(Dest, LI)) + // Merge adjacent basic blocks, if possible. + if (BasicBlock *Fold = FoldBlockIntoPredecessor(Dest, LI)) { std::replace(Latches.begin(), Latches.end(), Dest, Fold); + std::replace(Headers.begin(), Headers.end(), Dest, Fold); + } } } - + // At this point, the code is well formed. We now do a quick sweep over the // inserted code, doing constant propagation and dead code elimination as we // go. Modified: llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp Thu Jun 23 01:24:52 2011 @@ -16,7 +16,6 @@ #include "llvm/Type.h" #include "llvm/Constants.h" #include "llvm/Function.h" -#include "llvm/Instructions.h" #include "llvm/Metadata.h" #include "llvm/ADT/SmallVector.h" using namespace llvm; @@ -129,19 +128,6 @@ "Referenced value not in value map!"); } - // Remap phi nodes' incoming blocks. - if (PHINode *PN = dyn_cast(I)) { - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { - Value *V = MapValue(PN->getIncomingBlock(i), VMap, Flags); - // If we aren't ignoring missing entries, assert that something happened. - if (V != 0) - PN->setIncomingBlock(i, cast(V)); - else - assert((Flags & RF_IgnoreMissingEntries) && - "Referenced block not in value map!"); - } - } - // Remap attached metadata. SmallVector, 4> MDs; I->getAllMetadata(MDs); Modified: llvm/trunk/lib/VMCore/BasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/BasicBlock.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/BasicBlock.cpp (original) +++ llvm/trunk/lib/VMCore/BasicBlock.cpp Thu Jun 23 01:24:52 2011 @@ -308,19 +308,3 @@ return New; } -void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) { - TerminatorInst *TI = getTerminator(); - if (!TI) - // Cope with being called on a BasicBlock that doesn't have a terminator - // yet. Clang's CodeGenFunction::EmitReturnBlock() likes to do this. - return; - for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) { - BasicBlock *Succ = TI->getSuccessor(i); - for (iterator II = Succ->begin(); PHINode *PN = dyn_cast(II); - ++II) { - int i; - while ((i = PN->getBasicBlockIndex(this)) >= 0) - PN->setIncomingBlock(i, New); - } - } -} Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Thu Jun 23 01:24:52 2011 @@ -87,8 +87,11 @@ : Instruction(PN.getType(), Instruction::PHI, allocHungoffUses(PN.getNumOperands()), PN.getNumOperands()), ReservedSpace(PN.getNumOperands()) { - std::copy(PN.op_begin(), PN.op_end(), op_begin()); - std::copy(PN.block_begin(), PN.block_end(), block_begin()); + Use *OL = OperandList; + for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) { + OL[i] = PN.getOperand(i); + OL[i+1] = PN.getOperand(i+1); + } SubclassOptionalData = PN.SubclassOptionalData; } @@ -96,37 +99,31 @@ dropHungoffUses(); } -Use *PHINode::allocHungoffUses(unsigned N) const { - // Allocate the array of Uses of the incoming values, followed by a pointer - // (with bottom bit set) to the User, followed by the array of pointers to - // the incoming basic blocks. - size_t size = N * sizeof(Use) + sizeof(Use::UserRef) - + N * sizeof(BasicBlock*); - Use *Begin = static_cast(::operator new(size)); - Use *End = Begin + N; - (void) new(End) Use::UserRef(const_cast(this), 1); - return Use::initTags(Begin, End); -} - // removeIncomingValue - Remove an incoming value. This is useful if a // predecessor basic block is deleted. Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) { - Value *Removed = getIncomingValue(Idx); + unsigned NumOps = getNumOperands(); + Use *OL = OperandList; + assert(Idx*2 < NumOps && "BB not in PHI node!"); + Value *Removed = OL[Idx*2]; // Move everything after this operand down. // // FIXME: we could just swap with the end of the list, then erase. However, - // clients might not expect this to happen. The code as it is thrashes the + // client might not expect this to happen. The code as it is thrashes the // use/def lists, which is kinda lame. - std::copy(op_begin() + Idx + 1, op_end(), op_begin() + Idx); - std::copy(block_begin() + Idx + 1, block_end(), block_begin() + Idx); + for (unsigned i = (Idx+1)*2; i != NumOps; i += 2) { + OL[i-2] = OL[i]; + OL[i-2+1] = OL[i+1]; + } // Nuke the last value. - Op<-1>().set(0); - --NumOperands; + OL[NumOps-2].set(0); + OL[NumOps-2+1].set(0); + NumOperands = NumOps-2; // If the PHI node is dead, because it has zero entries, nuke it now. - if (getNumOperands() == 0 && DeletePHIIfEmpty) { + if (NumOps == 2 && DeletePHIIfEmpty) { // If anyone is using this PHI, make them use a dummy value instead... replaceAllUsesWith(UndefValue::get(getType())); eraseFromParent(); @@ -140,18 +137,15 @@ /// void PHINode::growOperands() { unsigned e = getNumOperands(); - unsigned NumOps = e + e / 2; - if (NumOps < 2) NumOps = 2; // 2 op PHI nodes are VERY common. - - Use *OldOps = op_begin(); - BasicBlock **OldBlocks = block_begin(); + // Multiply by 1.5 and round down so the result is still even. + unsigned NumOps = e + e / 4 * 2; + if (NumOps < 4) NumOps = 4; // 4 op PHI nodes are VERY common. ReservedSpace = NumOps; - OperandList = allocHungoffUses(ReservedSpace); - - std::copy(OldOps, OldOps + e, op_begin()); - std::copy(OldBlocks, OldBlocks + e, block_begin()); - + Use *OldOps = OperandList; + Use *NewOps = allocHungoffUses(NumOps); + std::copy(OldOps, OldOps + e, NewOps); + OperandList = NewOps; Use::zap(OldOps, OldOps + e, true); } Modified: llvm/trunk/lib/VMCore/User.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/User.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/User.cpp (original) +++ llvm/trunk/lib/VMCore/User.cpp Thu Jun 23 01:24:52 2011 @@ -40,10 +40,8 @@ //===----------------------------------------------------------------------===// Use *User::allocHungoffUses(unsigned N) const { - // Allocate the array of Uses, followed by a pointer (with bottom bit set) to - // the User. - size_t size = N * sizeof(Use) + sizeof(Use::UserRef); - Use *Begin = static_cast(::operator new(size)); + Use *Begin = static_cast(::operator new(sizeof(Use) * N + + sizeof(Use::UserRef))); Use *End = Begin + N; (void) new(End) Use::UserRef(const_cast(this), 1); return Use::initTags(Begin, End); Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Thu Jun 23 01:24:52 2011 @@ -305,9 +305,6 @@ U.set(New); } - - if (BasicBlock *BB = dyn_cast(this)) - BB->replaceSuccessorsPhiUsesWith(cast(New)); } void Value::replaceAllUsesWith(Value *New) { Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=133700&r1=133699&r2=133700&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Thu Jun 23 01:24:52 2011 @@ -1139,6 +1139,9 @@ for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { Assert1(PN.getType() == PN.getIncomingValue(i)->getType(), "PHI node operands are not the same type as the result!", &PN); + Assert1(isa(PN.getOperand( + PHINode::getOperandNumForIncomingBlock(i))), + "PHI node incoming block is not a BasicBlock!", &PN); } // All other PHI node constraints are checked in the visitBasicBlock method. From echristo at apple.com Thu Jun 23 01:31:47 2011 From: echristo at apple.com (Eric Christopher) Date: Wed, 22 Jun 2011 23:31:47 -0700 Subject: [llvm-commits] [llvm] r133513 - in /llvm/trunk: include/llvm/ include/llvm/Support/ lib/Target/CppBackend/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ In-Reply-To: <5AAC95DA-F372-4AC4-BF66-AF474C061E34@app