From baldrick at free.fr Mon May 4 02:00:47 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 4 May 2009 09:00:47 +0200 Subject: [llvm-commits] [llvm] r70820 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/no-irreducible-loops.ll In-Reply-To: <200905040228.n442S8tg027269@zion.cs.uiuc.edu> References: <200905040228.n442S8tg027269@zion.cs.uiuc.edu> Message-ID: <200905040900.50025.baldrick@free.fr> Hi Chris, > +/// FindLoopHeaders - We do not wan jump threading to turn proper loop do not wan -> do not want Ciao, Duncan. From baldrick at free.fr Mon May 4 02:05:18 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 4 May 2009 09:05:18 +0200 Subject: [llvm-commits] [llvm-gcc-4.2] r70801 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp In-Reply-To: <200905032136.n43LaNFN018015@zion.cs.uiuc.edu> References: <200905032136.n43LaNFN018015@zion.cs.uiuc.edu> Message-ID: <200905040905.18847.baldrick@free.fr> Hi Bill, > Don'e create debug info for ObjC metadata. how about setting DECL_ARTIFICIAL for such globals, and then teach the backend not to output debug info for globals with DECL_ARTIFICIAL set? /* Used to indicate that this DECL represents a compiler-generated entity. */ #define DECL_ARTIFICIAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.artificial_flag) Ciao, Duncan. > > Modified: > llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp > > 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=70801&r1=70800&r2=70801&view=diff > > ============================================================================== > --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) > +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Sun May 3 16:36:23 2009 > @@ -1390,8 +1390,15 @@ > // No debug info for globals when optimization is on. While this is > // something that would be accurate and useful to a user, it currently > // affects some optimizations that, e.g., count uses. > - if (TheDebugInfo && !optimize) > - TheDebugInfo->EmitGlobalVariable(GV, decl); > + if (TheDebugInfo && !optimize) { > + const char *Name = GV->getName().c_str(); > + const char LPrefix[] = "\01L_OBJC_"; > + const char lPrefix[] = "\01l_OBJC_"; > + > + if (strncmp(Name, LPrefix, sizeof(LPrefix) - 1) != 0 && > + strncmp(Name, lPrefix, sizeof(lPrefix) - 1) != 0) > + TheDebugInfo->EmitGlobalVariable(GV, decl); > + } > > TREE_ASM_WRITTEN(decl) = 1; > timevar_pop(TV_LLVM_GLOBALS); > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From kremenek at apple.com Mon May 4 02:13:49 2009 From: kremenek at apple.com (Ted Kremenek) Date: Mon, 04 May 2009 07:13:49 -0000 Subject: [llvm-commits] [llvm] r70838 - /llvm/tags/checker/checker-0.193/ Message-ID: <200905040713.n447Dno3004098@zion.cs.uiuc.edu> Author: kremenek Date: Mon May 4 02:13:49 2009 New Revision: 70838 URL: http://llvm.org/viewvc/llvm-project?rev=70838&view=rev Log: Removing checker-0.193. Removed: llvm/tags/checker/checker-0.193/ From kremenek at apple.com Mon May 4 02:15:04 2009 From: kremenek at apple.com (Ted Kremenek) Date: Mon, 04 May 2009 07:15:04 -0000 Subject: [llvm-commits] [llvm] r70840 - /llvm/tags/checker/checker-0.193/ Message-ID: <200905040715.n447F469004149@zion.cs.uiuc.edu> Author: kremenek Date: Mon May 4 02:15:04 2009 New Revision: 70840 URL: http://llvm.org/viewvc/llvm-project?rev=70840&view=rev Log: Tagging checker-0.193. Added: llvm/tags/checker/checker-0.193/ - copied from r70839, llvm/trunk/ From baldrick at free.fr Mon May 4 02:42:54 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 4 May 2009 09:42:54 +0200 Subject: [llvm-commits] [llvm] r70790 - /llvm/trunk/docs/LangRef.html In-Reply-To: <470D68BA-BCC1-4F82-9D78-426358B58E2E@nondot.org> References: <200905031906.n43J60Bg012814@zion.cs.uiuc.edu> <200905032206.29498.baldrick@free.fr> <470D68BA-BCC1-4F82-9D78-426358B58E2E@nondot.org> Message-ID: <200905040942.54978.baldrick@free.fr> Hi Chris, > >> throw > >> is the empty set. :) Thanks to Fritz for pointing this out. > > > > what's wrong with a readonly function using unwind? I think > > the use of unwind is orthogonal to readonly: it's what the > > nounwind attribute is for. Of course a readonly function can't > > call the C++ throw routine etc, but that's a different issue. > > If you want readonly to mean: doesn't do anything annoying > > (no side-effects), then the name should be changed, and the > > function attributes taught to do loop analysis and not mark > > a function readonly unless all loops are finite etc. I think > > it is better to keep readonly and nounwind separate. > > I can definitely be convinced :), but my understanding is that the > compiler currently deletes readonly/readnone calls if they are dead. yes, this is a known bug :) > We could change this to also require them to be nounwind, and change > the C front-ends to have pure/const also add nounwind. What do you > think? That's my preferred solution. I had a look at isInstructionTriviallyDead and was struck by the fact that it doesn't check isTrapping. Is it valid to delete a divide by zero if the result has no uses? Currently this is done. If so, is it valid to delete a readonly call even if it may throw an exception? Ciao, Duncan. From eli.friedman at gmail.com Mon May 4 03:31:43 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 4 May 2009 01:31:43 -0700 Subject: [llvm-commits] [llvm] r70790 - /llvm/trunk/docs/LangRef.html In-Reply-To: <200905040942.54978.baldrick@free.fr> References: <200905031906.n43J60Bg012814@zion.cs.uiuc.edu> <200905032206.29498.baldrick@free.fr> <470D68BA-BCC1-4F82-9D78-426358B58E2E@nondot.org> <200905040942.54978.baldrick@free.fr> Message-ID: On Mon, May 4, 2009 at 12:42 AM, Duncan Sands wrote: > Is it valid > to delete a divide by zero if the result has no uses? Yes, it is valid; division by zero is undefined behavior, so it can do anything; we make no attempt to preserve any traps from that. For example, we optimize x/x to 1 (where x is an integer). Besides, even if we did try to preserve the trap, depending on a trap isn't portable; for example, the PowerPC division instruction never traps. >?If so, is it valid to delete a readonly call even if it may throw > an exception? No, it is not valid; throwing an exception is well-defined behavior. (Of course, assuming throwing an exception from a readonly call is legal.) -Eli From edwintorok at gmail.com Mon May 4 03:49:05 2009 From: edwintorok at gmail.com (=?ISO-8859-1?Q?T=F6r=F6k_Edwin?=) Date: Mon, 04 May 2009 11:49:05 +0300 Subject: [llvm-commits] [llvm] r70790 - /llvm/trunk/docs/LangRef.html In-Reply-To: <470D68BA-BCC1-4F82-9D78-426358B58E2E@nondot.org> References: <200905031906.n43J60Bg012814@zion.cs.uiuc.edu> <200905032206.29498.baldrick@free.fr> <470D68BA-BCC1-4F82-9D78-426358B58E2E@nondot.org> Message-ID: <49FEAC01.4030708@gmail.com> On 2009-05-03 23:11, Chris Lattner wrote: > On May 3, 2009, at 1:06 PM, Duncan Sands wrote: > > >> Hi Chris, >> >> >>> Remove obsolete wording, the only exception a readnone function can >>> throw >>> is the empty set. :) Thanks to Fritz for pointing this out. >>> >> what's wrong with a readonly function using unwind? I think >> the use of unwind is orthogonal to readonly: it's what the >> nounwind attribute is for. Of course a readonly function can't >> call the C++ throw routine etc, but that's a different issue. >> If you want readonly to mean: doesn't do anything annoying >> (no side-effects), then the name should be changed, and the >> function attributes taught to do loop analysis and not mark >> a function readonly unless all loops are finite etc. I think >> it is better to keep readonly and nounwind separate. >> > > I can definitely be convinced :), but my understanding is that the > compiler currently deletes readonly/readnone calls if they are dead. > We could change this to also require them to be nounwind, and change > the C front-ends to have pure/const also add nounwind. I think gcc's pure/const attributes imply nounwind, though the documentation doesn't explicitly say so: `const' Many functions do not examine any values except their arguments, and have no effects except the return value. Basically this is just slightly more strict class than the `pure' attribute below, since function is not allowed to read global memory. I read "No effect except the return value" = cannot throw exceptions, does not write to global memory, ... If this is correct, then nounwind should be added by the C frontend. Also a function marked as pure/const is not allowed to have infinite loops either: "Interesting non-pure functions are functions with infinite loops or those depending on volatile memory or other system resource, that may change between two consecutive calls (such as `feof' in a multithreading environment)" Of course LLVM can define readonly/readnone to have less strict requirements, but then the C frontend should add more attributes than just 'readonly/readnone' for functions marked pure/const to match gcc's definition if we want optimizers to take advantage of knowing the strict requirements. Also what happens with C++'s const member functions? If there are mutable class members they aren't technically readonly, since they have the side-effect of modifying the object. However most people use this as a 'logical' const, i.e. the object may be modified, but the new object is equivalent to the old one. Can this be modeled via an LLVM attribute? Best regards, --Edwin From baldrick at free.fr Mon May 4 04:06:09 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 4 May 2009 11:06:09 +0200 Subject: [llvm-commits] [llvm] r70790 - /llvm/trunk/docs/LangRef.html In-Reply-To: <49FEAC01.4030708@gmail.com> References: <200905031906.n43J60Bg012814@zion.cs.uiuc.edu> <470D68BA-BCC1-4F82-9D78-426358B58E2E@nondot.org> <49FEAC01.4030708@gmail.com> Message-ID: <200905041106.10398.baldrick@free.fr> Hi Edwin, > I think gcc's pure/const attributes imply nounwind, though the > documentation doesn't explicitly say so: > > `const' > Many functions do not examine any values except their arguments, > and have no effects except the return value. Basically this is > just slightly more strict class than the `pure' attribute below, > since function is not allowed to read global memory. > > > I read "No effect except the return value" = cannot throw exceptions, > does not write to global memory, ... this comes up with great regularity on the gcc mailing list. One reason is that Ada wants 'const' functions to be able to throw exceptions (so that Ada's pure can be mapped onto 'const'), while C people tend to feel that 'const' should mean "no side effects", so don't think such functions should throw exceptions. I don't think any decision was made. I think the solution is to break 'const' up into multiple concepts, i.e. do as you suggest: have C map 'const' to readnone+nounwind, and have Ada map 'pure' to readnone. > If this is correct, then nounwind should be added by the C frontend. I agree. > Also a function marked as pure/const is not allowed to have infinite > loops either: > > "Interesting non-pure functions are functions with infinite loops > or those depending on volatile memory or other system resource, > that may change between two consecutive calls (such as `feof' in a > multithreading environment)" See PR965. The suggested solution is to have yet another attribute ("willreturn", "finite" or something like that) that can be used to mark functions that will not infinite loop. Then have the C front-end add that to 'const' functions, and have a pass that deduces it using loop info. > Of course LLVM can define readonly/readnone to have less strict > requirements, but then the C frontend should add more attributes than > just 'readonly/readnone' for > functions marked pure/const to match gcc's definition if we want > optimizers to take advantage of knowing the strict requirements. Right. > Also what happens with C++'s const member functions? Nothing special is done for them right now. > If there are mutable class members they aren't technically readonly, > since they have the side-effect of modifying the object. Yup. > However most people use this as a 'logical' const, i.e. the object may > be modified, but the new object is equivalent to the old one. > Can this be modeled via an LLVM attribute? You could always cheat and mark it readonly/readnone anyway. This might work in some circumstances if no-one can tell that these modifications are going on. Ciao, Duncan. From eli.friedman at gmail.com Mon May 4 04:22:04 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 4 May 2009 02:22:04 -0700 Subject: [llvm-commits] [llvm] r70790 - /llvm/trunk/docs/LangRef.html In-Reply-To: <200905041106.10398.baldrick@free.fr> References: <200905031906.n43J60Bg012814@zion.cs.uiuc.edu> <470D68BA-BCC1-4F82-9D78-426358B58E2E@nondot.org> <49FEAC01.4030708@gmail.com> <200905041106.10398.baldrick@free.fr> Message-ID: 2009/5/4 Duncan Sands : >> However most people use this as a 'logical' const, i.e. the object may >> be modified, but the new object is equivalent to the old one. >> Can this be modeled via an LLVM attribute? > > You could always cheat and mark it readonly/readnone anyway. ?This > might work in some circumstances if no-one can tell that these modifications > are going on. That would get to be extremely nasty... for example, take an class which caches the results of queries in a hashtable. Suppose only some of the hashtable queries get inlined: then the compiler could end up reusing the saved hashtable even though it moved because the hashtable grew. -Eli From nicolas.geoffray at lip6.fr Mon May 4 04:54:36 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 04 May 2009 11:54:36 +0200 Subject: [llvm-commits] [llvm] r70820 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/no-irreducible-loops.ll In-Reply-To: <200905040228.n442S8tg027269@zion.cs.uiuc.edu> References: <200905040228.n442S8tg027269@zion.cs.uiuc.edu> Message-ID: <49FEBB5C.4090707@lip6.fr> Hi Chris, Chris Lattner wrote: > +#ifdef NDEBUG > + SmallPtrSet LoopHeaders; > +#else > + SmallSet, 16> LoopHeaders; > +#endif > > > @@ -109,15 +121,42 @@ > DOUT << " JT: Deleting dead block '" << BB->getNameStart() > << "' with terminator: " << *BB->getTerminator(); > DeleteDeadBlock(BB); > + LoopHeaders.erase(BB); > SmallSet is an AssertingVH, so erasing the block in the LoopHeaders should come before deleting the block. Nicolas From nicolas.geoffray at lip6.fr Mon May 4 05:20:30 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 04 May 2009 12:20:30 +0200 Subject: [llvm-commits] [llvm] r70820 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/no-irreducible-loops.ll In-Reply-To: <49FEBB5C.4090707@lip6.fr> References: <200905040228.n442S8tg027269@zion.cs.uiuc.edu> <49FEBB5C.4090707@lip6.fr> Message-ID: <49FEC16E.3000005@lip6.fr> Nicolas Geoffray wrote: > > SmallSet is an AssertingVH, so erasing the block in the LoopHeaders > should come before deleting the block. > > Woops, read LoopHeaders instead of SmallSet. > Nicolas > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From asl at math.spbu.ru Mon May 4 05:24:53 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 04 May 2009 10:24:53 -0000 Subject: [llvm-commits] [llvm] r70848 - /llvm/trunk/docs/GettingStarted.html Message-ID: <200905041024.n44AOv79021738@zion.cs.uiuc.edu> Author: asl Date: Mon May 4 05:24:46 2009 New Revision: 70848 URL: http://llvm.org/viewvc/llvm-project?rev=70848&view=rev Log: It turns out that this version of gcc is broken (cygwin is well-known in shipping of broken/buggy/snapshot-based compilers) Modified: llvm/trunk/docs/GettingStarted.html Modified: llvm/trunk/docs/GettingStarted.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/GettingStarted.html?rev=70848&r1=70847&r2=70848&view=diff ============================================================================== --- llvm/trunk/docs/GettingStarted.html (original) +++ llvm/trunk/docs/GettingStarted.html Mon May 4 05:24:46 2009 @@ -545,6 +545,9 @@ about symbols remaining in the table on destruction.

GCC 4.1.2 20071124 (Red Hat 4.1.2-42): Suffers from the same symptoms as the previous one. It appears to work with ENABLE_OPTIMIZED=0 (the default).

+

Cygwin GCC 4.3.2 20080827 (beta) 2: + Users reported various problems related + with link errors when using this GCC version.

GNU ld 2.16.X. Some 2.16.X versions of the ld linker will produce very long warning messages complaining that some ".gnu.linkonce.t.*" symbol was From asl at math.spbu.ru Mon May 4 05:25:31 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 04 May 2009 10:25:31 -0000 Subject: [llvm-commits] [llvm] r70849 - /llvm/trunk/Makefile.rules Message-ID: <200905041025.n44APWof021763@zion.cs.uiuc.edu> Author: asl Date: Mon May 4 05:25:30 2009 New Revision: 70849 URL: http://llvm.org/viewvc/llvm-project?rev=70849&view=rev Log: Workaround libstdc++ bug when crosscompiling to mingw. Patch by Jay Foad! Modified: llvm/trunk/Makefile.rules Modified: llvm/trunk/Makefile.rules URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.rules?rev=70849&r1=70848&r2=70849&view=diff ============================================================================== --- llvm/trunk/Makefile.rules (original) +++ llvm/trunk/Makefile.rules Mon May 4 05:25:30 2009 @@ -361,6 +361,15 @@ LD.Flags += -Wl,--no-relax endif +ifeq ($(OS),MingW) + ifeq ($(LLVM_CROSS_COMPILING),1) + # Work around http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=525016 + ifdef TOOLNAME + LD.Flags += -Wl,--allow-multiple-definition + endif + endif +endif + #-------------------------------------------------------------------- # Directory locations #-------------------------------------------------------------------- From baldrick at free.fr Mon May 4 07:48:16 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 04 May 2009 12:48:16 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r70855 - in /llvm-gcc-4.2/trunk/gcc: config/i386/llvm-i386-target.h llvm-types.cpp Message-ID: <200905041248.n44CmH3Q026592@zion.cs.uiuc.edu> Author: baldrick Date: Mon May 4 07:48:14 2009 New Revision: 70855 URL: http://llvm.org/viewvc/llvm-project?rev=70855&view=rev Log: Fix PR3967: allow enums and references to have the "inreg" attribute, not just integers and pointers. Based on a patch by Haohui Mai. Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h?rev=70855&r1=70854&r2=70855&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h Mon May 4 07:48:14 2009 @@ -76,8 +76,8 @@ PAttribute |= Attribute::InReg; \ else \ local_fp_regparm = 0; \ - } else if (TREE_CODE(Type) == INTEGER_TYPE || \ - TREE_CODE(Type) == POINTER_TYPE) { \ + } else if (INTEGRAL_TYPE_P(Type) || \ + POINTER_TYPE_P(Type)) { \ int words = \ (Size + BITS_PER_WORD - 1) / BITS_PER_WORD; \ local_regparm -= words; \ Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=70855&r1=70854&r2=70855&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Mon May 4 07:48:14 2009 @@ -1241,8 +1241,8 @@ #ifdef LLVM_TARGET_ENABLE_REGPARM // Allow the target to mark this as inreg. - if (TREE_CODE(ArgTy) == INTEGER_TYPE || TREE_CODE(ArgTy) == POINTER_TYPE || - TREE_CODE(ArgTy) == REAL_TYPE) + if (INTEGRAL_TYPE_P(ArgTy) || POINTER_TYPE_P(ArgTy) || + SCALAR_FLOAT_TYPE_P(ArgTy)) LLVM_ADJUST_REGPARM_ATTRIBUTE(PAttributes, ArgTy, TREE_INT_CST_LOW(TYPE_SIZE(ArgTy)), local_regparam, local_fp_regparam); From baldrick at free.fr Mon May 4 07:54:15 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 04 May 2009 12:54:15 -0000 Subject: [llvm-commits] [llvm] r70856 - /llvm/trunk/test/FrontendC/2009-05-04-EnumInreg.c Message-ID: <200905041254.n44CsJC4026791@zion.cs.uiuc.edu> Author: baldrick Date: Mon May 4 07:54:02 2009 New Revision: 70856 URL: http://llvm.org/viewvc/llvm-project?rev=70856&view=rev Log: Testcase for PR3967. Added: llvm/trunk/test/FrontendC/2009-05-04-EnumInreg.c Added: llvm/trunk/test/FrontendC/2009-05-04-EnumInreg.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC/2009-05-04-EnumInreg.c?rev=70856&view=auto ============================================================================== --- llvm/trunk/test/FrontendC/2009-05-04-EnumInreg.c (added) +++ llvm/trunk/test/FrontendC/2009-05-04-EnumInreg.c Mon May 4 07:54:02 2009 @@ -0,0 +1,17 @@ +// RUN: llvm-gcc -S -m32 -mregparm=3 %s -emit-llvm -o - | grep {inreg %action} +// XTARGET: x86 +// PR3967 + +enum kobject_action { + KOBJ_ADD, + KOBJ_REMOVE, + KOBJ_CHANGE, + KOBJ_MOVE, + KOBJ_ONLINE, + KOBJ_OFFLINE, + KOBJ_MAX +}; + +struct kobject; + +int kobject_uevent(struct kobject *kobj, enum kobject_action action) {} From akyrtzi at gmail.com Mon May 4 11:23:49 2009 From: akyrtzi at gmail.com (Argiris Kirtzidis) Date: Mon, 04 May 2009 16:23:49 -0000 Subject: [llvm-commits] [llvm] r70871 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfWriter.cpp lib/CodeGen/SelectionDAG/FastISel.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp test/DebugInfo/2009-01-29-HeaderLocation.ll utils/TableGen/AsmWriterEmitter.cpp Message-ID: <200905041623.n44GNnOc001289@zion.cs.uiuc.edu> Author: akirtzidis Date: Mon May 4 11:23:49 2009 New Revision: 70871 URL: http://llvm.org/viewvc/llvm-project?rev=70871&view=rev Log: -Remove the DwarfWriter::RecordSourceLine calls from the instruction selectors. -Depend on DebugLocs for source line info. (Comes with Regression-Be-Gone(tm)) Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/test/DebugInfo/2009-01-29-HeaderLocation.ll llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=70871&r1=70870&r2=70871&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Mon May 4 11:23:49 2009 @@ -3262,11 +3262,12 @@ // Assumes in correct section after the entry point. EmitLabel("func_begin", ++SubprogramCount); - // Emit label for the implicitly defined dbg.stoppoint at the start of - // the function. - if (!Lines.empty()) { - const SrcLineInfo &LineInfo = Lines[0]; - Asm->printLabel(LineInfo.getLabelID()); + DebugLoc FDL = MF->getDefaultDebugLoc(); + if (!FDL.isUnknown()) { + DebugLocTuple DLT = MF->getDebugLocTuple(FDL); + unsigned LabelID = RecordSourceLine(DLT.Line, DLT.Col, + DICompileUnit(DLT.CompileUnit)); + Asm->printLabel(LabelID); } if (TimePassesIsEnabled) Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=70871&r1=70870&r2=70871&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Mon May 4 11:23:49 2009 @@ -333,11 +333,6 @@ unsigned Col = SPI->getColumn(); unsigned Idx = MF.getOrCreateDebugLocID(CU.getGV(), Line, Col); setCurDebugLoc(DebugLoc::get(Idx)); - if (DW && DW->ShouldEmitDwarfDebug()) { - unsigned ID = DW->RecordSourceLine(Line, Col, CU); - const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); - BuildMI(MBB, DL, II).addImm(ID); - } } return true; } @@ -402,7 +397,7 @@ CompileUnit.getGV(), Line, 0))); if (DW && DW->ShouldEmitDwarfDebug()) { - unsigned LabelID = DW->RecordSourceLine(Line, 0, CompileUnit); + unsigned LabelID = MMI->NextLabelID(); const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); BuildMI(MBB, DL, II).addImm(LabelID); DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); @@ -414,10 +409,9 @@ } else { // Record the source line. unsigned Line = Subprogram.getLineNumber(); - setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID( + MF.setDefaultDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID( CompileUnit.getGV(), Line, 0))); if (DW && DW->ShouldEmitDwarfDebug()) { - DW->RecordSourceLine(Line, 0, CompileUnit); // llvm.dbg.func_start also defines beginning of function scope. DW->RecordRegionStart(cast(FSI->getSubprogram())); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=70871&r1=70870&r2=70871&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon May 4 11:23:49 2009 @@ -3980,7 +3980,7 @@ MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0))); if (DW && DW->ShouldEmitDwarfDebug()) { - unsigned LabelID = DW->RecordSourceLine(Line, 0, CompileUnit); + unsigned LabelID = DAG.getMachineModuleInfo()->NextLabelID(); DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), getRoot(), LabelID)); DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); @@ -3992,10 +3992,9 @@ } else { // Record the source line. unsigned Line = Subprogram.getLineNumber(); - setCurDebugLoc(DebugLoc::get( + MF.setDefaultDebugLoc(DebugLoc::get( MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0))); if (DW && DW->ShouldEmitDwarfDebug()) { - DW->RecordSourceLine(Line, 0, CompileUnit); // llvm.dbg.func_start also defines beginning of function scope. DW->RecordRegionStart(cast(FSI.getSubprogram())); } Modified: llvm/trunk/test/DebugInfo/2009-01-29-HeaderLocation.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-01-29-HeaderLocation.ll?rev=70871&r1=70870&r2=70871&view=diff ============================================================================== --- llvm/trunk/test/DebugInfo/2009-01-29-HeaderLocation.ll (original) +++ llvm/trunk/test/DebugInfo/2009-01-29-HeaderLocation.ll Mon May 4 11:23:49 2009 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc | grep "m.h" | count 1 +; RUN: llvm-as < %s | llc | grep "\\"m.h\\"" | count 1 target triple = "i386-apple-darwin9.6" %llvm.dbg.anchor.type = type { i32, i32 } %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } Modified: llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp?rev=70871&r1=70870&r2=70871&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp Mon May 4 11:23:49 2009 @@ -650,12 +650,12 @@ O << "\";\n\n"; O << " if (TAI->doesSupportDebugInformation() &&\n" - << " DW->ShouldEmitDwarfDebug() && OptLevel != CodeGenOpt::None) {\n" + << " DW->ShouldEmitDwarfDebug()) {\n" << " DebugLoc CurDL = MI->getDebugLoc();\n\n" << " if (!CurDL.isUnknown()) {\n" << " static DebugLocTuple PrevDLT(0, ~0U, ~0U);\n" << " DebugLocTuple CurDLT = MF->getDebugLocTuple(CurDL);\n\n" - << " if (PrevDLT.CompileUnit != 0 && PrevDLT != CurDLT)\n" + << " if (CurDLT.CompileUnit != 0 && PrevDLT != CurDLT)\n" << " printLabel(DW->RecordSourceLine(CurDLT.Line, CurDLT.Col,\n" << " DICompileUnit(CurDLT.CompileUnit)));\n\n" << " PrevDLT = CurDLT;\n" From sabre at nondot.org Mon May 4 11:29:24 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 04 May 2009 16:29:24 -0000 Subject: [llvm-commits] [llvm] r70872 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200905041629.n44GTOVI001473@zion.cs.uiuc.edu> Author: lattner Date: Mon May 4 11:29:24 2009 New Revision: 70872 URL: http://llvm.org/viewvc/llvm-project?rev=70872&view=rev Log: fix some problems spotted by Duncan and Nicolas Geoffray Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=70872&r1=70871&r2=70872&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Mon May 4 11:29:24 2009 @@ -120,8 +120,8 @@ BB != &BB->getParent()->getEntryBlock()) { DOUT << " JT: Deleting dead block '" << BB->getNameStart() << "' with terminator: " << *BB->getTerminator(); - DeleteDeadBlock(BB); LoopHeaders.erase(BB); + DeleteDeadBlock(BB); Changed = true; } } @@ -133,7 +133,7 @@ return EverChanged; } -/// FindLoopHeaders - We do not wan jump threading to turn proper loop +/// FindLoopHeaders - We do not want jump threading to turn proper loop /// structures into irreducible loops. Doing this breaks up the loop nesting /// hierarchy and pessimizes later transformations. To prevent this from /// happening, we first have to find the loop headers. Here we approximate this From clattner at apple.com Mon May 4 11:37:16 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 4 May 2009 09:37:16 -0700 Subject: [llvm-commits] [llvm] r70790 - /llvm/trunk/docs/LangRef.html In-Reply-To: <200905040942.54978.baldrick@free.fr> References: <200905031906.n43J60Bg012814@zion.cs.uiuc.edu> <200905032206.29498.baldrick@free.fr> <470D68BA-BCC1-4F82-9D78-426358B58E2E@nondot.org> <200905040942.54978.baldrick@free.fr> Message-ID: <2C582DE5-9DA5-43D6-B46E-76740F5C98F2@apple.com> On May 4, 2009, at 12:42 AM, Duncan Sands wrote: >> I can definitely be convinced :), but my understanding is that the >> compiler currently deletes readonly/readnone calls if they are dead. > > yes, this is a known bug :) Ok, well I still think it is good to have the docs and code line up. :) That said, I do agree fully now that decoupling readnone/only and nothrow is the right thing to do. If you want to make this change, please make sure that all of the compiler agrees, update llvm-gcc, and fix the docs to be very clear about this. It is probably worth mentioning explicitly that while non- nothrow readonly functions are allowed to unwind, they cannot use C++ EH to do it because it changes global state. >> We could change this to also require them to be nounwind, and change >> the C front-ends to have pure/const also add nounwind. What do you >> think? > > That's my preferred solution. Ok, I agree that it makes sense. It would also be good to change llvm- gcc to set nounwind on all pure/const functions. Duncan wrote: > I had a look at isInstructionTriviallyDead > and was struck by the fact that it doesn't check isTrapping. Is it > valid > to delete a divide by zero if the result has no uses? Currently > this is > done. If so, is it valid to delete a readonly call even if it may > throw > an exception? Eli responded: > Yes, it is valid; division by zero is undefined behavior, so it can do > anything; we make no attempt to preserve any traps from that. These are the C semantics, and the semantics that LLVM IR currently has. However, in the future, we will probably end up extending LLVM IR to better serve other languages. In a language that requires a trap to be generated for things like this (and/or null pointer dereferences etc), then an exception could be generated. The optimizer will have to be careful not to do unsafe transformations. For example, a function that loads a potentially null pointer and is supposed to trap on it cannot be deleted if dead, but it can be CSE'd. -Chris From clattner at apple.com Mon May 4 11:38:49 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 4 May 2009 09:38:49 -0700 Subject: [llvm-commits] [llvm] r70790 - /llvm/trunk/docs/LangRef.html In-Reply-To: <49FEAC01.4030708@gmail.com> References: <200905031906.n43J60Bg012814@zion.cs.uiuc.edu> <200905032206.29498.baldrick@free.fr> <470D68BA-BCC1-4F82-9D78-426358B58E2E@nondot.org> <49FEAC01.4030708@gmail.com> Message-ID: On May 4, 2009, at 1:49 AM, T?r?k Edwin wrote: > Also what happens with C++'s const member functions? > If there are mutable class members they aren't technically readonly, > since they have the side-effect of modifying the object. > However most people use this as a 'logical' const, i.e. the object may > be modified, but the new object is equivalent to the old one. > Can this be modeled via an LLVM attribute? No, this cannot be modeled, because const is allowed to be cast away. -Chris From baldrick at free.fr Mon May 4 11:45:55 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 04 May 2009 16:45:55 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r70874 - /llvm-gcc-4.2/trunk/gcc/c-common.c Message-ID: <200905041645.n44GjtJ0002012@zion.cs.uiuc.edu> Author: baldrick Date: Mon May 4 11:45:55 2009 New Revision: 70874 URL: http://llvm.org/viewvc/llvm-project?rev=70874&view=rev Log: In C-like languages, marking a function pure/const means it cannot throw an exception. This is not the case in other languages such as Ada. Make this explicit by having pure/const imply nothrow for C and friends. Modified: llvm-gcc-4.2/trunk/gcc/c-common.c Modified: llvm-gcc-4.2/trunk/gcc/c-common.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-common.c?rev=70874&r1=70873&r2=70874&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-common.c (original) +++ llvm-gcc-4.2/trunk/gcc/c-common.c Mon May 4 11:45:55 2009 @@ -4739,9 +4739,12 @@ tree type = TREE_TYPE (*node); /* See FIXME comment on noreturn in c_common_attribute_table. */ - if (TREE_CODE (*node) == FUNCTION_DECL) + /* LLVM LOCAL begin */ + if (TREE_CODE (*node) == FUNCTION_DECL) { TREE_READONLY (*node) = 1; - else if (TREE_CODE (type) == POINTER_TYPE + TREE_NOTHROW (*node) = 1; + } else if (TREE_CODE (type) == POINTER_TYPE + /* LLVM LOCAL end */ && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) TREE_TYPE (*node) = build_pointer_type @@ -5573,10 +5576,13 @@ handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args), int ARG_UNUSED (flags), bool *no_add_attrs) { - if (TREE_CODE (*node) == FUNCTION_DECL) + /* LLVM LOCAL begin */ + if (TREE_CODE (*node) == FUNCTION_DECL) { DECL_IS_PURE (*node) = 1; - /* ??? TODO: Support types. */ - else + TREE_NOTHROW (*node) = 1; + } else + /* LLVM LOCAL end */ + /* ??? TODO: Support types. */ { warning (OPT_Wattributes, "%qE attribute ignored", name); *no_add_attrs = true; From baldrick at free.fr Mon May 4 11:47:11 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 04 May 2009 16:47:11 -0000 Subject: [llvm-commits] [llvm] r70875 - /llvm/trunk/test/FrontendC++/2009-05-04-PureConstNounwind.cpp Message-ID: <200905041647.n44GlBbP002059@zion.cs.uiuc.edu> Author: baldrick Date: Mon May 4 11:47:11 2009 New Revision: 70875 URL: http://llvm.org/viewvc/llvm-project?rev=70875&view=rev Log: Check that pure/const functions are marked nounwind. Added: llvm/trunk/test/FrontendC++/2009-05-04-PureConstNounwind.cpp Added: llvm/trunk/test/FrontendC++/2009-05-04-PureConstNounwind.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/2009-05-04-PureConstNounwind.cpp?rev=70875&view=auto ============================================================================== --- llvm/trunk/test/FrontendC++/2009-05-04-PureConstNounwind.cpp (added) +++ llvm/trunk/test/FrontendC++/2009-05-04-PureConstNounwind.cpp Mon May 4 11:47:11 2009 @@ -0,0 +1,8 @@ +// RUN: %llvmgxx -S -emit-llvm %s -o - | grep nounwind | count 4 +int c(void) __attribute__((const)); +int p(void) __attribute__((pure)); +int t(void); + +int f(void) { + return c() + p() + t(); +} From baldrick at free.fr Mon May 4 11:50:30 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 04 May 2009 16:50:30 -0000 Subject: [llvm-commits] [llvm] r70876 - in /llvm/trunk: lib/Analysis/CaptureTracking.cpp test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll Message-ID: <200905041650.n44GoXRA002178@zion.cs.uiuc.edu> Author: baldrick Date: Mon May 4 11:50:29 2009 New Revision: 70876 URL: http://llvm.org/viewvc/llvm-project?rev=70876&view=rev Log: Teach capture tracking that readonly functions can only capture their arguments by returning them or throwing an exception or not based on the argument value. Patch essentially by Frits van Bommel. Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=70876&r1=70875&r2=70876&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original) +++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Mon May 4 11:50:29 2009 @@ -49,11 +49,7 @@ switch (I->getOpcode()) { case Instruction::Call: case Instruction::Invoke: { - CallSite CS = CallSite::get(I); - // Not captured if the callee is readonly and doesn't return a copy - // through its return value. - if (CS.onlyReadsMemory() && I->getType() == Type::VoidTy) - break; + CallSite CS(I); // Not captured if only passed via 'nocapture' arguments. Note that // calling a function pointer does not in itself cause the pointer to @@ -62,46 +58,69 @@ // that loading a value from a pointer does not cause the pointer to be // captured, even though the loaded value might be the pointer itself // (think of self-referential objects). + bool MayBeCaptured = false; CallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end(); for (CallSite::arg_iterator A = B; A != E; ++A) - if (A->get() == V && !CS.paramHasAttr(A - B + 1, Attribute::NoCapture)) - // The parameter is not marked 'nocapture' - captured. - return true; - // Only passed via 'nocapture' arguments, or is the called function - not - // captured. + if (A->get() == V && !CS.paramHasAttr(A-B+1, Attribute::NoCapture)) { + // The parameter is not marked 'nocapture' - handled by generic code + // below. + MayBeCaptured = true; + break; + } + if (!MayBeCaptured) + // Only passed via 'nocapture' arguments, or is the called function - + // not captured. + continue; + if (!CS.doesNotThrow()) + // Even a readonly function can leak bits by throwing an exception or + // not depending on the input value. + return true; + // Fall through to the generic code. break; } case Instruction::Free: // Freeing a pointer does not cause it to be captured. - break; + continue; case Instruction::Load: // Loading from a pointer does not cause it to be captured. - break; + continue; case Instruction::Ret: if (ReturnCaptures) return true; - break; + continue; case Instruction::Store: if (V == I->getOperand(0)) // Stored the pointer - it may be captured. return true; // Storing to the pointee does not cause the pointer to be captured. - break; - case Instruction::BitCast: - case Instruction::GetElementPtr: - case Instruction::PHI: - case Instruction::Select: - // The original value is not captured via this if the new value isn't. - for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end(); - UI != UE; ++UI) { - Use *U = &UI.getUse(); - if (Visited.insert(U)) - Worklist.push_back(U); - } - break; - default: - // Something else - be conservative and say it is captured. + continue; + } + + // If it may write to memory and isn't one of the special cases above, + // be conservative and assume the pointer is captured. + if (I->mayWriteToMemory()) return true; + + // If the instruction doesn't write memory, it can only capture by + // having its own value depend on the input value. + const Type* Ty = I->getType(); + if (Ty == Type::VoidTy) + // The value of an instruction can't be a copy if it can't contain any + // information. + continue; + if (!isa(Ty)) + // At the moment, we don't track non-pointer values, so be conservative + // and assume the pointer is captured. + // FIXME: Track these too. This would need to be done very carefully as + // it is easy to leak bits via control flow if integer values are allowed. + return true; + + // The original value is not captured via this if the new value isn't. + for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end(); + UI != UE; ++UI) { + Use *U = &UI.getUse(); + if (Visited.insert(U)) + Worklist.push_back(U); } } Modified: llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll?rev=70876&r1=70875&r2=70876&view=diff ============================================================================== --- llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll (original) +++ llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll Mon May 4 11:50:29 2009 @@ -39,6 +39,16 @@ ret i1 %val } +declare void @throw_if_bit_set(i8*, i8) readonly +define i1 @c6(i8* %q, i8 %bit) { + invoke void @throw_if_bit_set(i8* %q, i8 %bit) + to label %ret0 unwind label %ret1 +ret0: + ret i1 0 +ret1: + ret i1 1 +} + define i32 @nc1(i32* %q, i32* %p, i1 %b) { e: br label %l @@ -63,14 +73,20 @@ ret void } -declare void @external(i8*) readonly +declare void @external(i8*) readonly nounwind define void @nc4(i8* %p) { call void @external(i8* %p) ret void } -define void @nc5(void (i8*)* %f, i8* %p) { - call void %f(i8* %p) readonly - call void %f(i8* nocapture %p) +define void @nc5(void (i8*)* %p, i8* %r) { + call void %p(i8* %r) + call void %p(i8* nocapture %r) + ret void +} + +declare i8* @external_identity(i8*) readonly nounwind +define void @nc6(i8* %p) { + call i8* @external_identity(i8* %p) ret void } From gohman at apple.com Mon May 4 12:09:52 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 04 May 2009 17:09:52 -0000 Subject: [llvm-commits] [llvm] r70879 - /llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200905041709.n44H9qM5002807@zion.cs.uiuc.edu> Author: djg Date: Mon May 4 12:09:51 2009 New Revision: 70879 URL: http://llvm.org/viewvc/llvm-project?rev=70879&view=rev Log: Quotes are used for including llvm headers, rather than angles. Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=70879&r1=70878&r2=70879&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Mon May 4 12:09:51 2009 @@ -2102,7 +2102,7 @@ OS << "// Include standard, target-independent definitions and methods used\n" << "// by the instruction selector.\n"; - OS << "#include \n\n"; + OS << "#include \"llvm/CodeGen/DAGISelHeader.h\"\n\n"; EmitNodeTransforms(OS); EmitPredicateFunctions(OS); From gohman at apple.com Mon May 4 12:11:06 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 04 May 2009 17:11:06 -0000 Subject: [llvm-commits] [llvm] r70880 - /llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp Message-ID: <200905041711.n44HB632002871@zion.cs.uiuc.edu> Author: djg Date: Mon May 4 12:11:06 2009 New Revision: 70880 URL: http://llvm.org/viewvc/llvm-project?rev=70880&view=rev Log: Trim unnecessary #includes. Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp?rev=70880&r1=70879&r2=70880&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp Mon May 4 12:11:06 2009 @@ -28,8 +28,6 @@ #include "llvm/Target/TargetLowering.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" -#include -#include using namespace llvm; /// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine From gohman at apple.com Mon May 4 12:12:00 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 04 May 2009 17:12:00 -0000 Subject: [llvm-commits] [llvm] r70881 - /llvm/trunk/lib/Target/MSP430/ Message-ID: <200905041712.n44HC08A002912@zion.cs.uiuc.edu> Author: djg Date: Mon May 4 12:12:00 2009 New Revision: 70881 URL: http://llvm.org/viewvc/llvm-project?rev=70881&view=rev Log: Add an svn:ignore property. Modified: llvm/trunk/lib/Target/MSP430/ (props changed) Propchange: llvm/trunk/lib/Target/MSP430/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Mon May 4 12:12:00 2009 @@ -0,0 +1,4 @@ +Debug +Release +Release-Asserts +*.inc From gohman at apple.com Mon May 4 12:25:21 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 04 May 2009 17:25:21 -0000 Subject: [llvm-commits] [llvm] r70882 - /llvm/trunk/lib/VMCore/Value.cpp Message-ID: <200905041725.n44HPLoW003469@zion.cs.uiuc.edu> Author: djg Date: Mon May 4 12:25:21 2009 New Revision: 70882 URL: http://llvm.org/viewvc/llvm-project?rev=70882&view=rev Log: Use true instead of 1 for a boolean value. And fix a copy+pasto in a comment. Modified: llvm/trunk/lib/VMCore/Value.cpp Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=70882&r1=70881&r2=70882&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Mon May 4 12:25:21 2009 @@ -406,8 +406,8 @@ typedef DenseMap ValueHandlesTy; static ManagedStatic ValueHandles; -/// AddToUseList - Add this ValueHandle to the use list for VP, where List is -/// known to point into the existing use list. +/// AddToExistingUseList - Add this ValueHandle to the use list for VP, where +/// List is known to point into the existing use list. void ValueHandleBase::AddToExistingUseList(ValueHandleBase **List) { assert(List && "Handle list is null?"); @@ -443,7 +443,7 @@ ValueHandleBase *&Entry = Handles[VP]; assert(Entry == 0 && "Value really did already have handles?"); AddToExistingUseList(&Entry); - VP->HasValueHandle = 1; + VP->HasValueHandle = true; // If reallocation didn't happen or if this was the first insertion, don't // walk the table. From eli.friedman at gmail.com Mon May 4 12:35:20 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 4 May 2009 10:35:20 -0700 Subject: [llvm-commits] [llvm] r70790 - /llvm/trunk/docs/LangRef.html In-Reply-To: References: <200905031906.n43J60Bg012814@zion.cs.uiuc.edu> <200905032206.29498.baldrick@free.fr> <470D68BA-BCC1-4F82-9D78-426358B58E2E@nondot.org> <49FEAC01.4030708@gmail.com> Message-ID: On Mon, May 4, 2009 at 9:38 AM, Chris Lattner wrote: > > On May 4, 2009, at 1:49 AM, T?r?k Edwin wrote: > >> Also what happens with C++'s const member functions? >> If there are mutable class members they aren't technically readonly, >> since they have the side-effect of modifying the object. >> However most people use this as a 'logical' const, i.e. the object may >> be modified, but the new object is equivalent to the old one. >> Can this be modeled via an LLVM attribute? > > No, this cannot be modeled, because const is allowed to be cast away. Well, not quite... per [dcl.type.cv], "Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior." That's a pretty narrow exception, though, and C++ programs generally aren't written to take advantage of it. -Eli From isanbard at gmail.com Mon May 4 13:00:28 2009 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 04 May 2009 18:00:28 -0000 Subject: [llvm-commits] [llvm] r70886 - /llvm/trunk/test/FrontendC/2009-05-04-EnumInreg.c Message-ID: <200905041800.n44I0Se2005358@zion.cs.uiuc.edu> Author: void Date: Mon May 4 13:00:27 2009 New Revision: 70886 URL: http://llvm.org/viewvc/llvm-project?rev=70886&view=rev Log: Use %llvmgcc instead of llvm-gcc. Modified: llvm/trunk/test/FrontendC/2009-05-04-EnumInreg.c Modified: llvm/trunk/test/FrontendC/2009-05-04-EnumInreg.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC/2009-05-04-EnumInreg.c?rev=70886&r1=70885&r2=70886&view=diff ============================================================================== --- llvm/trunk/test/FrontendC/2009-05-04-EnumInreg.c (original) +++ llvm/trunk/test/FrontendC/2009-05-04-EnumInreg.c Mon May 4 13:00:27 2009 @@ -1,4 +1,4 @@ -// RUN: llvm-gcc -S -m32 -mregparm=3 %s -emit-llvm -o - | grep {inreg %action} +// RUN: %llvmgcc -S -m32 -mregparm=3 %s -emit-llvm -o - | grep {inreg %action} // XTARGET: x86 // PR3967 From isanbard at gmail.com Mon May 4 13:06:56 2009 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 4 May 2009 11:06:56 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r70801 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp In-Reply-To: <200905040905.18847.baldrick@free.fr> References: <200905032136.n43LaNFN018015@zion.cs.uiuc.edu> <200905040905.18847.baldrick@free.fr> Message-ID: <16e5fdf90905041106n6ed30aaeg89870c25de1ea088@mail.gmail.com> On Mon, May 4, 2009 at 12:05 AM, Duncan Sands wrote: > Hi Bill, > >> Don'e create debug info for ObjC metadata. > > how about setting DECL_ARTIFICIAL for such globals, and then teach > the backend not to output debug info for globals with DECL_ARTIFICIAL > set? > > /* Used to indicate that this DECL represents a compiler-generated entity. ?*/ > #define DECL_ARTIFICIAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.artificial_flag) > Hi Duncan, I'll run this past our ObjC expert here. He wrote most of the stuff. Thanks! -bw From mrs at apple.com Mon May 4 13:34:35 2009 From: mrs at apple.com (Mike Stump) Date: Mon, 04 May 2009 18:34:35 -0000 Subject: [llvm-commits] [llvm] r70891 - /llvm/trunk/ Message-ID: <200905041834.n44IYZ3s006759@zion.cs.uiuc.edu> Author: mrs Date: Mon May 4 13:34:35 2009 New Revision: 70891 URL: http://llvm.org/viewvc/llvm-project?rev=70891&view=rev Log: Update. Removed: llvm/trunk/ From isanbard at gmail.com Mon May 4 13:36:02 2009 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 4 May 2009 11:36:02 -0700 Subject: [llvm-commits] [llvm] r70891 - /llvm/trunk/ In-Reply-To: <200905041834.n44IYZ3s006759@zion.cs.uiuc.edu> References: <200905041834.n44IYZ3s006759@zion.cs.uiuc.edu> Message-ID: <16e5fdf90905041136v1c45bc57hbae99c9acb44e7ea@mail.gmail.com> Huh?! -bw On Mon, May 4, 2009 at 11:34 AM, Mike Stump wrote: > Author: mrs > Date: Mon May ?4 13:34:35 2009 > New Revision: 70891 > > URL: http://llvm.org/viewvc/llvm-project?rev=70891&view=rev > Log: > Update. > > Removed: > ? ?llvm/trunk/ > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From anton at korobeynikov.info Mon May 4 13:34:15 2009 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Mon, 04 May 2009 22:34:15 +0400 Subject: [llvm-commits] [llvm] r70891 - /llvm/trunk/ In-Reply-To: <200905041834.n44IYZ3s006759@zion.cs.uiuc.edu> References: <200905041834.n44IYZ3s006759@zion.cs.uiuc.edu> Message-ID: <1241462055.18321.30.camel@aslstation> Hello, Mike > Author: mrs > Date: Mon May 4 13:34:35 2009 > New Revision: 70891 > > URL: http://llvm.org/viewvc/llvm-project?rev=70891&view=rev > Log: > Update. > > Removed: > llvm/trunk/ Did you really want to delete trunk??? -- With best regards, Anton Korobeynikov. Faculty of Mathematics & Mechanics, Saint Petersburg State University. From isanbard at gmail.com Mon May 4 13:39:51 2009 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 4 May 2009 11:39:51 -0700 Subject: [llvm-commits] [llvm] r70891 - /llvm/trunk/ In-Reply-To: <1241462055.18321.30.camel@aslstation> References: <200905041834.n44IYZ3s006759@zion.cs.uiuc.edu> <1241462055.18321.30.camel@aslstation> Message-ID: <16e5fdf90905041139v1bc8507ep355e550e1490e705@mail.gmail.com> On Mon, May 4, 2009 at 11:34 AM, Anton Korobeynikov wrote: > Hello, Mike > >> Author: mrs >> Date: Mon May ?4 13:34:35 2009 >> New Revision: 70891 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=70891&view=rev >> Log: >> Update. >> >> Removed: >> ? ? llvm/trunk/ > Did you really want to delete trunk??? > No. He's looking into it... -bw From mrs at apple.com Mon May 4 13:40:41 2009 From: mrs at apple.com (Mike Stump) Date: Mon, 04 May 2009 18:40:41 -0000 Subject: [llvm-commits] [llvm] r70892 - /llvm/trunk/ Message-ID: <200905041840.n44Ief6K006984@zion.cs.uiuc.edu> Author: mrs Date: Mon May 4 13:40:41 2009 New Revision: 70892 URL: http://llvm.org/viewvc/llvm-project?rev=70892&view=rev Log: Restore minor deletion. Added: llvm/trunk/ - copied from r70890, llvm/trunk/ From stoklund at 2pi.dk Mon May 4 13:43:50 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 4 May 2009 20:43:50 +0200 Subject: [llvm-commits] [llvm] r70892 - /llvm/trunk/ In-Reply-To: <200905041840.n44Ief6K006984@zion.cs.uiuc.edu> References: <200905041840.n44Ief6K006984@zion.cs.uiuc.edu> Message-ID: On 04/05/2009, at 20.40, Mike Stump wrote: > Author: mrs > Date: Mon May 4 13:40:41 2009 > New Revision: 70892 > > URL: http://llvm.org/viewvc/llvm-project?rev=70892&view=rev > Log: > Restore minor deletion. > > Added: > llvm/trunk/ > - copied from r70890, llvm/trunk/ You owe me a new keyboard! From collinwinter at google.com Mon May 4 13:53:42 2009 From: collinwinter at google.com (Collin Winter) Date: Mon, 4 May 2009 11:53:42 -0700 Subject: [llvm-commits] Fix the CPP backend's handling of conditional branches Message-ID: <3c8293b60905041153k31a7cc43uca421d75feb5046f@mail.gmail.com> Hi all, At head, llc -march=cpp emits broken calls to BranchInst::Create for conditional branches (llc succeeds, but g++ fails when compiling the emitted C++ code). The attached patch fixes this and adds a test. Thanks, Collin Winter -------------- next part -------------- A non-text attachment was scrubbed... Name: cpp-condbranch.patch Type: application/octet-stream Size: 1840 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090504/07fc1274/attachment.obj From asl at math.spbu.ru Mon May 4 14:10:39 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 04 May 2009 19:10:39 -0000 Subject: [llvm-commits] [llvm] r70898 - in /llvm/trunk: lib/Target/CppBackend/CPPBackend.cpp test/CodeGen/CPP/2009-05-04-CondBr.ll Message-ID: <200905041910.n44JAdQ1008360@zion.cs.uiuc.edu> Author: asl Date: Mon May 4 14:10:38 2009 New Revision: 70898 URL: http://llvm.org/viewvc/llvm-project?rev=70898&view=rev Log: Fix code emission for conditional branches. Patch by Collin Winter! Added: llvm/trunk/test/CodeGen/CPP/2009-05-04-CondBr.ll Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=70898&r1=70897&r2=70898&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Mon May 4 14:10:38 2009 @@ -1092,9 +1092,9 @@ const BranchInst* br = cast(I); Out << "BranchInst::Create(" ; if (br->getNumOperands() == 3 ) { - Out << opNames[0] << ", " + Out << opNames[2] << ", " << opNames[1] << ", " - << opNames[2] << ", "; + << opNames[0] << ", "; } else if (br->getNumOperands() == 1) { Out << opNames[0] << ", "; Added: llvm/trunk/test/CodeGen/CPP/2009-05-04-CondBr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CPP/2009-05-04-CondBr.ll?rev=70898&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CPP/2009-05-04-CondBr.ll (added) +++ llvm/trunk/test/CodeGen/CPP/2009-05-04-CondBr.ll Mon May 4 14:10:38 2009 @@ -0,0 +1,28 @@ +; RUN: llvm-as < %s | llc -march=cpp -cppgen=program -f -o %t +; RUN: grep "BranchInst::Create(label_if_then, label_if_end, int1_cmp, label_entry);" %t + +define i32 @some_func(i32 %a) nounwind { +entry: + %retval = alloca i32 ; [#uses=2] + %a.addr = alloca i32 ; [#uses=8] + store i32 %a, i32* %a.addr + %tmp = load i32* %a.addr ; [#uses=1] + %inc = add i32 %tmp, 1 ; [#uses=1] + store i32 %inc, i32* %a.addr + %tmp1 = load i32* %a.addr ; [#uses=1] + %cmp = icmp slt i32 %tmp1, 3 ; [#uses=1] + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + store i32 7, i32* %a.addr + br label %if.end + +if.end: ; preds = %if.then, %entry + %tmp2 = load i32* %a.addr ; [#uses=1] + %inc3 = add i32 %tmp2, 1 ; [#uses=1] + store i32 %inc3, i32* %a.addr + %tmp4 = load i32* %a.addr ; [#uses=1] + store i32 %tmp4, i32* %retval + %0 = load i32* %retval ; [#uses=1] + ret i32 %0 +} From anton at korobeynikov.info Mon May 4 14:08:59 2009 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Mon, 04 May 2009 23:08:59 +0400 Subject: [llvm-commits] Fix the CPP backend's handling of conditional branches In-Reply-To: <3c8293b60905041153k31a7cc43uca421d75feb5046f@mail.gmail.com> References: <3c8293b60905041153k31a7cc43uca421d75feb5046f@mail.gmail.com> Message-ID: <1241464139.18321.31.camel@aslstation> Hello, Collin > At head, llc -march=cpp emits broken calls to BranchInst::Create for > conditional branches (llc succeeds, but g++ fails when compiling the > emitted C++ code). The attached patch fixes this and adds a test. Applied, thanks! -- With best regards, Anton Korobeynikov. Faculty of Mathematics & Mechanics, Saint Petersburg State University. From akyrtzi at gmail.com Mon May 4 14:23:47 2009 From: akyrtzi at gmail.com (Argiris Kirtzidis) Date: Mon, 04 May 2009 19:23:47 -0000 Subject: [llvm-commits] [llvm] r70900 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Message-ID: <200905041923.n44JNl98008905@zion.cs.uiuc.edu> Author: akirtzidis Date: Mon May 4 14:23:45 2009 New Revision: 70900 URL: http://llvm.org/viewvc/llvm-project?rev=70900&view=rev Log: Restore a comment. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=70900&r1=70899&r2=70900&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Mon May 4 14:23:45 2009 @@ -3262,6 +3262,8 @@ // Assumes in correct section after the entry point. EmitLabel("func_begin", ++SubprogramCount); + // Emit label for the implicitly defined dbg.stoppoint at the start of + // the function. DebugLoc FDL = MF->getDefaultDebugLoc(); if (!FDL.isUnknown()) { DebugLocTuple DLT = MF->getDebugLocTuple(FDL); From gohman at apple.com Mon May 4 14:50:34 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 04 May 2009 19:50:34 -0000 Subject: [llvm-commits] [llvm] r70902 - in /llvm/trunk: lib/Target/X86/X86FastISel.cpp test/CodeGen/X86/fast-isel-tailcall.ll Message-ID: <200905041950.n44JoYld010013@zion.cs.uiuc.edu> Author: djg Date: Mon May 4 14:50:33 2009 New Revision: 70902 URL: http://llvm.org/viewvc/llvm-project?rev=70902&view=rev Log: X86FastISel doesn't support the -tailcallopt ABI. Added: llvm/trunk/test/CodeGen/X86/fast-isel-tailcall.ll Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=70902&r1=70901&r2=70902&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Mon May 4 14:50:33 2009 @@ -30,6 +30,7 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/GetElementPtrTypeIterator.h" +#include "llvm/Target/TargetOptions.h" using namespace llvm; namespace { @@ -1115,6 +1116,11 @@ CC != CallingConv::X86_FastCall) return false; + // On X86, -tailcallopt changes the fastcc ABI. FastISel doesn't + // handle this for now. + if (CC == CallingConv::Fast && PerformTailCallOpt) + return false; + // Let SDISel handle vararg functions. const PointerType *PT = cast(CS.getCalledValue()->getType()); const FunctionType *FTy = cast(PT->getElementType()); Added: llvm/trunk/test/CodeGen/X86/fast-isel-tailcall.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-tailcall.ll?rev=70902&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/fast-isel-tailcall.ll (added) +++ llvm/trunk/test/CodeGen/X86/fast-isel-tailcall.ll Mon May 4 14:50:33 2009 @@ -0,0 +1,13 @@ +; RUN: llvm-as < %s | llc -fast-isel -tailcallopt -march=x86 | not grep add +; PR4154 + +; On x86, -tailcallopt changes the ABI so the caller shouldn't readjust +; the stack pointer after the call in this code. + +define i32 @stub(i8* %t0) nounwind { +entry: + %t1 = load i32* inttoptr (i32 139708680 to i32*) ; [#uses=1] + %t2 = bitcast i8* %t0 to i32 (i32)* ; [#uses=1] + %t3 = call fastcc i32 %t2(i32 %t1) ; [#uses=1] + ret i32 %t3 +} From gohman at apple.com Mon May 4 17:02:23 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 04 May 2009 22:02:23 -0000 Subject: [llvm-commits] [llvm] r70919 - in /llvm/trunk/lib: Analysis/ScalarEvolution.cpp Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200905042202.n44M2NXr014656@zion.cs.uiuc.edu> Author: djg Date: Mon May 4 17:02:23 2009 New Revision: 70919 URL: http://llvm.org/viewvc/llvm-project?rev=70919&view=rev Log: Constify a bunch of SCEV-using code. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=70919&r1=70918&r2=70919&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon May 4 17:02:23 2009 @@ -650,25 +650,25 @@ "This is not a conversion to a SCEVable type!"); Ty = getEffectiveSCEVType(Ty); - if (SCEVConstant *SC = dyn_cast(Op)) + if (const SCEVConstant *SC = dyn_cast(Op)) return getUnknown( ConstantExpr::getTrunc(SC->getValue(), Ty)); // trunc(trunc(x)) --> trunc(x) - if (SCEVTruncateExpr *ST = dyn_cast(Op)) + if (const SCEVTruncateExpr *ST = dyn_cast(Op)) return getTruncateExpr(ST->getOperand(), Ty); // trunc(sext(x)) --> sext(x) if widening or trunc(x) if narrowing - if (SCEVSignExtendExpr *SS = dyn_cast(Op)) + if (const SCEVSignExtendExpr *SS = dyn_cast(Op)) return getTruncateOrSignExtend(SS->getOperand(), Ty); // trunc(zext(x)) --> zext(x) if widening or trunc(x) if narrowing - if (SCEVZeroExtendExpr *SZ = dyn_cast(Op)) + if (const SCEVZeroExtendExpr *SZ = dyn_cast(Op)) return getTruncateOrZeroExtend(SZ->getOperand(), Ty); // If the input value is a chrec scev made out of constants, truncate // all of the constants. - if (SCEVAddRecExpr *AddRec = dyn_cast(Op)) { + if (const SCEVAddRecExpr *AddRec = dyn_cast(Op)) { std::vector Operands; for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) // FIXME: This should allow truncation of other expression types! @@ -693,7 +693,7 @@ "This is not a conversion to a SCEVable type!"); Ty = getEffectiveSCEVType(Ty); - if (SCEVConstant *SC = dyn_cast(Op)) { + if (const SCEVConstant *SC = dyn_cast(Op)) { const Type *IntTy = getEffectiveSCEVType(Ty); Constant *C = ConstantExpr::getZExt(SC->getValue(), IntTy); if (IntTy != Ty) C = ConstantExpr::getIntToPtr(C, Ty); @@ -701,14 +701,14 @@ } // zext(zext(x)) --> zext(x) - if (SCEVZeroExtendExpr *SZ = dyn_cast(Op)) + if (const SCEVZeroExtendExpr *SZ = dyn_cast(Op)) return getZeroExtendExpr(SZ->getOperand(), Ty); // If the input value is a chrec scev, and we can prove that the value // did not overflow the old, smaller, value, we can zero extend all of the // operands (often constants). This allows analysis of something like // this: for (unsigned char X = 0; X < 100; ++X) { int Y = X; } - if (SCEVAddRecExpr *AR = dyn_cast(Op)) + if (const SCEVAddRecExpr *AR = dyn_cast(Op)) if (AR->isAffine()) { // Check whether the backedge-taken count is SCEVCouldNotCompute. // Note that this serves two purposes: It filters out loops that are @@ -778,7 +778,7 @@ "This is not a conversion to a SCEVable type!"); Ty = getEffectiveSCEVType(Ty); - if (SCEVConstant *SC = dyn_cast(Op)) { + if (const SCEVConstant *SC = dyn_cast(Op)) { const Type *IntTy = getEffectiveSCEVType(Ty); Constant *C = ConstantExpr::getSExt(SC->getValue(), IntTy); if (IntTy != Ty) C = ConstantExpr::getIntToPtr(C, Ty); @@ -786,14 +786,14 @@ } // sext(sext(x)) --> sext(x) - if (SCEVSignExtendExpr *SS = dyn_cast(Op)) + if (const SCEVSignExtendExpr *SS = dyn_cast(Op)) return getSignExtendExpr(SS->getOperand(), Ty); // If the input value is a chrec scev, and we can prove that the value // did not overflow the old, smaller, value, we can sign extend all of the // operands (often constants). This allows analysis of something like // this: for (signed char X = 0; X < 100; ++X) { int Y = X; } - if (SCEVAddRecExpr *AR = dyn_cast(Op)) + if (const SCEVAddRecExpr *AR = dyn_cast(Op)) if (AR->isAffine()) { // Check whether the backedge-taken count is SCEVCouldNotCompute. // Note that this serves two purposes: It filters out loops that are @@ -850,10 +850,10 @@ // If there are any constants, fold them together. unsigned Idx = 0; - if (SCEVConstant *LHSC = dyn_cast(Ops[0])) { + if (const SCEVConstant *LHSC = dyn_cast(Ops[0])) { ++Idx; assert(Idx < Ops.size()); - while (SCEVConstant *RHSC = dyn_cast(Ops[Idx])) { + while (const SCEVConstant *RHSC = dyn_cast(Ops[Idx])) { // We found two constants, fold them together! ConstantInt *Fold = ConstantInt::get(LHSC->getValue()->getValue() + RHSC->getValue()->getValue()); @@ -896,7 +896,7 @@ // If there are add operands they would be next. if (Idx < Ops.size()) { bool DeletedAdd = false; - while (SCEVAddExpr *Add = dyn_cast(Ops[Idx])) { + while (const SCEVAddExpr *Add = dyn_cast(Ops[Idx])) { // If we have an add, expand the add operands onto the end of the operands // list. Ops.insert(Ops.end(), Add->op_begin(), Add->op_end()); @@ -1075,11 +1075,11 @@ // If there are any constants, fold them together. unsigned Idx = 0; - if (SCEVConstant *LHSC = dyn_cast(Ops[0])) { + if (const SCEVConstant *LHSC = dyn_cast(Ops[0])) { // C1*(C2+V) -> C1*C2 + C1*V if (Ops.size() == 2) - if (SCEVAddExpr *Add = dyn_cast(Ops[1])) + if (const SCEVAddExpr *Add = dyn_cast(Ops[1])) if (Add->getNumOperands() == 2 && isa(Add->getOperand(0))) return getAddExpr(getMulExpr(LHSC, Add->getOperand(0)), @@ -1087,7 +1087,7 @@ ++Idx; - while (SCEVConstant *RHSC = dyn_cast(Ops[Idx])) { + while (const SCEVConstant *RHSC = dyn_cast(Ops[Idx])) { // We found two constants, fold them together! ConstantInt *Fold = ConstantInt::get(LHSC->getValue()->getValue() * RHSC->getValue()->getValue()); @@ -1117,7 +1117,7 @@ // If there are mul operands inline them all into this expression. if (Idx < Ops.size()) { bool DeletedMul = false; - while (SCEVMulExpr *Mul = dyn_cast(Ops[Idx])) { + while (const SCEVMulExpr *Mul = dyn_cast(Ops[Idx])) { // If we have an mul, expand the mul operands onto the end of the operands // list. Ops.insert(Ops.end(), Mul->op_begin(), Mul->op_end()); @@ -1225,11 +1225,11 @@ } SCEVHandle ScalarEvolution::getUDivExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) { - if (SCEVConstant *RHSC = dyn_cast(RHS)) { + if (const SCEVConstant *RHSC = dyn_cast(RHS)) { if (RHSC->getValue()->equalsInt(1)) return LHS; // X udiv 1 --> x - if (SCEVConstant *LHSC = dyn_cast(LHS)) { + if (const SCEVConstant *LHSC = dyn_cast(LHS)) { Constant *LHSCV = LHSC->getValue(); Constant *RHSCV = RHSC->getValue(); return getUnknown(ConstantExpr::getUDiv(LHSCV, RHSCV)); @@ -1250,7 +1250,7 @@ const SCEVHandle &Step, const Loop *L) { std::vector Operands; Operands.push_back(Start); - if (SCEVAddRecExpr *StepChrec = dyn_cast(Step)) + if (const SCEVAddRecExpr *StepChrec = dyn_cast(Step)) if (StepChrec->getLoop() == L) { Operands.insert(Operands.end(), StepChrec->op_begin(), StepChrec->op_end()); @@ -1273,7 +1273,7 @@ } // Canonicalize nested AddRecs in by nesting them in order of loop depth. - if (SCEVAddRecExpr *NestedAR = dyn_cast(Operands[0])) { + if (const SCEVAddRecExpr *NestedAR = dyn_cast(Operands[0])) { const Loop* NestedLoop = NestedAR->getLoop(); if (L->getLoopDepth() < NestedLoop->getLoopDepth()) { std::vector NestedOperands(NestedAR->op_begin(), @@ -1309,10 +1309,10 @@ // If there are any constants, fold them together. unsigned Idx = 0; - if (SCEVConstant *LHSC = dyn_cast(Ops[0])) { + if (const SCEVConstant *LHSC = dyn_cast(Ops[0])) { ++Idx; assert(Idx < Ops.size()); - while (SCEVConstant *RHSC = dyn_cast(Ops[Idx])) { + while (const SCEVConstant *RHSC = dyn_cast(Ops[Idx])) { // We found two constants, fold them together! ConstantInt *Fold = ConstantInt::get( APIntOps::smax(LHSC->getValue()->getValue(), @@ -1340,7 +1340,7 @@ // onto our operand list, and recurse to simplify. if (Idx < Ops.size()) { bool DeletedSMax = false; - while (SCEVSMaxExpr *SMax = dyn_cast(Ops[Idx])) { + while (const SCEVSMaxExpr *SMax = dyn_cast(Ops[Idx])) { Ops.insert(Ops.end(), SMax->op_begin(), SMax->op_end()); Ops.erase(Ops.begin()+Idx); DeletedSMax = true; @@ -1389,10 +1389,10 @@ // If there are any constants, fold them together. unsigned Idx = 0; - if (SCEVConstant *LHSC = dyn_cast(Ops[0])) { + if (const SCEVConstant *LHSC = dyn_cast(Ops[0])) { ++Idx; assert(Idx < Ops.size()); - while (SCEVConstant *RHSC = dyn_cast(Ops[Idx])) { + while (const SCEVConstant *RHSC = dyn_cast(Ops[Idx])) { // We found two constants, fold them together! ConstantInt *Fold = ConstantInt::get( APIntOps::umax(LHSC->getValue()->getValue(), @@ -1420,7 +1420,7 @@ // onto our operand list, and recurse to simplify. if (Idx < Ops.size()) { bool DeletedUMax = false; - while (SCEVUMaxExpr *UMax = dyn_cast(Ops[Idx])) { + while (const SCEVUMaxExpr *UMax = dyn_cast(Ops[Idx])) { Ops.insert(Ops.end(), UMax->op_begin(), UMax->op_end()); Ops.erase(Ops.begin()+Idx); DeletedUMax = true; @@ -1580,7 +1580,7 @@ /// getNegativeSCEV - Return a SCEV corresponding to -V = -1*V /// SCEVHandle ScalarEvolution::getNegativeSCEV(const SCEVHandle &V) { - if (SCEVConstant *VC = dyn_cast(V)) + if (const SCEVConstant *VC = dyn_cast(V)) return getUnknown(ConstantExpr::getNeg(VC->getValue())); const Type *Ty = V->getType(); @@ -1590,7 +1590,7 @@ /// getNotSCEV - Return a SCEV corresponding to ~V = -1-V SCEVHandle ScalarEvolution::getNotSCEV(const SCEVHandle &V) { - if (SCEVConstant *VC = dyn_cast(V)) + if (const SCEVConstant *VC = dyn_cast(V)) return getUnknown(ConstantExpr::getNot(VC->getValue())); const Type *Ty = V->getType(); @@ -1690,7 +1690,7 @@ // If the value coming around the backedge is an add with the symbolic // value we just inserted, then we found a simple induction variable! - if (SCEVAddExpr *Add = dyn_cast(BEValue)) { + if (const SCEVAddExpr *Add = dyn_cast(BEValue)) { // If there is a single occurrence of the symbolic value, replace it // with a recurrence. unsigned FoundIndex = Add->getNumOperands(); @@ -1726,7 +1726,8 @@ return PHISCEV; } } - } else if (SCEVAddRecExpr *AddRec = dyn_cast(BEValue)) { + } else if (const SCEVAddRecExpr *AddRec = + dyn_cast(BEValue)) { // Otherwise, this could be a loop like this: // i = 0; for (j = 1; ..; ++j) { .... i = j; } // In this case, j = {1,+,1} and BEValue is j. @@ -1765,26 +1766,26 @@ /// the minimum number of times S is divisible by 2. For example, given {4,+,8} /// it returns 2. If S is guaranteed to be 0, it returns the bitwidth of S. static uint32_t GetMinTrailingZeros(SCEVHandle S, const ScalarEvolution &SE) { - if (SCEVConstant *C = dyn_cast(S)) + if (const SCEVConstant *C = dyn_cast(S)) return C->getValue()->getValue().countTrailingZeros(); - if (SCEVTruncateExpr *T = dyn_cast(S)) + if (const SCEVTruncateExpr *T = dyn_cast(S)) return std::min(GetMinTrailingZeros(T->getOperand(), SE), (uint32_t)SE.getTypeSizeInBits(T->getType())); - if (SCEVZeroExtendExpr *E = dyn_cast(S)) { + if (const SCEVZeroExtendExpr *E = dyn_cast(S)) { uint32_t OpRes = GetMinTrailingZeros(E->getOperand(), SE); return OpRes == SE.getTypeSizeInBits(E->getOperand()->getType()) ? SE.getTypeSizeInBits(E->getOperand()->getType()) : OpRes; } - if (SCEVSignExtendExpr *E = dyn_cast(S)) { + if (const SCEVSignExtendExpr *E = dyn_cast(S)) { uint32_t OpRes = GetMinTrailingZeros(E->getOperand(), SE); return OpRes == SE.getTypeSizeInBits(E->getOperand()->getType()) ? SE.getTypeSizeInBits(E->getOperand()->getType()) : OpRes; } - if (SCEVAddExpr *A = dyn_cast(S)) { + if (const SCEVAddExpr *A = dyn_cast(S)) { // The result is the min of all operands results. uint32_t MinOpRes = GetMinTrailingZeros(A->getOperand(0), SE); for (unsigned i = 1, e = A->getNumOperands(); MinOpRes && i != e; ++i) @@ -1792,7 +1793,7 @@ return MinOpRes; } - if (SCEVMulExpr *M = dyn_cast(S)) { + if (const SCEVMulExpr *M = dyn_cast(S)) { // The result is the sum of all operands results. uint32_t SumOpRes = GetMinTrailingZeros(M->getOperand(0), SE); uint32_t BitWidth = SE.getTypeSizeInBits(M->getType()); @@ -1803,7 +1804,7 @@ return SumOpRes; } - if (SCEVAddRecExpr *A = dyn_cast(S)) { + if (const SCEVAddRecExpr *A = dyn_cast(S)) { // The result is the min of all operands results. uint32_t MinOpRes = GetMinTrailingZeros(A->getOperand(0), SE); for (unsigned i = 1, e = A->getNumOperands(); MinOpRes && i != e; ++i) @@ -1811,7 +1812,7 @@ return MinOpRes; } - if (SCEVSMaxExpr *M = dyn_cast(S)) { + if (const SCEVSMaxExpr *M = dyn_cast(S)) { // The result is the min of all operands results. uint32_t MinOpRes = GetMinTrailingZeros(M->getOperand(0), SE); for (unsigned i = 1, e = M->getNumOperands(); MinOpRes && i != e; ++i) @@ -1819,7 +1820,7 @@ return MinOpRes; } - if (SCEVUMaxExpr *M = dyn_cast(S)) { + if (const SCEVUMaxExpr *M = dyn_cast(S)) { // The result is the min of all operands results. uint32_t MinOpRes = GetMinTrailingZeros(M->getOperand(0), SE); for (unsigned i = 1, e = M->getNumOperands(); MinOpRes && i != e; ++i) @@ -2224,8 +2225,8 @@ // If we have a comparison of a chrec against a constant, try to use value // ranges to answer this query. - if (SCEVConstant *RHSC = dyn_cast(RHS)) - if (SCEVAddRecExpr *AddRec = dyn_cast(LHS)) + if (const SCEVConstant *RHSC = dyn_cast(RHS)) + if (const SCEVAddRecExpr *AddRec = dyn_cast(LHS)) if (AddRec->getLoop() == L) { // Form the comparison range using the constant of the correct type so // that the ConstantRange class knows to do a signed or unsigned @@ -2610,7 +2611,7 @@ // If this instruction is evolved from a constant-evolving PHI, compute the // exit value from the loop without using SCEVs. - if (SCEVUnknown *SU = dyn_cast(V)) { + if (const SCEVUnknown *SU = dyn_cast(V)) { if (Instruction *I = dyn_cast(SU->getValue())) { const Loop *LI = (*this->LI)[I->getParent()]; if (LI && LI->getParentLoop() == L) // Looking for loop exit value. @@ -2621,7 +2622,7 @@ // count. If so, we may be able to force computation of the exit // value. SCEVHandle BackedgeTakenCount = getBackedgeTakenCount(LI); - if (SCEVConstant *BTCC = + if (const SCEVConstant *BTCC = dyn_cast(BackedgeTakenCount)) { // Okay, we know how many times the containing loop executes. If // this is a constant evolving PHI node, get the final value at @@ -2652,7 +2653,7 @@ return V; SCEVHandle OpV = getSCEVAtScope(getSCEV(Op), L); - if (SCEVConstant *SC = dyn_cast(OpV)) { + if (const SCEVConstant *SC = dyn_cast(OpV)) { Constant *C = SC->getValue(); if (C->getType() != Op->getType()) C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false, @@ -2660,7 +2661,7 @@ false), C, Op->getType()); Operands.push_back(C); - } else if (SCEVUnknown *SU = dyn_cast(OpV)) { + } else if (const SCEVUnknown *SU = dyn_cast(OpV)) { if (Constant *C = dyn_cast(SU->getValue())) { if (C->getType() != Op->getType()) C = @@ -2692,7 +2693,7 @@ return V; } - if (SCEVCommutativeExpr *Comm = dyn_cast(V)) { + if (const SCEVCommutativeExpr *Comm = dyn_cast(V)) { // Avoid performing the look-up in the common case where the specified // expression has no loop-variant portions. for (unsigned i = 0, e = Comm->getNumOperands(); i != e; ++i) { @@ -2724,7 +2725,7 @@ return Comm; } - if (SCEVUDivExpr *Div = dyn_cast(V)) { + if (const SCEVUDivExpr *Div = dyn_cast(V)) { SCEVHandle LHS = getSCEVAtScope(Div->getLHS(), L); if (LHS == UnknownValue) return LHS; SCEVHandle RHS = getSCEVAtScope(Div->getRHS(), L); @@ -2736,7 +2737,7 @@ // If this is a loop recurrence for a loop that does not contain L, then we // are dealing with the final value computed by the loop. - if (SCEVAddRecExpr *AddRec = dyn_cast(V)) { + if (const SCEVAddRecExpr *AddRec = dyn_cast(V)) { if (!L || !AddRec->getLoop()->contains(L->getHeader())) { // To evaluate this recurrence, we need to know how many times the AddRec // loop iterates. Compute this now. @@ -2749,7 +2750,7 @@ return UnknownValue; } - if (SCEVZeroExtendExpr *Cast = dyn_cast(V)) { + if (const SCEVZeroExtendExpr *Cast = dyn_cast(V)) { SCEVHandle Op = getSCEVAtScope(Cast->getOperand(), L); if (Op == UnknownValue) return Op; if (Op == Cast->getOperand()) @@ -2757,7 +2758,7 @@ return getZeroExtendExpr(Op, Cast->getType()); } - if (SCEVSignExtendExpr *Cast = dyn_cast(V)) { + if (const SCEVSignExtendExpr *Cast = dyn_cast(V)) { SCEVHandle Op = getSCEVAtScope(Cast->getOperand(), L); if (Op == UnknownValue) return Op; if (Op == Cast->getOperand()) @@ -2765,7 +2766,7 @@ return getSignExtendExpr(Op, Cast->getType()); } - if (SCEVTruncateExpr *Cast = dyn_cast(V)) { + if (const SCEVTruncateExpr *Cast = dyn_cast(V)) { SCEVHandle Op = getSCEVAtScope(Cast->getOperand(), L); if (Op == UnknownValue) return Op; if (Op == Cast->getOperand()) @@ -2903,7 +2904,7 @@ /// value to zero will execute. If not computable, return UnknownValue SCEVHandle ScalarEvolution::HowFarToZero(SCEV *V, const Loop *L) { // If the value is a constant - if (SCEVConstant *C = dyn_cast(V)) { + if (const SCEVConstant *C = dyn_cast(V)) { // If the value is already zero, the branch will execute zero times. if (C->getValue()->isZero()) return C; return UnknownValue; // Otherwise it will loop infinitely. @@ -2931,7 +2932,7 @@ SCEVHandle Step = getSCEVAtScope(AddRec->getOperand(1), L->getParentLoop()); - if (SCEVConstant *StepC = dyn_cast(Step)) { + if (const SCEVConstant *StepC = dyn_cast(Step)) { // For now we handle only constant steps. // First, handle unitary steps. @@ -2941,7 +2942,7 @@ return Start; // N = Start (as unsigned) // Then, try to solve the above equation provided that Start is constant. - if (SCEVConstant *StartC = dyn_cast(Start)) + if (const SCEVConstant *StartC = dyn_cast(Start)) return SolveLinEquationWithOverflow(StepC->getValue()->getValue(), -StartC->getValue()->getValue(), *this); @@ -2988,7 +2989,7 @@ // If the value is a constant, check to see if it is known to be non-zero // already. If so, the backedge will execute zero times. - if (SCEVConstant *C = dyn_cast(V)) { + if (const SCEVConstant *C = dyn_cast(V)) { if (!C->getValue()->isNullValue()) return getIntegerSCEV(0, C->getType()); return UnknownValue; // Otherwise it will loop infinitely. @@ -3232,12 +3233,13 @@ return SE.getCouldNotCompute(); // If the start is a non-zero constant, shift the range to simplify things. - if (SCEVConstant *SC = dyn_cast(getStart())) + if (const SCEVConstant *SC = dyn_cast(getStart())) if (!SC->getValue()->isZero()) { std::vector Operands(op_begin(), op_end()); Operands[0] = SE.getIntegerSCEV(0, SC->getType()); SCEVHandle Shifted = SE.getAddRecExpr(Operands, getLoop()); - if (SCEVAddRecExpr *ShiftedAddRec = dyn_cast(Shifted)) + if (const SCEVAddRecExpr *ShiftedAddRec = + dyn_cast(Shifted)) return ShiftedAddRec->getNumIterationsInRange( Range.subtract(SC->getValue()->getValue()), SE); // This is strange and shouldn't happen. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=70919&r1=70918&r2=70919&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon May 4 17:02:23 2009 @@ -321,7 +321,7 @@ // for a nested AddRecExpr. if (const SCEVAddExpr *AE = dyn_cast(SH)) { for (unsigned i = 0, e = AE->getNumOperands(); i != e; ++i) - if (SCEVAddRecExpr *AddRec = + if (const SCEVAddRecExpr *AddRec = dyn_cast(AE->getOperand(i))) { if (AddRec->getLoop() == L) TheAddRec = SE->getAddExpr(AddRec, TheAddRec); @@ -1400,8 +1400,8 @@ // Iterate through the uses to find conditions that automatically rule out // full-lsr mode. for (unsigned i = 0, e = UsersToProcess.size(); i != e; ) { - SCEV *Base = UsersToProcess[i].Base; - SCEV *Imm = UsersToProcess[i].Imm; + const SCEV *Base = UsersToProcess[i].Base; + const SCEV *Imm = UsersToProcess[i].Imm; // If any users have a loop-variant component, they can't be fully // strength-reduced. if (Imm && !Imm->isLoopInvariant(L)) @@ -1410,7 +1410,7 @@ // the two Imm values can't be folded into the address, full // strength reduction would increase register pressure. do { - SCEV *CurImm = UsersToProcess[i].Imm; + const SCEV *CurImm = UsersToProcess[i].Imm; if ((CurImm || Imm) && CurImm != Imm) { if (!CurImm) CurImm = SE->getIntegerSCEV(0, Stride->getType()); if (!Imm) Imm = SE->getIntegerSCEV(0, Stride->getType()); From sabre at nondot.org Mon May 4 17:10:06 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 04 May 2009 22:10:06 -0000 Subject: [llvm-commits] [llvm] r70921 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200905042210.n44MA6ZB014912@zion.cs.uiuc.edu> Author: lattner Date: Mon May 4 17:10:05 2009 New Revision: 70921 URL: http://llvm.org/viewvc/llvm-project?rev=70921&view=rev Log: Make DBG_STOPPOINT nodes, and therefore DBG_LABEL labels, get a DebugLoc, so that it shows up in -print-machineinstrs. This doesn't appear to affect anything, but it was weird for some DBG_LABELs to have DebugLocs but not all of them. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=70921&r1=70920&r2=70921&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Mon May 4 17:10:05 2009 @@ -302,8 +302,8 @@ SDValue getArgFlags(ISD::ArgFlagsTy Flags); SDValue getValueType(MVT); SDValue getRegister(unsigned Reg, MVT VT); - SDValue getDbgStopPoint(SDValue Root, unsigned Line, unsigned Col, - Value *CU); + SDValue getDbgStopPoint(DebugLoc DL, SDValue Root, + unsigned Line, unsigned Col, Value *CU); SDValue getLabel(unsigned Opcode, DebugLoc dl, SDValue Root, unsigned LabelID); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=70921&r1=70920&r2=70921&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon May 4 17:10:05 2009 @@ -1273,11 +1273,12 @@ return SDValue(N, 0); } -SDValue SelectionDAG::getDbgStopPoint(SDValue Root, +SDValue SelectionDAG::getDbgStopPoint(DebugLoc DL, SDValue Root, unsigned Line, unsigned Col, Value *CU) { SDNode *N = NodeAllocator.Allocate(); new (N) DbgStopPointSDNode(Root, Line, Col, CU); + N->setDebugLoc(DL); AllNodes.push_back(N); return SDValue(N, 0); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=70921&r1=70920&r2=70921&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon May 4 17:10:05 2009 @@ -3889,15 +3889,16 @@ DbgStopPointInst &SPI = cast(I); if (DIDescriptor::ValidDebugInfo(SPI.getContext(), OptLevel)) { MachineFunction &MF = DAG.getMachineFunction(); + DICompileUnit CU(cast(SPI.getContext())); + DebugLoc Loc = DebugLoc::get(MF.getOrCreateDebugLocID(CU.getGV(), + SPI.getLine(), SPI.getColumn())); + setCurDebugLoc(Loc); + if (OptLevel == CodeGenOpt::None) - DAG.setRoot(DAG.getDbgStopPoint(getRoot(), + DAG.setRoot(DAG.getDbgStopPoint(Loc, getRoot(), SPI.getLine(), SPI.getColumn(), SPI.getContext())); - DICompileUnit CU(cast(SPI.getContext())); - unsigned idx = MF.getOrCreateDebugLocID(CU.getGV(), - SPI.getLine(), SPI.getColumn()); - setCurDebugLoc(DebugLoc::get(idx)); } return 0; } From gohman at apple.com Mon May 4 17:20:30 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 04 May 2009 22:20:30 -0000 Subject: [llvm-commits] [llvm] r70924 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200905042220.n44MKUKL015240@zion.cs.uiuc.edu> Author: djg Date: Mon May 4 17:20:30 2009 New Revision: 70924 URL: http://llvm.org/viewvc/llvm-project?rev=70924&view=rev Log: Fix doxygen comment syntax. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=70924&r1=70923&r2=70924&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon May 4 17:20:30 2009 @@ -1544,7 +1544,7 @@ return UnknownValue; } -// hasSCEV - Return true if the SCEV for this value has already been +/// hasSCEV - Return true if the SCEV for this value has already been /// computed. bool ScalarEvolution::hasSCEV(Value *V) const { return Scalars.count(V); From gohman at apple.com Mon May 4 17:23:19 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 04 May 2009 22:23:19 -0000 Subject: [llvm-commits] [llvm] r70925 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200905042223.n44MNJAZ015316@zion.cs.uiuc.edu> Author: djg Date: Mon May 4 17:23:18 2009 New Revision: 70925 URL: http://llvm.org/viewvc/llvm-project?rev=70925&view=rev Log: Fix an 80-column violation. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=70925&r1=70924&r2=70925&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon May 4 17:23:18 2009 @@ -1224,7 +1224,8 @@ return Result; } -SCEVHandle ScalarEvolution::getUDivExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) { +SCEVHandle ScalarEvolution::getUDivExpr(const SCEVHandle &LHS, + const SCEVHandle &RHS) { if (const SCEVConstant *RHSC = dyn_cast(RHS)) { if (RHSC->getValue()->equalsInt(1)) return LHS; // X udiv 1 --> x From gohman at apple.com Mon May 4 17:30:44 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 04 May 2009 22:30:44 -0000 Subject: [llvm-commits] [llvm] r70927 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h include/llvm/Transforms/Utils/BasicBlockUtils.h include/llvm/Transforms/Utils/Local.h lib/Analysis/ScalarEvolution.cpp lib/Transforms/Scalar/IndVarSimplify.cpp lib/Transforms/Scalar/LoopDeletion.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp lib/Transforms/Utils/BasicBlockUtils.cpp lib/Transforms/Utils/Local.cpp Message-ID: <200905042230.n44MUjMo015556@zion.cs.uiuc.edu> Author: djg Date: Mon May 4 17:30:44 2009 New Revision: 70927 URL: http://llvm.org/viewvc/llvm-project?rev=70927&view=rev Log: Re-apply 70645, converting ScalarEvolution to use CallbackVH, with fixes. allUsesReplacedWith need to walk the def-use chains and invalidate all users of a value that is replaced. SCEVs of users need to be recalcualted even if the new value is equivalent. Also, make forgetLoopPHIs walk def-use chains, since any SCEV that depends on a PHI should be recalculated when more information about that PHI becomes available. Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/trunk/include/llvm/Transforms/Utils/Local.h llvm/trunk/lib/Analysis/ScalarEvolution.cpp llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=70927&r1=70926&r2=70927&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Mon May 4 17:30:44 2009 @@ -24,6 +24,7 @@ #include "llvm/Pass.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ValueHandle.h" #include namespace llvm { @@ -140,13 +141,23 @@ static bool classof(const SCEV *S); }; + /// SCEVCallbackVH - A CallbackVH to arrange for ScalarEvolution to be + /// notified whenever a Value is deleted. + class SCEVCallbackVH : public CallbackVH { + ScalarEvolution *SE; + virtual void deleted(); + virtual void allUsesReplacedWith(Value *New); + public: + SCEVCallbackVH(Value *V, ScalarEvolution *SE = 0); + }; + /// SCEVHandle - This class is used to maintain the SCEV object's refcounts, /// freeing the objects when the last reference is dropped. class SCEVHandle { - SCEV *S; + const SCEV *S; SCEVHandle(); // DO NOT IMPLEMENT public: - SCEVHandle(const SCEV *s) : S(const_cast(s)) { + SCEVHandle(const SCEV *s) : S(s) { assert(S && "Cannot create a handle to a null SCEV!"); S->addRef(); } @@ -155,13 +166,13 @@ } ~SCEVHandle() { S->dropRef(); } - operator SCEV*() const { return S; } + operator const SCEV*() const { return S; } - SCEV &operator*() const { return *S; } - SCEV *operator->() const { return S; } + const SCEV &operator*() const { return *S; } + const SCEV *operator->() const { return S; } - bool operator==(SCEV *RHS) const { return S == RHS; } - bool operator!=(SCEV *RHS) const { return S != RHS; } + bool operator==(const SCEV *RHS) const { return S == RHS; } + bool operator!=(const SCEV *RHS) const { return S != RHS; } const SCEVHandle &operator=(SCEV *RHS) { if (S != RHS) { @@ -184,7 +195,7 @@ template struct simplify_type; template<> struct simplify_type { - typedef SCEV* SimpleType; + typedef const SCEV* SimpleType; static SimpleType getSimplifiedValue(const SCEVHandle &Node) { return Node; } @@ -197,6 +208,8 @@ /// they must ask this class for services. /// class ScalarEvolution : public FunctionPass { + friend class SCEVCallbackVH; + /// F - The function we are analyzing. /// Function *F; @@ -215,7 +228,7 @@ /// Scalars - This is a cache of the scalars we have analyzed so far. /// - std::map Scalars; + std::map Scalars; /// BackedgeTakenInfo - Information about the backedge-taken count /// of a loop. This currently inclues an exact count and a maximum count. @@ -232,7 +245,7 @@ /*implicit*/ BackedgeTakenInfo(SCEVHandle exact) : Exact(exact), Max(exact) {} - /*implicit*/ BackedgeTakenInfo(SCEV *exact) : + /*implicit*/ BackedgeTakenInfo(const SCEV *exact) : Exact(exact), Max(exact) {} BackedgeTakenInfo(SCEVHandle exact, SCEVHandle max) : @@ -302,18 +315,18 @@ /// HowFarToZero - Return the number of times a backedge comparing the /// specified value to zero will execute. If not computable, return /// UnknownValue. - SCEVHandle HowFarToZero(SCEV *V, const Loop *L); + SCEVHandle HowFarToZero(const SCEV *V, const Loop *L); /// HowFarToNonZero - Return the number of times a backedge checking the /// specified value for nonzero will execute. If not computable, return /// UnknownValue. - SCEVHandle HowFarToNonZero(SCEV *V, const Loop *L); + SCEVHandle HowFarToNonZero(const SCEV *V, const Loop *L); /// HowManyLessThans - Return the number of times a backedge containing the /// specified less-than comparison will execute. If not computable, return /// UnknownValue. isSigned specifies whether the less-than is signed. - BackedgeTakenInfo HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, - bool isSigned); + BackedgeTakenInfo HowManyLessThans(const SCEV *LHS, const SCEV *RHS, + const Loop *L, bool isSigned); /// getPredecessorWithUniqueSuccessorForBB - Return a predecessor of BB /// (which may not be an immediate predecessor) which has exactly one @@ -331,7 +344,7 @@ /// getSCEVAtScope - Compute the value of the specified expression within /// the indicated loop (which may be null to indicate in no loop). If the /// expression cannot be evaluated, return UnknownValue itself. - SCEVHandle getSCEVAtScope(SCEV *S, const Loop *L); + SCEVHandle getSCEVAtScope(const SCEV *S, const Loop *L); /// forgetLoopPHIs - Delete the memoized SCEVs associated with the /// PHI nodes in the given loop. This is used when the trip count of @@ -457,7 +470,7 @@ /// a conditional between LHS and RHS. This is used to help avoid max /// expressions in loop trip counts. bool isLoopGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, - SCEV *LHS, SCEV *RHS); + const SCEV *LHS, const SCEV *RHS); /// getBackedgeTakenCount - If the specified loop has a predictable /// backedge-taken count, return it, otherwise return a SCEVCouldNotCompute @@ -487,11 +500,6 @@ /// is deleted. void forgetLoopBackedgeTakenCount(const Loop *L); - /// deleteValueFromRecords - This method should be called by the - /// client before it removes a Value from the program, to make sure - /// that no dangling references are left around. - void deleteValueFromRecords(Value *V); - virtual bool runOnFunction(Function &F); virtual void releaseMemory(); virtual void getAnalysisUsage(AnalysisUsage &AU) const; Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=70927&r1=70926&r2=70927&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Mon May 4 17:30:44 2009 @@ -25,7 +25,6 @@ class Instruction; class Pass; class AliasAnalysis; -class ValueDeletionListener; /// DeleteDeadBlock - Delete the specified block, which must have no /// predecessors. @@ -41,9 +40,8 @@ /// DeleteDeadPHIs - Examine each PHI in the given block and delete it if it /// is dead. Also recursively delete any operands that become dead as /// a result. This includes tracing the def-use list from the PHI to see if -/// it is ultimately unused or if it reaches an unused cycle. If a -/// ValueDeletionListener is specified, it is notified of the deletions. -void DeleteDeadPHIs(BasicBlock *BB, ValueDeletionListener *VDL = 0); +/// it is ultimately unused or if it reaches an unused cycle. +void DeleteDeadPHIs(BasicBlock *BB); /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// if possible. The return value indicates success or failure. Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=70927&r1=70926&r2=70927&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Mon May 4 17:30:44 2009 @@ -50,40 +50,17 @@ /// bool isInstructionTriviallyDead(Instruction *I); -/// ValueDeletionListener - A simple abstract interface for delivering -/// notifications when Values are deleted. -/// -/// @todo Consider whether ValueDeletionListener can be made obsolete by -/// requiring clients to use CallbackVH instead. -class ValueDeletionListener { -public: - /// ValueWillBeDeleted - This method is called shortly before the specified - /// value will be deleted. - virtual void ValueWillBeDeleted(Value *V) = 0; - -protected: - virtual ~ValueDeletionListener(); -}; - /// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a /// trivially dead instruction, delete it. If that makes any of its operands /// trivially dead, delete them too, recursively. -/// -/// If a ValueDeletionListener is specified, it is notified of instructions that -/// are actually deleted (before they are actually deleted). -void RecursivelyDeleteTriviallyDeadInstructions(Value *V, - ValueDeletionListener *VDL = 0); +void RecursivelyDeleteTriviallyDeadInstructions(Value *V); /// RecursivelyDeleteDeadPHINode - If the specified value is an effectively /// dead PHI node, due to being a def-use chain of single-use nodes that /// either forms a cycle or is terminated by a trivially dead instruction, /// delete it. If that makes any of its operands trivially dead, delete them /// too, recursively. -/// -/// If a ValueDeletionListener is specified, it is notified of instructions that -/// are actually deleted (before they are actually deleted). -void RecursivelyDeleteDeadPHINode(PHINode *PN, - ValueDeletionListener *VDL = 0); +void RecursivelyDeleteDeadPHINode(PHINode *PN); //===----------------------------------------------------------------------===// // Control Flow Graph Restructuring. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=70927&r1=70926&r2=70927&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon May 4 17:30:44 2009 @@ -204,7 +204,7 @@ // SCEVTruncates - Only allow the creation of one SCEVTruncateExpr for any // particular input. Don't use a SCEVHandle here, or else the object will // never be deleted! -static ManagedStatic, +static ManagedStatic, SCEVTruncateExpr*> > SCEVTruncates; SCEVTruncateExpr::SCEVTruncateExpr(const SCEVHandle &op, const Type *ty) @@ -225,7 +225,7 @@ // SCEVZeroExtends - Only allow the creation of one SCEVZeroExtendExpr for any // particular input. Don't use a SCEVHandle here, or else the object will never // be deleted! -static ManagedStatic, +static ManagedStatic, SCEVZeroExtendExpr*> > SCEVZeroExtends; SCEVZeroExtendExpr::SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty) @@ -246,7 +246,7 @@ // SCEVSignExtends - Only allow the creation of one SCEVSignExtendExpr for any // particular input. Don't use a SCEVHandle here, or else the object will never // be deleted! -static ManagedStatic, +static ManagedStatic, SCEVSignExtendExpr*> > SCEVSignExtends; SCEVSignExtendExpr::SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty) @@ -267,13 +267,12 @@ // SCEVCommExprs - Only allow the creation of one SCEVCommutativeExpr for any // particular input. Don't use a SCEVHandle here, or else the object will never // be deleted! -static ManagedStatic >, +static ManagedStatic >, SCEVCommutativeExpr*> > SCEVCommExprs; SCEVCommutativeExpr::~SCEVCommutativeExpr() { - SCEVCommExprs->erase(std::make_pair(getSCEVType(), - std::vector(Operands.begin(), - Operands.end()))); + std::vector SCEVOps(Operands.begin(), Operands.end()); + SCEVCommExprs->erase(std::make_pair(getSCEVType(), SCEVOps)); } void SCEVCommutativeExpr::print(raw_ostream &OS) const { @@ -329,7 +328,7 @@ // SCEVUDivs - Only allow the creation of one SCEVUDivExpr for any particular // input. Don't use a SCEVHandle here, or else the object will never be // deleted! -static ManagedStatic, +static ManagedStatic, SCEVUDivExpr*> > SCEVUDivs; SCEVUDivExpr::~SCEVUDivExpr() { @@ -351,13 +350,13 @@ // SCEVAddRecExprs - Only allow the creation of one SCEVAddRecExpr for any // particular input. Don't use a SCEVHandle here, or else the object will never // be deleted! -static ManagedStatic >, +static ManagedStatic >, SCEVAddRecExpr*> > SCEVAddRecExprs; SCEVAddRecExpr::~SCEVAddRecExpr() { - SCEVAddRecExprs->erase(std::make_pair(L, - std::vector(Operands.begin(), - Operands.end()))); + std::vector SCEVOps(Operands.begin(), Operands.end()); + SCEVAddRecExprs->erase(std::make_pair(L, SCEVOps)); } bool SCEVAddRecExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { @@ -480,7 +479,7 @@ // be extremely short in practice. Note that we take this approach because we // do not want to depend on the addresses of the objects we are grouping. for (unsigned i = 0, e = Ops.size(); i != e-2; ++i) { - SCEV *S = Ops[i]; + const SCEV *S = Ops[i]; unsigned Complexity = S->getSCEVType(); // If there are any objects of the same complexity and same value as this @@ -919,9 +918,9 @@ // something is not already an operand of the multiply. If so, merge it into // the multiply. for (; Idx < Ops.size() && isa(Ops[Idx]); ++Idx) { - SCEVMulExpr *Mul = cast(Ops[Idx]); + const SCEVMulExpr *Mul = cast(Ops[Idx]); for (unsigned MulOp = 0, e = Mul->getNumOperands(); MulOp != e; ++MulOp) { - SCEV *MulOpSCEV = Mul->getOperand(MulOp); + const SCEV *MulOpSCEV = Mul->getOperand(MulOp); for (unsigned AddOp = 0, e = Ops.size(); AddOp != e; ++AddOp) if (MulOpSCEV == Ops[AddOp] && !isa(MulOpSCEV)) { // Fold W + X + (X * Y * Z) --> W + (X * ((Y*Z)+1)) @@ -952,7 +951,7 @@ for (unsigned OtherMulIdx = Idx+1; OtherMulIdx < Ops.size() && isa(Ops[OtherMulIdx]); ++OtherMulIdx) { - SCEVMulExpr *OtherMul = cast(Ops[OtherMulIdx]); + const SCEVMulExpr *OtherMul = cast(Ops[OtherMulIdx]); // If MulOp occurs in OtherMul, we can fold the two multiplies // together. for (unsigned OMulOp = 0, e = OtherMul->getNumOperands(); @@ -995,7 +994,7 @@ // Scan all of the other operands to this add and add them to the vector if // they are loop invariant w.r.t. the recurrence. std::vector LIOps; - SCEVAddRecExpr *AddRec = cast(Ops[Idx]); + const SCEVAddRecExpr *AddRec = cast(Ops[Idx]); for (unsigned i = 0, e = Ops.size(); i != e; ++i) if (Ops[i]->isLoopInvariant(AddRec->getLoop())) { LIOps.push_back(Ops[i]); @@ -1030,7 +1029,7 @@ for (unsigned OtherIdx = Idx+1; OtherIdx < Ops.size() && isa(Ops[OtherIdx]);++OtherIdx) if (OtherIdx != Idx) { - SCEVAddRecExpr *OtherAddRec = cast(Ops[OtherIdx]); + const SCEVAddRecExpr *OtherAddRec = cast(Ops[OtherIdx]); if (AddRec->getLoop() == OtherAddRec->getLoop()) { // Other + {A,+,B} + {C,+,D} --> Other + {A+C,+,B+D} std::vector NewOps(AddRec->op_begin(), AddRec->op_end()); @@ -1059,7 +1058,7 @@ // Okay, it looks like we really DO need an add expr. Check to see if we // already have one, otherwise create a new one. - std::vector SCEVOps(Ops.begin(), Ops.end()); + std::vector SCEVOps(Ops.begin(), Ops.end()); SCEVCommutativeExpr *&Result = (*SCEVCommExprs)[std::make_pair(scAddExpr, SCEVOps)]; if (Result == 0) Result = new SCEVAddExpr(Ops); @@ -1143,7 +1142,7 @@ // Scan all of the other operands to this mul and add them to the vector if // they are loop invariant w.r.t. the recurrence. std::vector LIOps; - SCEVAddRecExpr *AddRec = cast(Ops[Idx]); + const SCEVAddRecExpr *AddRec = cast(Ops[Idx]); for (unsigned i = 0, e = Ops.size(); i != e; ++i) if (Ops[i]->isLoopInvariant(AddRec->getLoop())) { LIOps.push_back(Ops[i]); @@ -1157,7 +1156,7 @@ std::vector NewOps; NewOps.reserve(AddRec->getNumOperands()); if (LIOps.size() == 1) { - SCEV *Scale = LIOps[0]; + const SCEV *Scale = LIOps[0]; for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) NewOps.push_back(getMulExpr(Scale, AddRec->getOperand(i))); } else { @@ -1188,10 +1187,10 @@ for (unsigned OtherIdx = Idx+1; OtherIdx < Ops.size() && isa(Ops[OtherIdx]);++OtherIdx) if (OtherIdx != Idx) { - SCEVAddRecExpr *OtherAddRec = cast(Ops[OtherIdx]); + const SCEVAddRecExpr *OtherAddRec = cast(Ops[OtherIdx]); if (AddRec->getLoop() == OtherAddRec->getLoop()) { // F * G --> {A,+,B} * {C,+,D} --> {A*C,+,F*D + G*B + B*D} - SCEVAddRecExpr *F = AddRec, *G = OtherAddRec; + const SCEVAddRecExpr *F = AddRec, *G = OtherAddRec; SCEVHandle NewStart = getMulExpr(F->getStart(), G->getStart()); SCEVHandle B = F->getStepRecurrence(*this); @@ -1216,7 +1215,7 @@ // Okay, it looks like we really DO need an mul expr. Check to see if we // already have one, otherwise create a new one. - std::vector SCEVOps(Ops.begin(), Ops.end()); + std::vector SCEVOps(Ops.begin(), Ops.end()); SCEVCommutativeExpr *&Result = (*SCEVCommExprs)[std::make_pair(scMulExpr, SCEVOps)]; if (Result == 0) @@ -1286,9 +1285,8 @@ } } - SCEVAddRecExpr *&Result = - (*SCEVAddRecExprs)[std::make_pair(L, std::vector(Operands.begin(), - Operands.end()))]; + std::vector SCEVOps(Operands.begin(), Operands.end()); + SCEVAddRecExpr *&Result = (*SCEVAddRecExprs)[std::make_pair(L, SCEVOps)]; if (Result == 0) Result = new SCEVAddRecExpr(Operands, L); return Result; } @@ -1366,7 +1364,7 @@ // Okay, it looks like we really DO need an smax expr. Check to see if we // already have one, otherwise create a new one. - std::vector SCEVOps(Ops.begin(), Ops.end()); + std::vector SCEVOps(Ops.begin(), Ops.end()); SCEVCommutativeExpr *&Result = (*SCEVCommExprs)[std::make_pair(scSMaxExpr, SCEVOps)]; if (Result == 0) Result = new SCEVSMaxExpr(Ops); @@ -1446,7 +1444,7 @@ // Okay, it looks like we really DO need a umax expr. Check to see if we // already have one, otherwise create a new one. - std::vector SCEVOps(Ops.begin(), Ops.end()); + std::vector SCEVOps(Ops.begin(), Ops.end()); SCEVCommutativeExpr *&Result = (*SCEVCommExprs)[std::make_pair(scUMaxExpr, SCEVOps)]; if (Result == 0) Result = new SCEVUMaxExpr(Ops); @@ -1467,34 +1465,6 @@ // Basic SCEV Analysis and PHI Idiom Recognition Code // -/// deleteValueFromRecords - This method should be called by the -/// client before it removes an instruction from the program, to make sure -/// that no dangling references are left around. -void ScalarEvolution::deleteValueFromRecords(Value *V) { - SmallVector Worklist; - - if (Scalars.erase(V)) { - if (PHINode *PN = dyn_cast(V)) - ConstantEvolutionLoopExitValue.erase(PN); - Worklist.push_back(V); - } - - while (!Worklist.empty()) { - Value *VV = Worklist.back(); - Worklist.pop_back(); - - for (Instruction::use_iterator UI = VV->use_begin(), UE = VV->use_end(); - UI != UE; ++UI) { - Instruction *Inst = cast(*UI); - if (Scalars.erase(Inst)) { - if (PHINode *PN = dyn_cast(VV)) - ConstantEvolutionLoopExitValue.erase(PN); - Worklist.push_back(Inst); - } - } - } -} - /// isSCEVable - Test if values of the given type are analyzable within /// the SCEV framework. This primarily includes integer types, and it /// can optionally include pointer types if the ScalarEvolution class @@ -1556,10 +1526,10 @@ SCEVHandle ScalarEvolution::getSCEV(Value *V) { assert(isSCEVable(V->getType()) && "Value is not SCEVable!"); - std::map::iterator I = Scalars.find(V); + std::map::iterator I = Scalars.find(V); if (I != Scalars.end()) return I->second; SCEVHandle S = createSCEV(V); - Scalars.insert(std::make_pair(V, S)); + Scalars.insert(std::make_pair(SCEVCallbackVH(V, this), S)); return S; } @@ -1648,7 +1618,8 @@ void ScalarEvolution:: ReplaceSymbolicValueWithConcrete(Instruction *I, const SCEVHandle &SymName, const SCEVHandle &NewVal) { - std::map::iterator SI = Scalars.find(I); + std::map::iterator SI = + Scalars.find(SCEVCallbackVH(I, this)); if (SI == Scalars.end()) return; SCEVHandle NV = @@ -1680,7 +1651,7 @@ SCEVHandle SymbolicName = getUnknown(PN); assert(Scalars.find(PN) == Scalars.end() && "PHI node already processed?"); - Scalars.insert(std::make_pair(PN, SymbolicName)); + Scalars.insert(std::make_pair(SCEVCallbackVH(PN, this), SymbolicName)); // Using this symbolic name for the PHI, analyze the value coming around // the back-edge. @@ -2131,9 +2102,20 @@ /// PHI nodes in the given loop. This is used when the trip count of /// the loop may have changed. void ScalarEvolution::forgetLoopPHIs(const Loop *L) { - for (BasicBlock::iterator I = L->getHeader()->begin(); + BasicBlock *Header = L->getHeader(); + + SmallVector Worklist; + for (BasicBlock::iterator I = Header->begin(); PHINode *PN = dyn_cast(I); ++I) - deleteValueFromRecords(PN); + Worklist.push_back(PN); + + while (!Worklist.empty()) { + Instruction *I = Worklist.pop_back_val(); + if (Scalars.erase(I)) + for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); + UI != UE; ++UI) + Worklist.push_back(cast(UI)); + } } /// ComputeBackedgeTakenCount - Compute the number of times the backedge @@ -2384,7 +2366,7 @@ // We can only recognize very limited forms of loop index expressions, in // particular, only affine AddRec's like {C1,+,C2}. - SCEVAddRecExpr *IdxExpr = dyn_cast(Idx); + const SCEVAddRecExpr *IdxExpr = dyn_cast(Idx); if (!IdxExpr || !IdxExpr->isAffine() || IdxExpr->isLoopInvariant(L) || !isa(IdxExpr->getOperand(0)) || !isa(IdxExpr->getOperand(1))) @@ -2605,7 +2587,7 @@ /// getSCEVAtScope - Compute the value of the specified expression within the /// indicated loop (which may be null to indicate in no loop). If the /// expression cannot be evaluated, return UnknownValue. -SCEVHandle ScalarEvolution::getSCEVAtScope(SCEV *V, const Loop *L) { +SCEVHandle ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) { // FIXME: this should be turned into a virtual method on SCEV! if (isa(V)) return V; @@ -2847,13 +2829,13 @@ static std::pair SolveQuadraticEquation(const SCEVAddRecExpr *AddRec, ScalarEvolution &SE) { assert(AddRec->getNumOperands() == 3 && "This is not a quadratic chrec!"); - SCEVConstant *LC = dyn_cast(AddRec->getOperand(0)); - SCEVConstant *MC = dyn_cast(AddRec->getOperand(1)); - SCEVConstant *NC = dyn_cast(AddRec->getOperand(2)); + const SCEVConstant *LC = dyn_cast(AddRec->getOperand(0)); + const SCEVConstant *MC = dyn_cast(AddRec->getOperand(1)); + const SCEVConstant *NC = dyn_cast(AddRec->getOperand(2)); // We currently can only solve this if the coefficients are constants. if (!LC || !MC || !NC) { - SCEV *CNC = SE.getCouldNotCompute(); + const SCEV *CNC = SE.getCouldNotCompute(); return std::make_pair(CNC, CNC); } @@ -2889,7 +2871,7 @@ APInt NegB(-B); APInt TwoA( A << 1 ); if (TwoA.isMinValue()) { - SCEV *CNC = SE.getCouldNotCompute(); + const SCEV *CNC = SE.getCouldNotCompute(); return std::make_pair(CNC, CNC); } @@ -2903,7 +2885,7 @@ /// HowFarToZero - Return the number of times a backedge comparing the specified /// value to zero will execute. If not computable, return UnknownValue -SCEVHandle ScalarEvolution::HowFarToZero(SCEV *V, const Loop *L) { +SCEVHandle ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) { // If the value is a constant if (const SCEVConstant *C = dyn_cast(V)) { // If the value is already zero, the branch will execute zero times. @@ -2911,7 +2893,7 @@ return UnknownValue; // Otherwise it will loop infinitely. } - SCEVAddRecExpr *AddRec = dyn_cast(V); + const SCEVAddRecExpr *AddRec = dyn_cast(V); if (!AddRec || AddRec->getLoop() != L) return UnknownValue; @@ -2953,8 +2935,8 @@ // the quadratic equation to solve it. std::pair Roots = SolveQuadraticEquation(AddRec, *this); - SCEVConstant *R1 = dyn_cast(Roots.first); - SCEVConstant *R2 = dyn_cast(Roots.second); + const SCEVConstant *R1 = dyn_cast(Roots.first); + const SCEVConstant *R2 = dyn_cast(Roots.second); if (R1) { #if 0 errs() << "HFTZ: " << *V << " - sol#1: " << *R1 @@ -2983,7 +2965,7 @@ /// HowFarToNonZero - Return the number of times a backedge checking the /// specified value for nonzero will execute. If not computable, return /// UnknownValue -SCEVHandle ScalarEvolution::HowFarToNonZero(SCEV *V, const Loop *L) { +SCEVHandle ScalarEvolution::HowFarToNonZero(const SCEV *V, const Loop *L) { // Loops that look like: while (X == 0) are very strange indeed. We don't // handle them yet except for the trivial case. This could be expanded in the // future as needed. @@ -3029,7 +3011,7 @@ /// expressions in loop trip counts. bool ScalarEvolution::isLoopGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, - SCEV *LHS, SCEV *RHS) { + const SCEV *LHS, const SCEV *RHS) { BasicBlock *Preheader = L->getLoopPreheader(); BasicBlock *PreheaderDest = L->getHeader(); @@ -3133,11 +3115,12 @@ /// specified less-than comparison will execute. If not computable, return /// UnknownValue. ScalarEvolution::BackedgeTakenInfo ScalarEvolution:: -HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, bool isSigned) { +HowManyLessThans(const SCEV *LHS, const SCEV *RHS, + const Loop *L, bool isSigned) { // Only handle: "ADDREC < LoopInvariant". if (!RHS->isLoopInvariant(L)) return UnknownValue; - SCEVAddRecExpr *AddRec = dyn_cast(LHS); + const SCEVAddRecExpr *AddRec = dyn_cast(LHS); if (!AddRec || AddRec->getLoop() != L) return UnknownValue; @@ -3304,8 +3287,8 @@ // Next, solve the constructed addrec std::pair Roots = SolveQuadraticEquation(cast(NewAddRec), SE); - SCEVConstant *R1 = dyn_cast(Roots.first); - SCEVConstant *R2 = dyn_cast(Roots.second); + const SCEVConstant *R1 = dyn_cast(Roots.first); + const SCEVConstant *R2 = dyn_cast(Roots.second); if (R1) { // Pick the smallest positive root value. if (ConstantInt *CB = @@ -3347,6 +3330,57 @@ //===----------------------------------------------------------------------===// +// SCEVCallbackVH Class Implementation +//===----------------------------------------------------------------------===// + +void SCEVCallbackVH::deleted() { + assert(SE && "SCEVCallbackVH called with a non-null ScalarEvolution!"); + if (PHINode *PN = dyn_cast(getValPtr())) + SE->ConstantEvolutionLoopExitValue.erase(PN); + SE->Scalars.erase(getValPtr()); + // this now dangles! +} + +void SCEVCallbackVH::allUsesReplacedWith(Value *) { + assert(SE && "SCEVCallbackVH called with a non-null ScalarEvolution!"); + + // Forget all the expressions associated with users of the old value, + // so that future queries will recompute the expressions using the new + // value. + SmallVector Worklist; + Value *Old = getValPtr(); + bool DeleteOld = false; + for (Value::use_iterator UI = Old->use_begin(), UE = Old->use_end(); + UI != UE; ++UI) + Worklist.push_back(*UI); + while (!Worklist.empty()) { + User *U = Worklist.pop_back_val(); + // Deleting the Old value will cause this to dangle. Postpone + // that until everything else is done. + if (U == Old) { + DeleteOld = true; + continue; + } + if (PHINode *PN = dyn_cast(U)) + SE->ConstantEvolutionLoopExitValue.erase(PN); + if (SE->Scalars.erase(U)) + for (Value::use_iterator UI = U->use_begin(), UE = U->use_end(); + UI != UE; ++UI) + Worklist.push_back(*UI); + } + if (DeleteOld) { + if (PHINode *PN = dyn_cast(Old)) + SE->ConstantEvolutionLoopExitValue.erase(PN); + SE->Scalars.erase(Old); + // this now dangles! + } + // this may dangle! +} + +SCEVCallbackVH::SCEVCallbackVH(Value *V, ScalarEvolution *se) + : CallbackVH(V), SE(se) {} + +//===----------------------------------------------------------------------===// // ScalarEvolution Class Implementation //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=70927&r1=70926&r2=70927&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Mon May 4 17:30:44 2009 @@ -124,7 +124,6 @@ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) if (Instruction *U = dyn_cast(I->getOperand(i))) Insts.insert(U); - SE->deleteValueFromRecords(I); DOUT << "INDVARS: Deleting: " << *I; I->eraseFromParent(); Changed = true; @@ -308,7 +307,6 @@ // the PHI entirely. This is safe, because the NewVal won't be variant // in the loop, so we don't need an LCSSA phi node anymore. if (NumPreds == 1) { - SE->deleteValueFromRecords(PN); PN->replaceAllUsesWith(ExitVal); PN->eraseFromParent(); break; Modified: llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp?rev=70927&r1=70926&r2=70927&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Mon May 4 17:30:44 2009 @@ -246,13 +246,6 @@ DT.eraseNode(*LI); if (DF) DF->removeBlock(*LI); - // Remove instructions that we're deleting from ScalarEvolution. - for (BasicBlock::iterator BI = (*LI)->begin(), BE = (*LI)->end(); - BI != BE; ++BI) - SE.deleteValueFromRecords(BI); - - SE.deleteValueFromRecords(*LI); - // Remove the block from the reference counting scheme, so that we can // delete it freely later. (*LI)->dropAllReferences(); Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=70927&r1=70926&r2=70927&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon May 4 17:30:44 2009 @@ -253,8 +253,6 @@ if (I == 0 || !isInstructionTriviallyDead(I)) continue; - SE->deleteValueFromRecords(I); - for (User::op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI) { if (Instruction *U = dyn_cast(*OI)) { *OI = 0; @@ -2130,7 +2128,6 @@ // Remove the old compare instruction. The old indvar is probably dead too. DeadInsts.push_back(cast(CondUse->OperandValToReplace)); - SE->deleteValueFromRecords(OldCond); OldCond->replaceAllUsesWith(Cond); OldCond->eraseFromParent(); @@ -2214,7 +2211,7 @@ SCEVHandle IterationCount = SE->getAddExpr(BackedgeTakenCount, One); // Check for a max calculation that matches the pattern. - SCEVSMaxExpr *SMax = dyn_cast(IterationCount); + const SCEVSMaxExpr *SMax = dyn_cast(IterationCount); if (!SMax || SMax != SE->getSCEV(Sel)) return Cond; SCEVHandle SMaxLHS = SMax->getOperand(0); @@ -2251,16 +2248,12 @@ Cond->getOperand(0), NewRHS, "scmp", Cond); // Delete the max calculation instructions. - SE->deleteValueFromRecords(Cond); Cond->replaceAllUsesWith(NewCond); Cond->eraseFromParent(); Instruction *Cmp = cast(Sel->getOperand(0)); - SE->deleteValueFromRecords(Sel); Sel->eraseFromParent(); - if (Cmp->use_empty()) { - SE->deleteValueFromRecords(Cmp); + if (Cmp->use_empty()) Cmp->eraseFromParent(); - } CondUse->User = NewCond; return NewCond; } @@ -2367,7 +2360,6 @@ NewPH->addIncoming(NewIncr, PH->getIncomingBlock(Latch)); /* Remove cast operation */ - SE->deleteValueFromRecords(ShadowUse); ShadowUse->replaceAllUsesWith(NewPH); ShadowUse->eraseFromParent(); SI->second.Users.erase(CandidateUI); @@ -2507,17 +2499,8 @@ DeleteTriviallyDeadInstructions(); // At this point, it is worth checking to see if any recurrence PHIs are also - // dead, so that we can remove them as well. To keep ScalarEvolution - // current, use a ValueDeletionListener class. - struct LSRListener : public ValueDeletionListener { - ScalarEvolution &SE; - explicit LSRListener(ScalarEvolution &se) : SE(se) {} - - virtual void ValueWillBeDeleted(Value *V) { - SE.deleteValueFromRecords(V); - } - } VDL(*SE); - DeleteDeadPHIs(L->getHeader(), &VDL); + // dead, so that we can remove them as well. + DeleteDeadPHIs(L->getHeader()); return Changed; } Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=70927&r1=70926&r2=70927&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Mon May 4 17:30:44 2009 @@ -78,9 +78,8 @@ /// DeleteDeadPHIs - Examine each PHI in the given block and delete it if it /// is dead. Also recursively delete any operands that become dead as /// a result. This includes tracing the def-use list from the PHI to see if -/// it is ultimately unused or if it reaches an unused cycle. If a -/// ValueDeletionListener is specified, it is notified of the deletions. -void llvm::DeleteDeadPHIs(BasicBlock *BB, ValueDeletionListener *VDL) { +/// it is ultimately unused or if it reaches an unused cycle. +void llvm::DeleteDeadPHIs(BasicBlock *BB) { // Recursively deleting a PHI may cause multiple PHIs to be deleted // or RAUW'd undef, so use an array of WeakVH for the PHIs to delete. SmallVector PHIs; @@ -90,7 +89,7 @@ for (unsigned i = 0, e = PHIs.size(); i != e; ++i) if (PHINode *PN = dyn_cast_or_null(PHIs[i].operator Value*())) - RecursivelyDeleteDeadPHINode(PN, VDL); + RecursivelyDeleteDeadPHINode(PN); } /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=70927&r1=70926&r2=70927&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Mon May 4 17:30:44 2009 @@ -178,18 +178,10 @@ return false; } -/// ~ValueDeletionListener - A trivial dtor, defined out of line to give the -/// class a home. -llvm::ValueDeletionListener::~ValueDeletionListener() {} - /// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a /// trivially dead instruction, delete it. If that makes any of its operands /// trivially dead, delete them too, recursively. -/// -/// If a ValueDeletionListener is specified, it is notified of instructions that -/// are actually deleted (before they are actually deleted). -void llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V, - ValueDeletionListener *VDL) { +void llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V) { Instruction *I = dyn_cast(V); if (!I || !I->use_empty() || !isInstructionTriviallyDead(I)) return; @@ -201,10 +193,6 @@ I = DeadInsts.back(); DeadInsts.pop_back(); - // If the client wanted to know, tell it about deleted instructions. - if (VDL) - VDL->ValueWillBeDeleted(I); - // Null out all of the instruction's operands to see if any operand becomes // dead as we go. for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { @@ -230,11 +218,8 @@ /// either forms a cycle or is terminated by a trivially dead instruction, /// delete it. If that makes any of its operands trivially dead, delete them /// too, recursively. -/// -/// If a ValueDeletionListener is specified, it is notified of instructions that -/// are actually deleted (before they are actually deleted). void -llvm::RecursivelyDeleteDeadPHINode(PHINode *PN, ValueDeletionListener *VDL) { +llvm::RecursivelyDeleteDeadPHINode(PHINode *PN) { // We can remove a PHI if it is on a cycle in the def-use graph // where each node in the cycle has degree one, i.e. only one use, @@ -253,7 +238,7 @@ if (!PHIs.insert(cast(JP))) { // Break the cycle and delete the PHI and its operands. JP->replaceAllUsesWith(UndefValue::get(JP->getType())); - RecursivelyDeleteTriviallyDeadInstructions(JP, VDL); + RecursivelyDeleteTriviallyDeadInstructions(JP); break; } } From evan.cheng at apple.com Mon May 4 17:49:18 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 04 May 2009 22:49:18 -0000 Subject: [llvm-commits] [llvm] r70929 - in /llvm/trunk/lib/Target/X86: X86CodeEmitter.cpp X86InstrInfo.cpp Message-ID: <200905042249.n44MnJVH016244@zion.cs.uiuc.edu> Author: evancheng Date: Mon May 4 17:49:16 2009 New Revision: 70929 URL: http://llvm.org/viewvc/llvm-project?rev=70929&view=rev Log: - Avoid the longer SIB encoding on x86_64 when it's not needed. - Synchronize instruction length computation code in X86InstrInfo with code in X86CodeEmitter.cpp Patch by Zoltan Varga. Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=70929&r1=70928&r2=70929&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Mon May 4 17:49:16 2009 @@ -338,8 +338,8 @@ unsigned BaseReg = Base.getReg(); // Is a SIB byte needed? - if ((!Is64BitMode || DispForReloc) && IndexReg.getReg() == 0 && - (BaseReg == 0 || getX86RegNum(BaseReg) != N86::ESP)) { + if (IndexReg.getReg() == 0 && (!Is64BitMode || BaseReg != 0) && + (BaseReg == 0 || getX86RegNum(BaseReg) != N86::ESP)) { if (BaseReg == 0) { // Just a displacement? // Emit special case [disp32] encoding MCE.emitByte(ModRMByte(0, RegOpcodeField, 5)); Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=70929&r1=70928&r2=70929&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon May 4 17:49:16 2009 @@ -2811,8 +2811,8 @@ unsigned BaseReg = Base.getReg(); // Is a SIB byte needed? - if ((!Is64BitMode || DispForReloc) && IndexReg.getReg() == 0 && - (BaseReg == 0 || X86RegisterInfo::getX86RegNum(BaseReg) != N86::ESP)) { + if (IndexReg.getReg() == 0 && (!Is64BitMode || BaseReg != 0) && + (BaseReg == 0 || X86RegisterInfo::getX86RegNum(BaseReg) != N86::ESP)) { if (BaseReg == 0) { // Just a displacement? // Emit special case [disp32] encoding ++FinalSize; @@ -2932,6 +2932,9 @@ unsigned CurOp = 0; if (NumOps > 1 && Desc->getOperandConstraint(1, TOI::TIED_TO) != -1) CurOp++; + else if (NumOps > 2 && Desc->getOperandConstraint(NumOps-1, TOI::TIED_TO)== 0) + // Skip the last source operand that is tied_to the dest reg. e.g. LXADD32 + --NumOps; switch (Desc->TSFlags & X86II::FormMask) { default: assert(0 && "Unknown FormMask value in X86 MachineCodeEmitter!"); @@ -3022,7 +3025,7 @@ case X86II::MRMDestMem: { ++FinalSize; FinalSize += getMemModRMByteSize(MI, CurOp, IsPIC, Is64BitMode); - CurOp += 5; + CurOp += X86AddrNumOperands + 1; if (CurOp != NumOps) { ++CurOp; FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc)); @@ -3041,10 +3044,16 @@ break; case X86II::MRMSrcMem: { + int AddrOperands; + if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r || + Opcode == X86::LEA16r || Opcode == X86::LEA32r) + AddrOperands = X86AddrNumOperands - 1; // No segment register + else + AddrOperands = X86AddrNumOperands; ++FinalSize; FinalSize += getMemModRMByteSize(MI, CurOp+1, IsPIC, Is64BitMode); - CurOp += 5; + CurOp += AddrOperands + 1; if (CurOp != NumOps) { ++CurOp; FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc)); @@ -3057,8 +3066,14 @@ case X86II::MRM4r: case X86II::MRM5r: case X86II::MRM6r: case X86II::MRM7r: ++FinalSize; - ++CurOp; - FinalSize += sizeRegModRMByte(); + // Special handling of lfence and mfence. + if (Desc->getOpcode() == X86::LFENCE || + Desc->getOpcode() == X86::MFENCE) + FinalSize += sizeRegModRMByte(); + else { + ++CurOp; + FinalSize += sizeRegModRMByte(); + } if (CurOp != NumOps) { const MachineOperand &MO1 = MI.getOperand(CurOp++); @@ -3088,7 +3103,7 @@ ++FinalSize; FinalSize += getMemModRMByteSize(MI, CurOp, IsPIC, Is64BitMode); - CurOp += 4; + CurOp += X86AddrNumOperands; if (CurOp != NumOps) { const MachineOperand &MO = MI.getOperand(CurOp++); From evan.cheng at apple.com Mon May 4 18:05:20 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 04 May 2009 23:05:20 -0000 Subject: [llvm-commits] [llvm] r70934 - in /llvm/trunk/tools: llc/llc.cpp lli/lli.cpp Message-ID: <200905042305.n44N5MMS016811@zion.cs.uiuc.edu> Author: evancheng Date: Mon May 4 18:05:19 2009 New Revision: 70934 URL: http://llvm.org/viewvc/llvm-project?rev=70934&view=rev Log: Default llc / lli optimization to "Default", which corresponds to -O1 / -O2. Modified: llvm/trunk/tools/llc/llc.cpp llvm/trunk/tools/lli/lli.cpp Modified: llvm/trunk/tools/llc/llc.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llc/llc.cpp?rev=70934&r1=70933&r2=70934&view=diff ============================================================================== --- llvm/trunk/tools/llc/llc.cpp (original) +++ llvm/trunk/tools/llc/llc.cpp Mon May 4 18:05:19 2009 @@ -55,10 +55,11 @@ static cl::opt Force("f", cl::desc("Overwrite output files")); -// Determine optimization level. Level -O0 is equivalent to "fast" code gen. +// Determine optimization level. static cl::opt OptLevel("O", - cl::desc("Optimization level. [-O0, -O1, -O2, or -O3]"), + cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " + "(default = '-O2')"), cl::Prefix, cl::ZeroOrMore, cl::init(' ')); @@ -253,8 +254,7 @@ raw_ostream *Out = GetOutputStream(argv[0]); if (Out == 0) return 1; - CodeGenOpt::Level OLvl = CodeGenOpt::Aggressive; - + CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { default: std::cerr << argv[0] << ": invalid optimization level.\n"; Modified: llvm/trunk/tools/lli/lli.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=70934&r1=70933&r2=70934&view=diff ============================================================================== --- llvm/trunk/tools/lli/lli.cpp (original) +++ llvm/trunk/tools/lli/lli.cpp Mon May 4 18:05:19 2009 @@ -43,10 +43,14 @@ cl::desc("Force interpretation: disable JIT"), cl::init(false)); - cl::opt Fast("fast", - cl::desc("Generate code quickly, " - "potentially sacrificing code quality"), - cl::init(false)); + // Determine optimization level. + cl::opt + OptLevel("O", + cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " + "(default = '-O2')"), + cl::Prefix, + cl::ZeroOrMore, + cl::init(' ')); cl::opt TargetTriple("mtriple", cl::desc("Override target triple for module")); @@ -122,9 +126,19 @@ if (!TargetTriple.empty()) Mod->setTargetTriple(TargetTriple); - EE = ExecutionEngine::create(MP, ForceInterpreter, &ErrorMsg, - Fast ? - CodeGenOpt::None : CodeGenOpt::Aggressive); + CodeGenOpt::Level OLvl = CodeGenOpt::Default; + switch (OptLevel) { + default: + std::cerr << argv[0] << ": invalid optimization level.\n"; + return 1; + case ' ': break; + case '0': OLvl = CodeGenOpt::None; break; + case '1': + case '2': OLvl = CodeGenOpt::Default; break; + case '3': OLvl = CodeGenOpt::Aggressive; break; + } + + EE = ExecutionEngine::create(MP, ForceInterpreter, &ErrorMsg, OLvl); if (!EE && !ErrorMsg.empty()) { std::cerr << argv[0] << ":error creating EE: " << ErrorMsg << "\n"; exit(1); From evan.cheng at apple.com Mon May 4 18:09:00 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 04 May 2009 23:09:00 -0000 Subject: [llvm-commits] [test-suite] r70935 - /test-suite/trunk/Makefile.programs Message-ID: <200905042309.n44N92tm016931@zion.cs.uiuc.edu> Author: evancheng Date: Mon May 4 18:08:59 2009 New Revision: 70935 URL: http://llvm.org/viewvc/llvm-project?rev=70935&view=rev Log: Run llc / lli with -O3 option to match gcc. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=70935&r1=70934&r2=70935&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Mon May 4 18:08:59 2009 @@ -356,6 +356,11 @@ endif endif +# llc optimization level +ifdef LLC_OPTFLAGS +LLCFLAGS += $(LLC_OPTFLAGS) +endif + # Pass target specific llc flags ifdef TARGET_LLCFLAGS LLCFLAGS += $(TARGET_LLCFLAGS) @@ -431,6 +436,12 @@ LLI_OPTS = -force-interpreter=true --disable-core-files JIT_OPTS = -force-interpreter=false --disable-core-files +# lli optimization level +ifdef LLI_OPTFLAGS +LLI_OPTFLAGS += $(LLI_OPTFLAGS) +JIT_OPTFLAGS += $(LLI_OPTFLAGS) +endif + # Pass target specific lli flags ifdef TARGET_LLIFLAGS LLI_OPTS += $(TARGET_LLIFLAGS) From evan.cheng at apple.com Mon May 4 18:13:13 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 04 May 2009 23:13:13 -0000 Subject: [llvm-commits] [llvm] r70937 - /llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Message-ID: <200905042313.n44NDD4R017147@zion.cs.uiuc.edu> Author: evancheng Date: Mon May 4 18:13:13 2009 New Revision: 70937 URL: http://llvm.org/viewvc/llvm-project?rev=70937&view=rev Log: Do forward and backward substitution to eliminate loads and stores when possible. Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=70937&r1=70936&r2=70937&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Mon May 4 18:13:13 2009 @@ -45,8 +45,10 @@ static cl::opt DCELimit("ssc-dce-limit", cl::init(-1), cl::Hidden); STATISTIC(NumEliminated, "Number of stack slots eliminated due to coloring"); -STATISTIC(NumDead, "Number of trivially dead stack accesses eliminated"); STATISTIC(NumRegRepl, "Number of stack slot refs replaced with reg refs"); +STATISTIC(NumLoadElim, "Number of load eliminated"); +STATISTIC(NumStoreElim, "Number of stores eliminated"); +STATISTIC(NumDead, "Number of trivially dead stack accesses eliminated"); namespace { class VISIBILITY_HIDDEN StackSlotColoring : public MachineFunctionPass { @@ -115,8 +117,15 @@ BitVector &SlotIsReg); void RewriteInstruction(MachineInstr *MI, int OldFI, int NewFI, MachineFunction &MF); + bool PropagateBackward(MachineBasicBlock::iterator MII, + MachineBasicBlock *MBB, + unsigned OldReg, unsigned NewReg); + bool PropagateForward(MachineBasicBlock::iterator MII, + MachineBasicBlock *MBB, + unsigned OldReg, unsigned NewReg); void UnfoldAndRewriteInstruction(MachineInstr *MI, int OldFI, - unsigned Reg, MachineFunction &MF); + unsigned Reg, const TargetRegisterClass *RC, + MachineFunction &MF); bool AllMemRefsCanBeUnfolded(int SS); bool RemoveDeadStores(MachineBasicBlock* MBB); }; @@ -384,11 +393,13 @@ SmallVector &RefMIs = SSRefs[SS]; for (unsigned i = 0, e = RefMIs.size(); i != e; ++i) - if (isReg) - // Rewrite to use a register instead. - UnfoldAndRewriteInstruction(RefMIs[i], SS, NewFI, MF); - else + if (!isReg) RewriteInstruction(RefMIs[i], SS, NewFI, MF); + else { + // Rewrite to use a register instead. + const TargetRegisterClass *RC = LS->getIntervalRegClass(SS); + UnfoldAndRewriteInstruction(RefMIs[i], SS, NewFI, RC, MF); + } } // Delete unused stack slots. @@ -407,6 +418,10 @@ SmallVector &RefMIs = SSRefs[SS]; for (unsigned i = 0, e = RefMIs.size(); i != e; ++i) { MachineInstr *MI = RefMIs[i]; + if (TII->isLoadFromStackSlot(MI, SS) || + TII->isStoreToStackSlot(MI, SS)) + // Restore and spill will become copies. + return true; if (!TII->getOpcodeAfterMemoryUnfold(MI->getOpcode(), false, false)) return false; for (unsigned j = 0, ee = MI->getNumOperands(); j != ee; ++j) { @@ -451,19 +466,118 @@ } } +/// PropagateBackward - Traverse backward and look for the definition of +/// OldReg. If it can successfully update all of the references with NewReg, +/// do so and return true. +bool StackSlotColoring::PropagateBackward(MachineBasicBlock::iterator MII, + MachineBasicBlock *MBB, + unsigned OldReg, unsigned NewReg) { + SmallVector Refs; + while (--MII != MBB->begin()) { + bool FoundDef = false; // Not counting 2address def. + bool FoundUse = false; + bool FoundKill = false; + for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MII->getOperand(i); + if (!MO.isReg()) + continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) + continue; + if (Reg == OldReg) { + if (MO.isUse()) { + FoundUse = true; + if (MO.isKill()) + FoundKill = true; + Refs.push_back(&MO); + } else { + Refs.push_back(&MO); + if (!MII->isRegTiedToUseOperand(i)) + FoundDef = true; + } + } else if (TRI->regsOverlap(Reg, NewReg)) { + return false; + } else if (TRI->regsOverlap(Reg, OldReg)) { + if (!MO.isUse() || !MO.isKill()) + return false; + } + } + if (FoundDef) { + for (unsigned i = 0, e = Refs.size(); i != e; ++i) + Refs[i]->setReg(NewReg); + return true; + } + } + return false; +} + +/// PropagateForward - Traverse forward and look for the kill of OldReg. If +/// it can successfully update all of the uses with NewReg, do so and +/// return true. +bool StackSlotColoring::PropagateForward(MachineBasicBlock::iterator MII, + MachineBasicBlock *MBB, + unsigned OldReg, unsigned NewReg) { + SmallVector Uses; + while (++MII != MBB->end()) { + bool FoundUse = false; + bool FoundKill = false; + for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MII->getOperand(i); + if (!MO.isReg()) + continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) + continue; + if (Reg == OldReg) { + if (MO.isDef()) + return false; + FoundUse = true; + if (MO.isKill()) + FoundKill = true; + Uses.push_back(&MO); + } else if (TRI->regsOverlap(Reg, NewReg) || + TRI->regsOverlap(Reg, OldReg)) + return false; + } + if (FoundKill) { + for (unsigned i = 0, e = Uses.size(); i != e; ++i) + Uses[i]->setReg(NewReg); + return true; + } + } + return false; +} + /// UnfoldAndRewriteInstruction - Rewrite specified instruction by unfolding /// folded memory references and replacing those references with register /// references instead. void StackSlotColoring::UnfoldAndRewriteInstruction(MachineInstr *MI, int OldFI, - unsigned Reg, - MachineFunction &MF) { + unsigned Reg, + const TargetRegisterClass *RC, + MachineFunction &MF) { MachineBasicBlock *MBB = MI->getParent(); - SmallVector NewMIs; - bool Success = TII->unfoldMemoryOperand(MF, MI, Reg, false, false, NewMIs); - assert(Success && "Failed to unfold!"); - MBB->insert(MI, NewMIs[0]); + if (unsigned DstReg = TII->isLoadFromStackSlot(MI, OldFI)) { + if (PropagateForward(MI, MBB, DstReg, Reg)) { + ++NumLoadElim; + } else { + TII->copyRegToReg(*MBB, MI, DstReg, Reg, RC, RC); + ++NumRegRepl; + } + } else if (unsigned SrcReg = TII->isStoreToStackSlot(MI, OldFI)) { + if (MI->killsRegister(SrcReg) && PropagateBackward(MI, MBB, SrcReg, Reg)) { + ++NumStoreElim; + } else { + TII->copyRegToReg(*MBB, MI, Reg, SrcReg, RC, RC); + ++NumRegRepl; + } + } else { + SmallVector NewMIs; + bool Success = TII->unfoldMemoryOperand(MF, MI, Reg, false, false, NewMIs); + assert(Success && "Failed to unfold!"); + MBB->insert(MI, NewMIs[0]); + ++NumRegRepl; + } MBB->erase(MI); - ++NumRegRepl; } /// RemoveDeadStores - Scan through a basic block and look for loads followed From kremenek at apple.com Mon May 4 19:03:51 2009 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 05 May 2009 00:03:51 -0000 Subject: [llvm-commits] [llvm] r70944 - /llvm/tags/checker/checker-0.194/ Message-ID: <200905050003.n4503pbK018980@zion.cs.uiuc.edu> Author: kremenek Date: Mon May 4 19:03:51 2009 New Revision: 70944 URL: http://llvm.org/viewvc/llvm-project?rev=70944&view=rev Log: Tagging checker-0.194. Added: llvm/tags/checker/checker-0.194/ - copied from r70943, llvm/trunk/ From evan.cheng at apple.com Mon May 4 19:30:10 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 05 May 2009 00:30:10 -0000 Subject: [llvm-commits] [llvm] r70950 - in /llvm/trunk: include/llvm/Target/TargetInstrInfo.h lib/CodeGen/PostRASchedulerList.cpp lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp lib/Target/TargetInstrInfo.cpp Message-ID: <200905050030.n450UASi019913@zion.cs.uiuc.edu> Author: evancheng Date: Mon May 4 19:30:09 2009 New Revision: 70950 URL: http://llvm.org/viewvc/llvm-project?rev=70950&view=rev Log: Move getInstrOperandRegClass from the scheduler to TargetInstrInfo. Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp llvm/trunk/lib/Target/TargetInstrInfo.cpp Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=70950&r1=70949&r2=70950&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Mon May 4 19:30:09 2009 @@ -20,6 +20,7 @@ namespace llvm { class TargetRegisterClass; +class TargetRegisterInfo; class LiveVariables; class CalleeSavedInfo; class SDNode; @@ -505,6 +506,12 @@ virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const; }; +/// getInstrOperandRegClass - Return register class of the operand of an +/// instruction of the specified TargetInstrDesc. +const TargetRegisterClass* +getInstrOperandRegClass(const TargetRegisterInfo *TRI, + const TargetInstrDesc &II, unsigned Op); + } // End llvm namespace #endif Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=70950&r1=70949&r2=70950&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon May 4 19:30:09 2009 @@ -418,18 +418,6 @@ ScheduleDAGInstrs::FinishBlock(); } -/// getInstrOperandRegClass - Return register class of the operand of an -/// instruction of the specified TargetInstrDesc. -static const TargetRegisterClass* -getInstrOperandRegClass(const TargetRegisterInfo *TRI, - const TargetInstrDesc &II, unsigned Op) { - if (Op >= II.getNumOperands()) - return NULL; - if (II.OpInfo[Op].isLookupPtrRegClass()) - return TRI->getPointerRegClass(); - return TRI->getRegClass(II.OpInfo[Op].RegClass); -} - /// CriticalPathStep - Return the next SUnit after SU on the bottom-up /// critical path. static SDep *CriticalPathStep(SUnit *SU) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp?rev=70950&r1=70949&r2=70950&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp Mon May 4 19:30:09 2009 @@ -28,20 +28,6 @@ #include "llvm/Support/MathExtras.h" using namespace llvm; -/// getInstrOperandRegClass - Return register class of the operand of an -/// instruction of the specified TargetInstrDesc. -static const TargetRegisterClass* -getInstrOperandRegClass(const TargetRegisterInfo *TRI, - const TargetInstrDesc &II, unsigned Op) { - if (Op >= II.getNumOperands()) { - assert(II.isVariadic() && "Invalid operand # of instruction"); - return NULL; - } - if (II.OpInfo[Op].isLookupPtrRegClass()) - return TRI->getPointerRegClass(); - return TRI->getRegClass(II.OpInfo[Op].RegClass); -} - /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an /// implicit physical register output. void ScheduleDAGSDNodes::EmitCopyFromReg(SDNode *Node, unsigned ResNo, Modified: llvm/trunk/lib/Target/TargetInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetInstrInfo.cpp?rev=70950&r1=70949&r2=70950&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/TargetInstrInfo.cpp Mon May 4 19:30:09 2009 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Constant.h" #include "llvm/DerivedTypes.h" using namespace llvm; @@ -35,3 +36,15 @@ return true; return !isPredicated(MI); } + +/// getInstrOperandRegClass - Return register class of the operand of an +/// instruction of the specified TargetInstrDesc. +const TargetRegisterClass* +llvm::getInstrOperandRegClass(const TargetRegisterInfo *TRI, + const TargetInstrDesc &II, unsigned Op) { + if (Op >= II.getNumOperands()) + return NULL; + if (II.OpInfo[Op].isLookupPtrRegClass()) + return TRI->getPointerRegClass(); + return TRI->getRegClass(II.OpInfo[Op].RegClass); +} From evan.cheng at apple.com Mon May 4 19:46:17 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 05 May 2009 00:46:17 -0000 Subject: [llvm-commits] [llvm] r70953 - /llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Message-ID: <200905050046.n450kHUD020653@zion.cs.uiuc.edu> Author: evancheng Date: Mon May 4 19:46:16 2009 New Revision: 70953 URL: http://llvm.org/viewvc/llvm-project?rev=70953&view=rev Log: Do not substitute if the new register isn't in the register class of the operand being updated. Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=70953&r1=70952&r2=70953&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Mon May 4 19:46:16 2009 @@ -477,6 +477,7 @@ bool FoundDef = false; // Not counting 2address def. bool FoundUse = false; bool FoundKill = false; + const TargetInstrDesc &TID = MII->getDesc(); for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) { MachineOperand &MO = MII->getOperand(i); if (!MO.isReg()) @@ -485,6 +486,10 @@ if (Reg == 0) continue; if (Reg == OldReg) { + const TargetRegisterClass *RC = getInstrOperandRegClass(TRI, TID, i); + if (RC && !RC->contains(NewReg)) + return false; + if (MO.isUse()) { FoundUse = true; if (MO.isKill()) @@ -521,6 +526,7 @@ while (++MII != MBB->end()) { bool FoundUse = false; bool FoundKill = false; + const TargetInstrDesc &TID = MII->getDesc(); for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) { MachineOperand &MO = MII->getOperand(i); if (!MO.isReg()) @@ -531,6 +537,10 @@ if (Reg == OldReg) { if (MO.isDef()) return false; + + const TargetRegisterClass *RC = getInstrOperandRegClass(TRI, TID, i); + if (RC && !RC->contains(NewReg)) + return false; FoundUse = true; if (MO.isKill()) FoundKill = true; @@ -558,6 +568,8 @@ MachineBasicBlock *MBB = MI->getParent(); if (unsigned DstReg = TII->isLoadFromStackSlot(MI, OldFI)) { if (PropagateForward(MI, MBB, DstReg, Reg)) { + DOUT << "Eliminated load: "; + DEBUG(MI->dump()); ++NumLoadElim; } else { TII->copyRegToReg(*MBB, MI, DstReg, Reg, RC, RC); @@ -565,6 +577,8 @@ } } else if (unsigned SrcReg = TII->isStoreToStackSlot(MI, OldFI)) { if (MI->killsRegister(SrcReg) && PropagateBackward(MI, MBB, SrcReg, Reg)) { + DOUT << "Eliminated store: "; + DEBUG(MI->dump()); ++NumStoreElim; } else { TII->copyRegToReg(*MBB, MI, Reg, SrcReg, RC, RC); From sabre at nondot.org Mon May 4 23:55:57 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 05 May 2009 04:55:57 -0000 Subject: [llvm-commits] [llvm] r70964 - in /llvm/trunk/lib: Analysis/DebugInfo.cpp CodeGen/AsmPrinter/DwarfWriter.cpp Message-ID: <200905050455.n454tvkQ028360@zion.cs.uiuc.edu> Author: lattner Date: Mon May 4 23:55:56 2009 New Revision: 70964 URL: http://llvm.org/viewvc/llvm-project?rev=70964&view=rev Log: Do not require variable debug info nodes to have a compile unit. For implicit decls like "self" and "_cmd" in ObjC, these decls should not have a location. Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=70964&r1=70963&r2=70964&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Mon May 4 23:55:56 2009 @@ -295,7 +295,7 @@ return false; DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) + if (!CU.isNull() && !CU.Verify()) return false; DIType Ty = getType(); @@ -320,7 +320,6 @@ if (!Ty.Verify()) return false; - return true; } Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=70964&r1=70963&r2=70964&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Mon May 4 23:55:56 2009 @@ -1524,11 +1524,13 @@ /// AddSourceLine - Add location information to specified debug information /// entry. void AddSourceLine(DIE *Die, const DIVariable *V) { - unsigned FileID = 0; + // If there is no compile unit specified, don't add a line #. + if (V->getCompileUnit().isNull()) + return; + unsigned Line = V->getLineNumber(); - CompileUnit *Unit = FindCompileUnit(V->getCompileUnit()); - FileID = Unit->getID(); - assert (FileID && "Invalid file id"); + unsigned FileID = FindCompileUnit(V->getCompileUnit()).getID(); + assert(FileID && "Invalid file id"); AddUInt(Die, DW_AT_decl_file, 0, FileID); AddUInt(Die, DW_AT_decl_line, 0, Line); } @@ -1536,24 +1538,25 @@ /// AddSourceLine - Add location information to specified debug information /// entry. void AddSourceLine(DIE *Die, const DIGlobal *G) { - unsigned FileID = 0; + // If there is no compile unit specified, don't add a line #. + if (G->getCompileUnit().isNull()) + return; unsigned Line = G->getLineNumber(); - CompileUnit *Unit = FindCompileUnit(G->getCompileUnit()); - FileID = Unit->getID(); - assert (FileID && "Invalid file id"); + unsigned FileID = FindCompileUnit(G->getCompileUnit()).getID(); + assert(FileID && "Invalid file id"); AddUInt(Die, DW_AT_decl_file, 0, FileID); AddUInt(Die, DW_AT_decl_line, 0, Line); } void AddSourceLine(DIE *Die, const DIType *Ty) { - unsigned FileID = 0; - unsigned Line = Ty->getLineNumber(); + // If there is no compile unit specified, don't add a line #. DICompileUnit CU = Ty->getCompileUnit(); if (CU.isNull()) return; - CompileUnit *Unit = FindCompileUnit(CU); - FileID = Unit->getID(); - assert (FileID && "Invalid file id"); + + unsigned Line = Ty->getLineNumber(); + unsigned FileID = FindCompileUnit(CU).getID(); + assert(FileID && "Invalid file id"); AddUInt(Die, DW_AT_decl_file, 0, FileID); AddUInt(Die, DW_AT_decl_line, 0, Line); } @@ -1953,10 +1956,11 @@ /// FindCompileUnit - Get the compile unit for the given descriptor. /// - CompileUnit *FindCompileUnit(DICompileUnit Unit) { - CompileUnit *DW_Unit = CompileUnitMap[Unit.getGV()]; - assert(DW_Unit && "Missing compile unit."); - return DW_Unit; + CompileUnit &FindCompileUnit(DICompileUnit Unit) const { + DenseMap::const_iterator I = + CompileUnitMap.find(Unit.getGV()); + assert(I != CompileUnitMap.end() && "Missing compile unit."); + return *I->second; } /// NewDbgScopeVariable - Create a new scope variable. @@ -2118,7 +2122,7 @@ // Get the compile unit context. CompileUnit *Unit = MainCU; if (!Unit) - Unit = FindCompileUnit(SPD.getCompileUnit()); + Unit = &FindCompileUnit(SPD.getCompileUnit()); // Get the subprogram die. DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV()); @@ -2984,7 +2988,7 @@ DIGlobalVariable DI_GV(GV); CompileUnit *DW_Unit = MainCU; if (!DW_Unit) - DW_Unit = FindCompileUnit(DI_GV.getCompileUnit()); + DW_Unit = &FindCompileUnit(DI_GV.getCompileUnit()); // Check for pre-existence. DIE *&Slot = DW_Unit->getDieMapSlotFor(DI_GV.getGV()); @@ -3040,7 +3044,7 @@ DISubprogram SP(GV); CompileUnit *Unit = MainCU; if (!Unit) - Unit = FindCompileUnit(SP.getCompileUnit()); + Unit = &FindCompileUnit(SP.getCompileUnit()); // Check for pre-existence. DIE *&Slot = Unit->getDieMapSlotFor(GV); From sabre at nondot.org Tue May 5 00:10:00 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 05 May 2009 05:10:00 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r70968 - /llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Message-ID: <200905050510.n455A0sq028820@zion.cs.uiuc.edu> Author: lattner Date: Tue May 5 00:10:00 2009 New Revision: 70968 URL: http://llvm.org/viewvc/llvm-project?rev=70968&view=rev Log: Fix rdar://6856261 - llvm-gcc generates incorrect (and unnecessary) file and line info for DW_TAG_inheritance dies. A location with a line # of 0 is not valid, and this isn't useful anyway. Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=70968&r1=70967&r2=70968&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Tue May 5 00:10:00 2009 @@ -607,9 +607,8 @@ // FIXME : name, size, align etc... DIType DTy = DebugFactory.CreateDerivedType(DW_TAG_inheritance, - findRegion(type),"", - getOrCreateCompileUnit(Loc.file), - 0,0,0, + findRegion(type), "", + llvm::DICompileUnit(), 0,0,0, getINTEGER_CSTVal(BINFO_OFFSET(BInfo)), 0, BaseClass); EltTys.push_back(DTy); From foldr at codedgers.com Tue May 5 07:34:39 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Tue, 05 May 2009 12:34:39 -0000 Subject: [llvm-commits] [llvm] r70973 - in /llvm/trunk: test/LLVMC/EnvParentheses.td utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200905051234.n45CYf8P022127@zion.cs.uiuc.edu> Author: foldr Date: Tue May 5 07:34:34 2009 New Revision: 70973 URL: http://llvm.org/viewvc/llvm-project?rev=70973&view=rev Log: Fix incorrect code generation with ENV. See PR4157 for details. Patch by Martin Nowack! Added: llvm/trunk/test/LLVMC/EnvParentheses.td Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Added: llvm/trunk/test/LLVMC/EnvParentheses.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/EnvParentheses.td?rev=70973&view=auto ============================================================================== --- llvm/trunk/test/LLVMC/EnvParentheses.td (added) +++ llvm/trunk/test/LLVMC/EnvParentheses.td Tue May 5 07:34:34 2009 @@ -0,0 +1,16 @@ +// Check the fix for PR4157. +// http://llvm.org/bugs/show_bug.cgi?id=4157 +// RUN: tblgen -I $srcroot/include --gen-llvmc %s -o %t +// RUN: not grep {)));} %t + +include "llvm/CompilerDriver/Common.td" + +def dummy_tool : Tool<[ +(cmd_line "gcc -o $OUTFILE $INFILE $ENV(FOO)/bar"), +(in_language "dummy"), +(out_language "dummy") +]>; + +def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; + +def Graph : CompilationGraph<[]>; Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=70973&r1=70972&r2=70973&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Tue May 5 07:34:34 2009 @@ -1265,7 +1265,6 @@ assert(Leftover.at(0) == ')'); if (Leftover.size() != 1) O << " + std::string(\"" << (Leftover.c_str() + 1) << "\")"; - O << ')'; return Pos; } From greened at obbligato.org Tue May 5 11:28:28 2009 From: greened at obbligato.org (David Greene) Date: Tue, 05 May 2009 16:28:28 -0000 Subject: [llvm-commits] [llvm] r70979 - in /llvm/trunk: test/TableGen/MultiClassDefName.td utils/TableGen/TGLexer.cpp utils/TableGen/TGParser.cpp Message-ID: <200905051628.n45GSVga031801@zion.cs.uiuc.edu> Author: greened Date: Tue May 5 11:28:25 2009 New Revision: 70979 URL: http://llvm.org/viewvc/llvm-project?rev=70979&view=rev Log: Allow multiclass def names to contain "#NAME"" where TableGen replaces #NAME# with the name of the defm instantiating the multiclass. This is useful for AVX instruction naming where a "V" prefix is standard throughout the ISA. For example: multiclass SSE_AVX_Inst<...> { def SS : Instr<...>; def SD : Instr<...>; def PS : Instr<...>; def PD : Instr<...>; def V#NAME#SS : Instr<...>; def V#NAME#SD : Instr<...>; def V#NAME#PS : Instr<...>; def V#NAME#PD : Instr<...>; } defm ADD : SSE_AVX_Inst<...>; Results in ADDSS ADDSD ADDPS ADDPD VADDSS VADDSD VADDPS VADDPD Added: llvm/trunk/test/TableGen/MultiClassDefName.td Modified: llvm/trunk/utils/TableGen/TGLexer.cpp llvm/trunk/utils/TableGen/TGParser.cpp Added: llvm/trunk/test/TableGen/MultiClassDefName.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/MultiClassDefName.td?rev=70979&view=auto ============================================================================== --- llvm/trunk/test/TableGen/MultiClassDefName.td (added) +++ llvm/trunk/test/TableGen/MultiClassDefName.td Tue May 5 11:28:25 2009 @@ -0,0 +1,12 @@ +// RUN: tblgen %s | grep WorldHelloCC | count 1 + +class C { + string name = n; +} + +multiclass Names { + def CC : C; + def World#NAME#CC : C; +} + +defm Hello : Names<"hello", "world">; Modified: llvm/trunk/utils/TableGen/TGLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=70979&r1=70978&r2=70979&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGLexer.cpp (original) +++ llvm/trunk/utils/TableGen/TGLexer.cpp Tue May 5 11:28:25 2009 @@ -98,7 +98,7 @@ switch (CurChar) { default: // Handle letters: [a-zA-Z_] - if (isalpha(CurChar) || CurChar == '_') + if (isalpha(CurChar) || CurChar == '_' || CurChar == '#') return LexIdentifier(); // Unknown character, emit an error. @@ -220,8 +220,20 @@ const char *IdentStart = TokStart; // Match the rest of the identifier regex: [0-9a-zA-Z_]* - while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_') - ++CurPtr; + while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_' + || *CurPtr == '#') { + // If this contains a '#', make sure it's value + if (*CurPtr == '#') { + if (strncmp(CurPtr, "#NAME#", 6) != 0) { + return tgtok::Error; + } + CurPtr += 6; + } + else { + ++CurPtr; + } + } + // Check to see if this identifier is a keyword. unsigned Len = CurPtr-IdentStart; Modified: llvm/trunk/utils/TableGen/TGParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.cpp?rev=70979&r1=70978&r2=70979&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGParser.cpp (original) +++ llvm/trunk/utils/TableGen/TGParser.cpp Tue May 5 11:28:25 2009 @@ -1609,9 +1609,18 @@ for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) { Record *DefProto = MC->DefPrototypes[i]; - // Add the suffix to the defm name to get the new name. - Record *CurRec = new Record(DefmPrefix + DefProto->getName(), - DefmPrefixLoc); + // Add in the defm name + std::string DefName = DefProto->getName(); + std::string::size_type idx = DefName.find("#NAME#"); + if (idx != std::string::npos) { + DefName.replace(idx, 6, DefmPrefix); + } + else { + // Add the suffix to the defm name to get the new name. + DefName = DefmPrefix + DefName; + } + + Record *CurRec = new Record(DefName, DefmPrefixLoc); SubClassReference Ref; Ref.RefLoc = DefmPrefixLoc; From evan.cheng at apple.com Tue May 5 13:19:15 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 05 May 2009 18:19:15 -0000 Subject: [llvm-commits] [llvm] r70986 - in /llvm/trunk/lib/Target/X86: X86CodeEmitter.cpp X86InstrInfo.cpp Message-ID: <200905051819.n45IJmNt004227@zion.cs.uiuc.edu> Author: evancheng Date: Tue May 5 13:18:57 2009 New Revision: 70986 URL: http://llvm.org/viewvc/llvm-project?rev=70986&view=rev Log: Revert part of 70929 that has to do with determining whether a SIB byte is needed. It causes a lot of x86_64 JIT failures. Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=70986&r1=70985&r2=70986&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Tue May 5 13:18:57 2009 @@ -338,8 +338,8 @@ unsigned BaseReg = Base.getReg(); // Is a SIB byte needed? - if (IndexReg.getReg() == 0 && (!Is64BitMode || BaseReg != 0) && - (BaseReg == 0 || getX86RegNum(BaseReg) != N86::ESP)) { + if ((!Is64BitMode || DispForReloc) && IndexReg.getReg() == 0 && + (BaseReg == 0 || getX86RegNum(BaseReg) != N86::ESP)) { if (BaseReg == 0) { // Just a displacement? // Emit special case [disp32] encoding MCE.emitByte(ModRMByte(0, RegOpcodeField, 5)); Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=70986&r1=70985&r2=70986&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Tue May 5 13:18:57 2009 @@ -2811,7 +2811,7 @@ unsigned BaseReg = Base.getReg(); // Is a SIB byte needed? - if (IndexReg.getReg() == 0 && (!Is64BitMode || BaseReg != 0) && + if ((!Is64BitMode || DispForReloc) && IndexReg.getReg() == 0 && (BaseReg == 0 || X86RegisterInfo::getX86RegNum(BaseReg) != N86::ESP)) { if (BaseReg == 0) { // Just a displacement? // Emit special case [disp32] encoding From evan.cheng at apple.com Tue May 5 13:35:38 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 05 May 2009 18:35:38 -0000 Subject: [llvm-commits] [llvm] r70988 - /llvm/trunk/tools/bugpoint/ToolRunner.cpp Message-ID: <200905051835.n45IZckI004805@zion.cs.uiuc.edu> Author: evancheng Date: Tue May 5 13:35:36 2009 New Revision: 70988 URL: http://llvm.org/viewvc/llvm-project?rev=70988&view=rev Log: bugpoint for jit should just ignore GCC arguments. Modified: llvm/trunk/tools/bugpoint/ToolRunner.cpp Modified: llvm/trunk/tools/bugpoint/ToolRunner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ToolRunner.cpp?rev=70988&r1=70987&r2=70988&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/ToolRunner.cpp (original) +++ llvm/trunk/tools/bugpoint/ToolRunner.cpp Tue May 5 13:35:36 2009 @@ -140,9 +140,6 @@ throw ToolExecutionError("LLI currently does not support " "loading shared libraries."); - if (!GCCArgs.empty()) - throw ToolExecutionError("LLI currently does not support " - "GCC Arguments."); std::vector LLIArgs; LLIArgs.push_back(LLIPath.c_str()); LLIArgs.push_back("-force-interpreter=true"); @@ -409,8 +406,6 @@ const std::vector &SharedLibs, unsigned Timeout, unsigned MemoryLimit) { - if (!GCCArgs.empty()) - throw ToolExecutionError("JIT does not support GCC Arguments."); // Construct a vector of parameters, incorporating those from the command-line std::vector JITArgs; JITArgs.push_back(LLIPath.c_str()); From sabre at nondot.org Tue May 5 13:52:36 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 05 May 2009 18:52:36 -0000 Subject: [llvm-commits] [llvm] r70992 - in /llvm/trunk: docs/CodeGenerator.html lib/Target/X86/X86Instr64bit.td lib/Target/X86/X86InstrInfo.td test/CodeGen/X86/movfs.ll Message-ID: <200905051852.n45IqjqG005662@zion.cs.uiuc.edu> Author: lattner Date: Tue May 5 13:52:19 2009 New Revision: 70992 URL: http://llvm.org/viewvc/llvm-project?rev=70992&view=rev Log: Add basic support for code generation of addrspace(257) -> FS relative on x86. Patch by Zoltan Varga! Added: llvm/trunk/test/CodeGen/X86/movfs.ll Modified: llvm/trunk/docs/CodeGenerator.html llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/docs/CodeGenerator.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodeGenerator.html?rev=70992&r1=70991&r2=70992&view=diff ============================================================================== --- llvm/trunk/docs/CodeGenerator.html (original) +++ llvm/trunk/docs/CodeGenerator.html Tue May 5 13:52:19 2009 @@ -1844,11 +1844,13 @@ segment. LLVM address space 0 is the default address space, which includes the stack, and any unqualified memory accesses in a program. Address spaces 1-255 are currently reserved for user-defined code. The GS-segment is - represented by address space 256. Other x86 segments have yet to be - allocated address space numbers.

- -

Some operating systems use the GS-segment to implement TLS, so care should be - taken when reading and writing to address space 256 on these platforms.

+ represented by address space 256, while the FS-segment is represented by + address space 257. Other x86 segments have yet to be allocated address space + numbers.

+ +

Some operating systems use the FS/GS-segment to implement TLS, so care + should be taken when reading and writing to address space 256/257 on these + platforms.

Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=70992&r1=70991&r2=70992&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Tue May 5 13:52:19 2009 @@ -1326,6 +1326,11 @@ "movq\t%gs:$src, $dst", [(set GR64:$dst, (gsload addr:$src))]>, SegGS; +let AddedComplexity = 5 in +def MOV64FSrm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), + "movq\t%fs:$src, $dst", + [(set GR64:$dst, (fsload addr:$src))]>, SegFS; + //===----------------------------------------------------------------------===// // Atomic Instructions //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=70992&r1=70991&r2=70992&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Tue May 5 13:52:19 2009 @@ -345,6 +345,13 @@ return false; }]>; +def fsload : PatFrag<(ops node:$ptr), (load node:$ptr), [{ + if (const Value *Src = cast(N)->getSrcValue()) + if (const PointerType *PT = dyn_cast(Src->getType())) + return PT->getAddressSpace() == 257; + return false; +}]>; + def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr)), [{ if (const Value *Src = cast(N)->getSrcValue()) if (const PointerType *PT = dyn_cast(Src->getType())) @@ -3004,6 +3011,11 @@ "movl\t%gs:$src, $dst", [(set GR32:$dst, (gsload addr:$src))]>, SegGS; +let AddedComplexity = 5 in +def FS_MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), + "movl\t%fs:$src, $dst", + [(set GR32:$dst, (fsload addr:$src))]>, SegFS; + //===----------------------------------------------------------------------===// // DWARF Pseudo Instructions // Added: llvm/trunk/test/CodeGen/X86/movfs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/movfs.ll?rev=70992&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/movfs.ll (added) +++ llvm/trunk/test/CodeGen/X86/movfs.ll Tue May 5 13:52:19 2009 @@ -0,0 +1,8 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep fs + +define i32 @foo() nounwind readonly { +entry: + %tmp = load i32* addrspace(257)* getelementptr (i32* addrspace(257)* inttoptr (i32 72 to i32* addrspace(257)*), i32 31) ; [#uses=1] + %tmp1 = load i32* %tmp ; [#uses=1] + ret i32 %tmp1 +} From wendling at apple.com Tue May 5 15:44:44 2009 From: wendling at apple.com (Bill Wendling) Date: Tue, 5 May 2009 13:44:44 -0700 Subject: [llvm-commits] [llvm-testresults] buildbot failure in The LLVM Compiler Infrastructure on full-llvm-OSX In-Reply-To: <20090505203815.0C25128050@relay13.apple.com> References: <20090505203815.0C25128050@relay13.apple.com> Message-ID: David, Your recent check-in r71008 is causing this failure. Please investigate: Running /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ CodeGen/X86/dg.exp ... FAIL: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ CodeGen/X86/change-compare-stride-1.ll Failed with exit(1) at line 2 while running: grep {cmpq $-478,} change-compare-stride-1.ll.tmp child process exited abnormally -bw On May 5, 2009, at 1:39 PM, buildbot at apple.com wrote: > The Buildbot has detected a new failure of full-llvm-OSX on The LLVM > Compiler Infrastructure. > Full details are available at: > http://blamebot.apple.com:80/builders/full-llvm-OSX/builds/1571 > > Buildbot URL: http://blamebot.apple.com:80/ > > Buildslave for this Build: blamebot > > Build Reason: > Build Source Stamp: HEAD > Blamelist: greened > > BUILD FAILED: failed shell > > sincerely, > -The Buildbot > > _______________________________________________ > llvm-testresults mailing list > llvm-testresults at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-testresults From isanbard at gmail.com Tue May 5 17:19:26 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 05 May 2009 22:19:26 -0000 Subject: [llvm-commits] [llvm] r71028 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h lib/Analysis/DebugInfo.cpp Message-ID: <200905052219.n45MJRDr013409@zion.cs.uiuc.edu> Author: void Date: Tue May 5 17:19:25 2009 New Revision: 71028 URL: http://llvm.org/viewvc/llvm-project?rev=71028&view=rev Log: Add dump method to DIDescriptor. Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/lib/Analysis/DebugInfo.cpp Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=71028&r1=71027&r2=71028&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Tue May 5 17:19:25 2009 @@ -74,6 +74,8 @@ /// ValidDebugInfo - Return true if V represents valid debug info value. static bool ValidDebugInfo(Value *V, CodeGenOpt::Level OptLevel); + /// dump - print descriptor. + void dump() const; }; /// DIAnchor - A wrapper for various anchor descriptors. Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=71028&r1=71027&r2=71028&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Tue May 5 17:19:25 2009 @@ -981,6 +981,11 @@ } } +/// dump - print descriptor. +void DIDescriptor::dump() const { + cerr << " [" << dwarf::TagString(getTag()) << "]\n"; +} + /// dump - print compile unit. void DICompileUnit::dump() const { if (getLanguage()) @@ -1035,7 +1040,6 @@ /// dump - print basic type. void DIBasicType::dump() const { cerr << " [" << dwarf::AttributeEncodingString(getEncoding()) << "] "; - } /// dump - print derived type. From gohman at apple.com Tue May 5 16:23:41 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 05 May 2009 21:23:41 -0000 Subject: [llvm-commits] [llvm] r71022 - /llvm/trunk/include/llvm/Support/ValueHandle.h Message-ID: <200905052123.n45LNoM6011216@zion.cs.uiuc.edu> Author: djg Date: Tue May 5 16:23:20 2009 New Revision: 71022 URL: http://llvm.org/viewvc/llvm-project?rev=71022&view=rev Log: Add an explicit keyword. Modified: llvm/trunk/include/llvm/Support/ValueHandle.h Modified: llvm/trunk/include/llvm/Support/ValueHandle.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ValueHandle.h?rev=71022&r1=71021&r2=71022&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/ValueHandle.h (original) +++ llvm/trunk/include/llvm/Support/ValueHandle.h Tue May 5 16:23:20 2009 @@ -53,7 +53,8 @@ ValueHandleBase *Next; Value *VP; public: - ValueHandleBase(HandleBaseKind Kind) : PrevPair(0, Kind), Next(0), VP(0) {} + explicit ValueHandleBase(HandleBaseKind Kind) + : PrevPair(0, Kind), Next(0), VP(0) {} ValueHandleBase(HandleBaseKind Kind, Value *V) : PrevPair(0, Kind), Next(0), VP(V) { if (V) From evan.cheng at apple.com Tue May 5 15:54:49 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 05 May 2009 20:54:49 -0000 Subject: [llvm-commits] [llvm] r71014 - /llvm/trunk/include/llvm/CodeGen/Passes.h Message-ID: <200905052054.n45Kss11010226@zion.cs.uiuc.edu> Author: evancheng Date: Tue May 5 15:54:11 2009 New Revision: 71014 URL: http://llvm.org/viewvc/llvm-project?rev=71014&view=rev Log: Forgot this in the last commit. Modified: llvm/trunk/include/llvm/CodeGen/Passes.h Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=71014&r1=71013&r2=71014&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Tue May 5 15:54:11 2009 @@ -191,7 +191,7 @@ FunctionPass *createMachineSinkingPass(); /// createStackSlotColoringPass - This pass performs stack slot coloring. - FunctionPass *createStackSlotColoringPass(); + FunctionPass *createStackSlotColoringPass(bool); /// createStackProtectorPass - This pass adds stack protectors to functions. FunctionPass *createStackProtectorPass(const TargetLowering *tli); From gohman at apple.com Tue May 5 15:48:53 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 05 May 2009 20:48:53 -0000 Subject: [llvm-commits] [llvm] r71012 - /llvm/trunk/docs/CodeGenerator.html Message-ID: <200905052048.n45KmwEV009976@zion.cs.uiuc.edu> Author: djg Date: Tue May 5 15:48:47 2009 New Revision: 71012 URL: http://llvm.org/viewvc/llvm-project?rev=71012&view=rev Log: Add some more documentation for x86 special address spaces. Modified: llvm/trunk/docs/CodeGenerator.html Modified: llvm/trunk/docs/CodeGenerator.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodeGenerator.html?rev=71012&r1=71011&r2=71012&view=diff ============================================================================== --- llvm/trunk/docs/CodeGenerator.html (original) +++ llvm/trunk/docs/CodeGenerator.html Tue May 5 15:48:47 2009 @@ -1838,7 +1838,8 @@
-

x86 has the ability to perform loads and stores to different address spaces +

x86 has an experimental feature which provides + the ability to perform loads and stores to different address spaces via the x86 segment registers. A segment override prefix byte on an instruction causes the instruction's memory access to go to the specified segment. LLVM address space 0 is the default address space, which includes @@ -1848,9 +1849,30 @@ address space 257. Other x86 segments have yet to be allocated address space numbers.

-

Some operating systems use the FS/GS-segment to implement TLS, so care - should be taken when reading and writing to address space 256/257 on these - platforms.

+

While these address spaces may seem similar to TLS via the + thread_local keyword, and often use the same underlying hardware, + there are some fundamental differences.

+ +

The thread_local keyword applies to global variables and + specifies that they are to be allocated in thread-local memory. There are + no type qualifiers involved, and these variables can be pointed to with + normal pointers and accessed with normal loads and stores. + The thread_local keyword is target-independent at the LLVM IR + level (though LLVM doesn't yet have implementations of it for some + configurations).

+ +

Special address spaces, in contrast, apply to static types. Every + load and store has a particular address space in its address operand type, + and this is what determines which address space is accessed. + LLVM ignores these special address space qualifiers on global variables, + and does not provide a way to directly allocate storage in them. + At the LLVM IR level, the behavior of these special address spaces depends + in part on the underlying OS or runtime environment, and they are specific + to x86 (and LLVM doesn't yet handle them correctly in some cases).

+ +

Some operating systems and runtime environments use (or may in the future + use) the FS/GS-segment registers for various low-level purposes, so care + should be taken when considering them.

From gohman at apple.com Tue May 5 16:10:53 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 05 May 2009 21:10:53 -0000 Subject: [llvm-commits] [llvm] r71018 - in /llvm/trunk: lib/CodeGen/IfConversion.cpp lib/CodeGen/MachineBasicBlock.cpp test/CodeGen/X86/omit-label.ll Message-ID: <200905052110.n45LAx1D010796@zion.cs.uiuc.edu> Author: djg Date: Tue May 5 16:10:19 2009 New Revision: 71018 URL: http://llvm.org/viewvc/llvm-project?rev=71018&view=rev Log: If a MachineBasicBlock has multiple ways of reaching another block, allow it to have multiple CFG edges to that block. This is needed to allow MachineBasicBlock::isOnlyReachableByFallthrough to work correctly. This fixes PR4126. Added: llvm/trunk/test/CodeGen/X86/omit-label.ll Modified: llvm/trunk/lib/CodeGen/IfConversion.cpp llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Modified: llvm/trunk/lib/CodeGen/IfConversion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IfConversion.cpp?rev=71018&r1=71017&r2=71018&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/IfConversion.cpp (original) +++ llvm/trunk/lib/CodeGen/IfConversion.cpp Tue May 5 16:10:19 2009 @@ -1174,8 +1174,7 @@ // Fallthrough edge can't be transferred. if (Succ == FallThrough) continue; - if (!ToBBI.BB->isSuccessor(Succ)) - ToBBI.BB->addSuccessor(Succ); + ToBBI.BB->addSuccessor(Succ); } std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(), @@ -1215,12 +1214,11 @@ if (Succ == FallThrough) continue; FromBBI.BB->removeSuccessor(Succ); - if (!ToBBI.BB->isSuccessor(Succ)) - ToBBI.BB->addSuccessor(Succ); + ToBBI.BB->addSuccessor(Succ); } // Now FromBBI always fall through to the next block! - if (NBB && !FromBBI.BB->isSuccessor(NBB)) + if (NBB) FromBBI.BB->addSuccessor(NBB); std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(), Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=71018&r1=71017&r2=71018&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Tue May 5 16:10:19 2009 @@ -305,11 +305,9 @@ I->getOperand(i).setMBB(New); } - // Update the successor information. If New was already a successor, just - // remove the link to Old instead of creating another one. PR 1444. + // Update the successor information. removeSuccessor(Old); - if (!isSuccessor(New)) - addSuccessor(New); + addSuccessor(New); } /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in the Added: llvm/trunk/test/CodeGen/X86/omit-label.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/omit-label.ll?rev=71018&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/omit-label.ll (added) +++ llvm/trunk/test/CodeGen/X86/omit-label.ll Tue May 5 16:10:19 2009 @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep BB1_1: +; PR4126 + +; Don't omit this label's definition. + +define void @bux(i32 %p_53) nounwind optsize { +entry: + %0 = icmp eq i32 %p_53, 0 ; [#uses=1] + %1 = icmp sgt i32 %p_53, 0 ; [#uses=1] + %or.cond = and i1 %0, %1 ; [#uses=1] + br i1 %or.cond, label %bb.i, label %bb3 + +bb.i: ; preds = %entry + %2 = add i32 %p_53, 1 ; [#uses=1] + %3 = icmp slt i32 %2, 0 ; [#uses=0] + br label %bb3 + +bb3: ; preds = %bb.i, %entry + %4 = tail call i32 (...)* @baz(i32 0) nounwind ; [#uses=0] + ret void +} + +declare i32 @baz(...) From greened at obbligato.org Tue May 5 15:22:57 2009 From: greened at obbligato.org (David Greene) Date: Tue, 05 May 2009 20:22:57 -0000 Subject: [llvm-commits] [llvm] r71008 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll Message-ID: <200905052023.n45KNE3G008989@zion.cs.uiuc.edu> Author: greened Date: Tue May 5 15:22:36 2009 New Revision: 71008 URL: http://llvm.org/viewvc/llvm-project?rev=71008&view=rev Log: Handle overflow of 64-bit loop conditions. Added: llvm/trunk/test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=71008&r1=71007&r2=71008&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue May 5 15:22:36 2009 @@ -2027,9 +2027,10 @@ Scale = SSInt / CmpSSInt; int64_t NewCmpVal = CmpVal * Scale; - APInt Mul = APInt(BitWidth, NewCmpVal); + APInt Mul = APInt(BitWidth*2, CmpVal); + Mul = Mul * APInt(BitWidth*2, Scale); // Check for overflow. - if (Mul.getSExtValue() != NewCmpVal) + if (!Mul.isSignedIntN(BitWidth)) continue; // Watch out for overflow. Added: llvm/trunk/test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll?rev=71008&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll (added) +++ llvm/trunk/test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll Tue May 5 15:22:36 2009 @@ -0,0 +1,122 @@ +; Check that we do not strength reduce to an overflowiong loop condition +; RUN: llvm-as < %s | opt -loop-reduce | llvm-dis | not grep 4755160694556239428 + +target datalayout = "e-p:64:64" +target triple = "x86_64-unknown-linux-gnu" +@"initialized$$$CFE_id_3d9e38d5_main" = linkonce global [3 x i64] [i64 6729544817907097974, i64 754394135718280480, i64 0] +@"initialized$main$$CFE_id_3d9e38d5_main" = linkonce global [512 x i64] zeroinitializer + +define i32 @main() { +"file loop.c, line 10, bb14": + %vals = alloca [512 x i64], align 16 + br label %"file loop.c, line 10, bb101" + +"file loop.c, line 10, bb101": + br label %"file loop.c, line 10, in inner vector loop at depth 0, bb62" + +"file loop.c, line 10, in inner vector loop at depth 0, bb62": + %"$SI_S13.0" = phi i64 [ 0, %"file loop.c, line 10, bb101" ], [ %r35, %"file loop.c, line 13, in inner vector loop at depth 0, bb63" ] + %"$LC_S14.0" = phi i64 [ -256, %"file loop.c, line 10, bb101" ], [ %r37, %"file loop.c, line 13, in inner vector loop at depth 0, bb63" ] + br label %"file loop.c, line 13, in inner vector loop at depth 0, bb63" + +"file loop.c, line 13, in inner vector loop at depth 0, bb63": + %r3 = add i64 %"$SI_S13.0", ptrtoint ([512 x i64]* @"initialized$main$$CFE_id_3d9e38d5_main" to i64) + %vals18 = bitcast [512 x i64]* %vals to i8* + %ctg2 = getelementptr i8* %vals18, i64 %"$SI_S13.0" + %r9 = inttoptr i64 %r3 to <2 x i64>* + %r10 = load <2 x i64>* %r9, align 8 + %r12 = bitcast i8* %ctg2 to <2 x i64>* + store <2 x i64> %r10, <2 x i64>* %r12, align 16 + %tmp17 = inttoptr i64 %r3 to <2 x i64>* + %r15 = getelementptr <2 x i64>* %tmp17, i64 1 + %r16 = load <2 x i64>* %r15, align 8 + %ctg2.sum19 = or i64 %"$SI_S13.0", 16 + %r19 = getelementptr i8* %vals18, i64 %ctg2.sum19 + %0 = bitcast i8* %r19 to <2 x i64>* + store <2 x i64> %r16, <2 x i64>* %0, align 16 + %tmp15 = inttoptr i64 %r3 to <2 x i64>* + %r22 = getelementptr <2 x i64>* %tmp15, i64 2 + %r23 = load <2 x i64>* %r22, align 8 + %ctg2.sum20 = or i64 %"$SI_S13.0", 32 + %r26 = getelementptr i8* %vals18, i64 %ctg2.sum20 + %1 = bitcast i8* %r26 to <2 x i64>* + store <2 x i64> %r23, <2 x i64>* %1, align 16 + %tmp13 = inttoptr i64 %r3 to <2 x i64>* + %r29 = getelementptr <2 x i64>* %tmp13, i64 3 + %r30 = load <2 x i64>* %r29, align 8 + %ctg2.sum21 = or i64 %"$SI_S13.0", 48 + %r33 = getelementptr i8* %vals18, i64 %ctg2.sum21 + %2 = bitcast i8* %r33 to <2 x i64>* + store <2 x i64> %r30, <2 x i64>* %2, align 16 + %r35 = add i64 %"$SI_S13.0", 64 + %r37 = add i64 %"$LC_S14.0", 4 + %r39 = icmp slt i64 %r37, 0 + br i1 %r39, label %"file loop.c, line 10, in inner vector loop at depth 0, bb62", label %"file loop.c, line 15, bb51" + +"file loop.c, line 15, bb51": + %3 = getelementptr [512 x i64]* %vals, i64 0, i64 0 + store i64 0, i64* %3, align 16 + br label %"file loop.c, line 10, in inner loop at depth 0, bb65" + +"file loop.c, line 10, in inner loop at depth 0, bb65": + %"$vals_WR0_S15.0" = phi i64 [ 0, %"file loop.c, line 15, bb51" ], [ %r70, %"file loop.c, line 16, in inner loop at depth 0, bb67" ] + %"$i_S16.0" = phi i64 [ 0, %"file loop.c, line 15, bb51" ], [ %r78, %"file loop.c, line 16, in inner loop at depth 0, bb67" ] + br label %"file loop.c, line 16, in inner loop at depth 0, bb67" + +"file loop.c, line 16, in inner loop at depth 0, bb67": + %r45 = add i64 %"$vals_WR0_S15.0", 81985529216486895 + %r5111 = or i64 %"$i_S16.0", 1 + %r5212 = getelementptr [512 x i64]* %vals, i64 0, i64 %r5111 + store i64 %r45, i64* %r5212, align 8 + %r54 = add i64 %"$vals_WR0_S15.0", 163971058432973790 + %r599 = or i64 %"$i_S16.0", 2 + %r6010 = getelementptr [512 x i64]* %vals, i64 0, i64 %r599 + store i64 %r54, i64* %r6010, align 16 + %r62 = add i64 %"$vals_WR0_S15.0", 245956587649460685 + %r677 = or i64 %"$i_S16.0", 3 + %r688 = getelementptr [512 x i64]* %vals, i64 0, i64 %r677 + store i64 %r62, i64* %r688, align 8 + %r70 = add i64 %"$vals_WR0_S15.0", 327942116865947580 + %r75 = add i64 %"$i_S16.0", 4 + %r766 = getelementptr [512 x i64]* %vals, i64 0, i64 %r75 + store i64 %r70, i64* %r766, align 16 + %r78 = add i64 %"$i_S16.0", 4 + %r80 = icmp slt i64 %r78, 508 + br i1 %r80, label %"file loop.c, line 10, in inner loop at depth 0, bb65", label %"file loop.c, line 16, bb39" + +"file loop.c, line 16, bb39": + %r84 = add i64 %"$vals_WR0_S15.0", 409927646082434475 + %r885 = getelementptr [512 x i64]* %vals, i64 0, i64 509 + store i64 %r84, i64* %r885, align 8 + %r90 = add i64 %"$vals_WR0_S15.0", 491913175298921370 + %r944 = getelementptr [512 x i64]* %vals, i64 0, i64 510 + store i64 %r90, i64* %r944, align 16 + %r1003 = getelementptr [512 x i64]* %vals, i64 0, i64 511 + %r96.c = add i64 %"$vals_WR0_S15.0", 573898704515408265 + store i64 %r96.c, i64* %r1003, align 8 + br label %"file loop.c, line 10, in inner loop at depth 0, bb13" + +"file loop.c, line 10, in inner loop at depth 0, bb13": + %"$i_S17.0" = phi i64 [ 0, %"file loop.c, line 16, bb39" ], [ %r111, %"file loop.c, line 19, in inner loop at depth 0, bb25" ] + br label %"file loop.c, line 19, in inner loop at depth 0, bb6" + +"file loop.c, line 19, in inner loop at depth 0, bb6": + %r102 = add i64 %"$i_S17.0", 1 + %r106 = add i64 %"$i_S17.0", 1 + %r1071 = getelementptr [512 x i64]* %vals, i64 0, i64 %r106 + %r1072 = load i64* %r1071, align 8 + %r109 = call i32 (...)* @printf([17 x i8]* bitcast ([3 x i64]* @"initialized$$$CFE_id_3d9e38d5_main" to [17 x i8]*), i64 %r102, i64 %r1072) + br label %"file loop.c, line 19, in inner loop at depth 0, bb25" + +"file loop.c, line 19, in inner loop at depth 0, bb25": + %r111 = add i64 %"$i_S17.0", 1 + %r113 = icmp slt i64 %r111, 511 + br i1 %r113, label %"file loop.c, line 10, in inner loop at depth 0, bb13", label %"file loop.c, line 19, bb10" + +"file loop.c, line 19, bb10": + ret i32 0 +} + +declare i8* @llvm.returnaddress(i32) nounwind readnone + +declare i32 @printf(...) From isanbard at gmail.com Tue May 5 15:50:27 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 05 May 2009 20:50:27 -0000 Subject: [llvm-commits] [llvm] r71013 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll Message-ID: <200905052050.n45KojDJ010074@zion.cs.uiuc.edu> Author: void Date: Tue May 5 15:49:46 2009 New Revision: 71013 URL: http://llvm.org/viewvc/llvm-project?rev=71013&view=rev Log: Temporarily reverting r71008. It was causing this failure: Running /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ CodeGen/X86/dg.exp ... FAIL: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ CodeGen/X86/change-compare-stride-1.ll Failed with exit(1) at line 2 while running: grep {cmpq $-478,} change-compare-stride-1.ll.tmp child process exited abnormally Removed: llvm/trunk/test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=71013&r1=71012&r2=71013&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue May 5 15:49:46 2009 @@ -2027,10 +2027,9 @@ Scale = SSInt / CmpSSInt; int64_t NewCmpVal = CmpVal * Scale; - APInt Mul = APInt(BitWidth*2, CmpVal); - Mul = Mul * APInt(BitWidth*2, Scale); + APInt Mul = APInt(BitWidth, NewCmpVal); // Check for overflow. - if (!Mul.isSignedIntN(BitWidth)) + if (Mul.getSExtValue() != NewCmpVal) continue; // Watch out for overflow. Removed: llvm/trunk/test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll?rev=71012&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll (original) +++ llvm/trunk/test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll (removed) @@ -1,122 +0,0 @@ -; Check that we do not strength reduce to an overflowiong loop condition -; RUN: llvm-as < %s | opt -loop-reduce | llvm-dis | not grep 4755160694556239428 - -target datalayout = "e-p:64:64" -target triple = "x86_64-unknown-linux-gnu" -@"initialized$$$CFE_id_3d9e38d5_main" = linkonce global [3 x i64] [i64 6729544817907097974, i64 754394135718280480, i64 0] -@"initialized$main$$CFE_id_3d9e38d5_main" = linkonce global [512 x i64] zeroinitializer - -define i32 @main() { -"file loop.c, line 10, bb14": - %vals = alloca [512 x i64], align 16 - br label %"file loop.c, line 10, bb101" - -"file loop.c, line 10, bb101": - br label %"file loop.c, line 10, in inner vector loop at depth 0, bb62" - -"file loop.c, line 10, in inner vector loop at depth 0, bb62": - %"$SI_S13.0" = phi i64 [ 0, %"file loop.c, line 10, bb101" ], [ %r35, %"file loop.c, line 13, in inner vector loop at depth 0, bb63" ] - %"$LC_S14.0" = phi i64 [ -256, %"file loop.c, line 10, bb101" ], [ %r37, %"file loop.c, line 13, in inner vector loop at depth 0, bb63" ] - br label %"file loop.c, line 13, in inner vector loop at depth 0, bb63" - -"file loop.c, line 13, in inner vector loop at depth 0, bb63": - %r3 = add i64 %"$SI_S13.0", ptrtoint ([512 x i64]* @"initialized$main$$CFE_id_3d9e38d5_main" to i64) - %vals18 = bitcast [512 x i64]* %vals to i8* - %ctg2 = getelementptr i8* %vals18, i64 %"$SI_S13.0" - %r9 = inttoptr i64 %r3 to <2 x i64>* - %r10 = load <2 x i64>* %r9, align 8 - %r12 = bitcast i8* %ctg2 to <2 x i64>* - store <2 x i64> %r10, <2 x i64>* %r12, align 16 - %tmp17 = inttoptr i64 %r3 to <2 x i64>* - %r15 = getelementptr <2 x i64>* %tmp17, i64 1 - %r16 = load <2 x i64>* %r15, align 8 - %ctg2.sum19 = or i64 %"$SI_S13.0", 16 - %r19 = getelementptr i8* %vals18, i64 %ctg2.sum19 - %0 = bitcast i8* %r19 to <2 x i64>* - store <2 x i64> %r16, <2 x i64>* %0, align 16 - %tmp15 = inttoptr i64 %r3 to <2 x i64>* - %r22 = getelementptr <2 x i64>* %tmp15, i64 2 - %r23 = load <2 x i64>* %r22, align 8 - %ctg2.sum20 = or i64 %"$SI_S13.0", 32 - %r26 = getelementptr i8* %vals18, i64 %ctg2.sum20 - %1 = bitcast i8* %r26 to <2 x i64>* - store <2 x i64> %r23, <2 x i64>* %1, align 16 - %tmp13 = inttoptr i64 %r3 to <2 x i64>* - %r29 = getelementptr <2 x i64>* %tmp13, i64 3 - %r30 = load <2 x i64>* %r29, align 8 - %ctg2.sum21 = or i64 %"$SI_S13.0", 48 - %r33 = getelementptr i8* %vals18, i64 %ctg2.sum21 - %2 = bitcast i8* %r33 to <2 x i64>* - store <2 x i64> %r30, <2 x i64>* %2, align 16 - %r35 = add i64 %"$SI_S13.0", 64 - %r37 = add i64 %"$LC_S14.0", 4 - %r39 = icmp slt i64 %r37, 0 - br i1 %r39, label %"file loop.c, line 10, in inner vector loop at depth 0, bb62", label %"file loop.c, line 15, bb51" - -"file loop.c, line 15, bb51": - %3 = getelementptr [512 x i64]* %vals, i64 0, i64 0 - store i64 0, i64* %3, align 16 - br label %"file loop.c, line 10, in inner loop at depth 0, bb65" - -"file loop.c, line 10, in inner loop at depth 0, bb65": - %"$vals_WR0_S15.0" = phi i64 [ 0, %"file loop.c, line 15, bb51" ], [ %r70, %"file loop.c, line 16, in inner loop at depth 0, bb67" ] - %"$i_S16.0" = phi i64 [ 0, %"file loop.c, line 15, bb51" ], [ %r78, %"file loop.c, line 16, in inner loop at depth 0, bb67" ] - br label %"file loop.c, line 16, in inner loop at depth 0, bb67" - -"file loop.c, line 16, in inner loop at depth 0, bb67": - %r45 = add i64 %"$vals_WR0_S15.0", 81985529216486895 - %r5111 = or i64 %"$i_S16.0", 1 - %r5212 = getelementptr [512 x i64]* %vals, i64 0, i64 %r5111 - store i64 %r45, i64* %r5212, align 8 - %r54 = add i64 %"$vals_WR0_S15.0", 163971058432973790 - %r599 = or i64 %"$i_S16.0", 2 - %r6010 = getelementptr [512 x i64]* %vals, i64 0, i64 %r599 - store i64 %r54, i64* %r6010, align 16 - %r62 = add i64 %"$vals_WR0_S15.0", 245956587649460685 - %r677 = or i64 %"$i_S16.0", 3 - %r688 = getelementptr [512 x i64]* %vals, i64 0, i64 %r677 - store i64 %r62, i64* %r688, align 8 - %r70 = add i64 %"$vals_WR0_S15.0", 327942116865947580 - %r75 = add i64 %"$i_S16.0", 4 - %r766 = getelementptr [512 x i64]* %vals, i64 0, i64 %r75 - store i64 %r70, i64* %r766, align 16 - %r78 = add i64 %"$i_S16.0", 4 - %r80 = icmp slt i64 %r78, 508 - br i1 %r80, label %"file loop.c, line 10, in inner loop at depth 0, bb65", label %"file loop.c, line 16, bb39" - -"file loop.c, line 16, bb39": - %r84 = add i64 %"$vals_WR0_S15.0", 409927646082434475 - %r885 = getelementptr [512 x i64]* %vals, i64 0, i64 509 - store i64 %r84, i64* %r885, align 8 - %r90 = add i64 %"$vals_WR0_S15.0", 491913175298921370 - %r944 = getelementptr [512 x i64]* %vals, i64 0, i64 510 - store i64 %r90, i64* %r944, align 16 - %r1003 = getelementptr [512 x i64]* %vals, i64 0, i64 511 - %r96.c = add i64 %"$vals_WR0_S15.0", 573898704515408265 - store i64 %r96.c, i64* %r1003, align 8 - br label %"file loop.c, line 10, in inner loop at depth 0, bb13" - -"file loop.c, line 10, in inner loop at depth 0, bb13": - %"$i_S17.0" = phi i64 [ 0, %"file loop.c, line 16, bb39" ], [ %r111, %"file loop.c, line 19, in inner loop at depth 0, bb25" ] - br label %"file loop.c, line 19, in inner loop at depth 0, bb6" - -"file loop.c, line 19, in inner loop at depth 0, bb6": - %r102 = add i64 %"$i_S17.0", 1 - %r106 = add i64 %"$i_S17.0", 1 - %r1071 = getelementptr [512 x i64]* %vals, i64 0, i64 %r106 - %r1072 = load i64* %r1071, align 8 - %r109 = call i32 (...)* @printf([17 x i8]* bitcast ([3 x i64]* @"initialized$$$CFE_id_3d9e38d5_main" to [17 x i8]*), i64 %r102, i64 %r1072) - br label %"file loop.c, line 19, in inner loop at depth 0, bb25" - -"file loop.c, line 19, in inner loop at depth 0, bb25": - %r111 = add i64 %"$i_S17.0", 1 - %r113 = icmp slt i64 %r111, 511 - br i1 %r113, label %"file loop.c, line 10, in inner loop at depth 0, bb13", label %"file loop.c, line 19, bb10" - -"file loop.c, line 19, bb10": - ret i32 0 -} - -declare i8* @llvm.returnaddress(i32) nounwind readnone - -declare i32 @printf(...) From evan.cheng at apple.com Tue May 5 15:30:44 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 05 May 2009 20:30:44 -0000 Subject: [llvm-commits] [llvm] r71010 - in /llvm/trunk: lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/StackSlotColoring.cpp test/CodeGen/X86/stack-color-with-reg.ll Message-ID: <200905052030.n45KUrjC009298@zion.cs.uiuc.edu> Author: evancheng Date: Tue May 5 15:30:36 2009 New Revision: 71010 URL: http://llvm.org/viewvc/llvm-project?rev=71010&view=rev Log: Enable stack coloring with regs at -O3. Added: llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=71010&r1=71009&r2=71010&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Tue May 5 15:30:36 2009 @@ -193,7 +193,7 @@ // Perform stack slot coloring. if (OptLevel != CodeGenOpt::None) - PM.add(createStackSlotColoringPass()); + PM.add(createStackSlotColoringPass(OptLevel >= CodeGenOpt::Aggressive)); if (PrintMachineCode) // Print the register-allocated code PM.add(createMachineFunctionPrinterPass(cerr)); Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=71010&r1=71009&r2=71010&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Tue May 5 15:30:36 2009 @@ -37,21 +37,22 @@ cl::desc("Suppress slot sharing during stack coloring")); static cl::opt -ColorWithRegs("color-ss-with-regs", - cl::init(false), cl::Hidden, - cl::desc("Color stack slots with free registers")); +ColorWithRegsOpt("color-ss-with-regs", + cl::init(false), cl::Hidden, + cl::desc("Color stack slots with free registers")); static cl::opt DCELimit("ssc-dce-limit", cl::init(-1), cl::Hidden); STATISTIC(NumEliminated, "Number of stack slots eliminated due to coloring"); STATISTIC(NumRegRepl, "Number of stack slot refs replaced with reg refs"); -STATISTIC(NumLoadElim, "Number of load eliminated"); +STATISTIC(NumLoadElim, "Number of loads eliminated"); STATISTIC(NumStoreElim, "Number of stores eliminated"); STATISTIC(NumDead, "Number of trivially dead stack accesses eliminated"); namespace { class VISIBILITY_HIDDEN StackSlotColoring : public MachineFunctionPass { + bool ColorWithRegs; LiveStacks* LS; VirtRegMap* VRM; MachineFrameInfo *MFI; @@ -89,7 +90,10 @@ public: static char ID; // Pass identification - StackSlotColoring() : MachineFunctionPass(&ID), NextColor(-1) {} + StackSlotColoring() : + MachineFunctionPass(&ID), ColorWithRegs(false), NextColor(-1) {} + StackSlotColoring(bool RegColor) : + MachineFunctionPass(&ID), ColorWithRegs(RegColor), NextColor(-1) {} virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -136,8 +140,8 @@ static RegisterPass X("stack-slot-coloring", "Stack Slot Coloring"); -FunctionPass *llvm::createStackSlotColoringPass() { - return new StackSlotColoring(); +FunctionPass *llvm::createStackSlotColoringPass(bool RegColor) { + return new StackSlotColoring(RegColor); } namespace { @@ -231,7 +235,7 @@ StackSlotColoring::ColorSlotsWithFreeRegs(SmallVector &SlotMapping, SmallVector, 16> &RevMap, BitVector &SlotIsReg) { - if (!ColorWithRegs || !VRM->HasUnusedRegisters()) + if (!(ColorWithRegs || ColorWithRegsOpt) || !VRM->HasUnusedRegisters()) return false; bool Changed = false; @@ -239,7 +243,9 @@ for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) { LiveInterval *li = SSIntervals[i]; int SS = li->getStackSlotIndex(); - if (!UsedColors[SS]) + if (!UsedColors[SS] || li->weight < 20) + // If the weight is < 20, i.e. two references in a loop with depth 1, + // don't bother with it. continue; // These slots allow to share the same registers. @@ -472,6 +478,9 @@ bool StackSlotColoring::PropagateBackward(MachineBasicBlock::iterator MII, MachineBasicBlock *MBB, unsigned OldReg, unsigned NewReg) { + if (MII == MBB->begin()) + return false; + SmallVector Refs; while (--MII != MBB->begin()) { bool FoundDef = false; // Not counting 2address def. @@ -522,6 +531,9 @@ bool StackSlotColoring::PropagateForward(MachineBasicBlock::iterator MII, MachineBasicBlock *MBB, unsigned OldReg, unsigned NewReg) { + if (MII == MBB->end()) + return false; + SmallVector Uses; while (++MII != MBB->end()) { bool FoundUse = false; Added: llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll?rev=71010&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll (added) +++ llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll Tue May 5 15:30:36 2009 @@ -0,0 +1,361 @@ +; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin10 -relocation-model=pic -disable-fp-elim -O3 -stats -info-output-file - > %t +; RUN: grep stackcoloring %t | grep "loads eliminated" +; RUN: grep stackcoloring %t | grep "stores eliminated" + + type { [62 x %struct.Bitvec*] } ; type %0 + type { i8* } ; type %1 + type { double } ; type %2 + %struct..5sPragmaType = type { i8*, i32 } + %struct.AggInfo = type { i8, i8, i32, %struct.ExprList*, i32, %struct.AggInfo_col*, i32, i32, i32, %struct.AggInfo_func*, i32, i32 } + %struct.AggInfo_col = type { %struct.Table*, i32, i32, i32, i32, %struct.Expr* } + %struct.AggInfo_func = type { %struct.Expr*, %struct.FuncDef*, i32, i32 } + %struct.AuxData = type { i8*, void (i8*)* } + %struct.Bitvec = type { i32, i32, i32, %0 } + %struct.BtCursor = type { %struct.Btree*, %struct.BtShared*, %struct.BtCursor*, %struct.BtCursor*, i32 (i8*, i32, i8*, i32, i8*)*, i8*, i32, %struct.MemPage*, i32, %struct.CellInfo, i8, i8, i8*, i64, i32, i8, i32* } + %struct.BtLock = type { %struct.Btree*, i32, i8, %struct.BtLock* } + %struct.BtShared = type { %struct.Pager*, %struct.sqlite3*, %struct.BtCursor*, %struct.MemPage*, i8, i8, i8, i8, i8, i8, i8, i8, i32, i16, i16, i32, i32, i32, i32, i8, i32, i8*, void (i8*)*, %struct.sqlite3_mutex*, %struct.BusyHandler, i32, %struct.BtShared*, %struct.BtLock*, %struct.Btree* } + %struct.Btree = type { %struct.sqlite3*, %struct.BtShared*, i8, i8, i8, i32, %struct.Btree*, %struct.Btree* } + %struct.BtreeMutexArray = type { i32, [11 x %struct.Btree*] } + %struct.BusyHandler = type { i32 (i8*, i32)*, i8*, i32 } + %struct.CellInfo = type { i8*, i64, i32, i32, i16, i16, i16, i16 } + %struct.CollSeq = type { i8*, i8, i8, i8*, i32 (i8*, i32, i8*, i32, i8*)*, void (i8*)* } + %struct.Column = type { i8*, %struct.Expr*, i8*, i8*, i8, i8, i8, i8 } + %struct.Context = type { i64, i32, %struct.Fifo } + %struct.CountCtx = type { i64 } + %struct.Cursor = type { %struct.BtCursor*, i32, i64, i64, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i64, %struct.Btree*, i32, i8*, i64, i8*, %struct.KeyInfo*, i32, i64, %struct.sqlite3_vtab_cursor*, %struct.sqlite3_module*, i32, i32, i32*, i32*, i8* } + %struct.Db = type { i8*, %struct.Btree*, i8, i8, i8*, void (i8*)*, %struct.Schema* } + %struct.DbPage = type { %struct.Pager*, i32, %struct.DbPage*, %struct.DbPage*, %struct.PagerLruLink, %struct.DbPage*, i8, i8, i8, i8, i8, i16, %struct.DbPage*, %struct.DbPage*, i8* } + %struct.Expr = type { i8, i8, i16, %struct.CollSeq*, %struct.Expr*, %struct.Expr*, %struct.ExprList*, %struct..5sPragmaType, %struct..5sPragmaType, i32, i32, %struct.AggInfo*, i32, i32, %struct.Select*, %struct.Table*, i32 } + %struct.ExprList = type { i32, i32, i32, %struct.ExprList_item* } + %struct.ExprList_item = type { %struct.Expr*, i8*, i8, i8, i8 } + %struct.FKey = type { %struct.Table*, %struct.FKey*, i8*, %struct.FKey*, i32, %struct.sColMap*, i8, i8, i8, i8 } + %struct.Fifo = type { i32, %struct.FifoPage*, %struct.FifoPage* } + %struct.FifoPage = type { i32, i32, i32, %struct.FifoPage*, [1 x i64] } + %struct.FuncDef = type { i16, i8, i8, i8, i8*, %struct.FuncDef*, void (%struct.sqlite3_context*, i32, %struct.Mem**)*, void (%struct.sqlite3_context*, i32, %struct.Mem**)*, void (%struct.sqlite3_context*)*, [1 x i8] } + %struct.Hash = type { i8, i8, i32, i32, %struct.HashElem*, %struct._ht* } + %struct.HashElem = type { %struct.HashElem*, %struct.HashElem*, i8*, i8*, i32 } + %struct.IdList = type { %struct..5sPragmaType*, i32, i32 } + %struct.Index = type { i8*, i32, i32*, i32*, %struct.Table*, i32, i8, i8, i8*, %struct.Index*, %struct.Schema*, i8*, i8** } + %struct.KeyInfo = type { %struct.sqlite3*, i8, i8, i8, i32, i8*, [1 x %struct.CollSeq*] } + %struct.Mem = type { %struct.CountCtx, double, %struct.sqlite3*, i8*, i32, i16, i8, i8, void (i8*)* } + %struct.MemPage = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i16, i16, i16, i16, i16, i16, [5 x %struct._OvflCell], %struct.BtShared*, i8*, %struct.DbPage*, i32, %struct.MemPage* } + %struct.Module = type { %struct.sqlite3_module*, i8*, i8*, void (i8*)* } + %struct.Op = type { i8, i8, i8, i8, i32, i32, i32, %1 } + %struct.Pager = type { %struct.sqlite3_vfs*, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.Bitvec*, %struct.Bitvec*, i8*, i8*, i8*, i8*, %struct.sqlite3_file*, %struct.sqlite3_file*, %struct.sqlite3_file*, %struct.BusyHandler*, %struct.PagerLruList, %struct.DbPage*, %struct.DbPage*, %struct.DbPage*, i64, i64, i64, i64, i64, i32, void (%struct.DbPage*, i32)*, void (%struct.DbPage*, i32)*, i32, %struct.DbPage**, i8*, [16 x i8] } + %struct.PagerLruLink = type { %struct.DbPage*, %struct.DbPage* } + %struct.PagerLruList = type { %struct.DbPage*, %struct.DbPage*, %struct.DbPage* } + %struct.Schema = type { i32, %struct.Hash, %struct.Hash, %struct.Hash, %struct.Hash, %struct.Table*, i8, i8, i16, i32, %struct.sqlite3* } + %struct.Select = type { %struct.ExprList*, i8, i8, i8, i8, i8, i8, i8, %struct.SrcList*, %struct.Expr*, %struct.ExprList*, %struct.Expr*, %struct.ExprList*, %struct.Select*, %struct.Select*, %struct.Select*, %struct.Expr*, %struct.Expr*, i32, i32, [3 x i32] } + %struct.SrcList = type { i16, i16, [1 x %struct.SrcList_item] } + %struct.SrcList_item = type { i8*, i8*, i8*, %struct.Table*, %struct.Select*, i8, i8, i32, %struct.Expr*, %struct.IdList*, i64 } + %struct.Table = type { i8*, i32, %struct.Column*, i32, %struct.Index*, i32, %struct.Select*, i32, %struct.Trigger*, %struct.FKey*, i8*, %struct.Expr*, i32, i8, i8, i8, i8, i8, i8, i8, %struct.Module*, %struct.sqlite3_vtab*, i32, i8**, %struct.Schema* } + %struct.Trigger = type { i8*, i8*, i8, i8, %struct.Expr*, %struct.IdList*, %struct..5sPragmaType, %struct.Schema*, %struct.Schema*, %struct.TriggerStep*, %struct.Trigger* } + %struct.TriggerStep = type { i32, i32, %struct.Trigger*, %struct.Select*, %struct..5sPragmaType, %struct.Expr*, %struct.ExprList*, %struct.IdList*, %struct.TriggerStep*, %struct.TriggerStep* } + %struct.Vdbe = type { %struct.sqlite3*, %struct.Vdbe*, %struct.Vdbe*, i32, i32, %struct.Op*, i32, i32, i32*, %struct.Mem**, %struct.Mem*, i32, %struct.Cursor**, i32, %struct.Mem*, i8**, i32, i32, i32, %struct.Mem*, i32, i32, %struct.Fifo, i32, i32, %struct.Context*, i32, i32, i32, i32, i32, [25 x i32], i32, i32, i8**, i8*, %struct.Mem*, i8, i8, i8, i8, i8, i8, i32, i64, i32, %struct.BtreeMutexArray, i32, i8*, i32 } + %struct.VdbeFunc = type { %struct.FuncDef*, i32, [1 x %struct.AuxData] } + %struct._OvflCell = type { i8*, i16 } + %struct._ht = type { i32, %struct.HashElem* } + %struct.sColMap = type { i32, i8* } + %struct.sqlite3 = type { %struct.sqlite3_vfs*, i32, %struct.Db*, i32, i32, i32, i32, i8, i8, i8, i8, i32, %struct.CollSeq*, i64, i64, i32, i32, i32, %struct.sqlite3_mutex*, %struct.sqlite3InitInfo, i32, i8**, %struct.Vdbe*, i32, void (i8*, i8*)*, i8*, void (i8*, i8*, i64)*, i8*, i8*, i32 (i8*)*, i8*, void (i8*)*, i8*, void (i8*, i32, i8*, i8*, i64)*, void (i8*, %struct.sqlite3*, i32, i8*)*, void (i8*, %struct.sqlite3*, i32, i8*)*, i8*, %struct.Mem*, i8*, i8*, %2, i32 (i8*, i32, i8*, i8*, i8*, i8*)*, i8*, i32 (i8*)*, i8*, i32, %struct.Hash, %struct.Table*, %struct.sqlite3_vtab**, i32, %struct.Hash, %struct.Hash, %struct.BusyHandler, i32, [2 x %struct.Db], i8 } + %struct.sqlite3InitInfo = type { i32, i32, i8 } + %struct.sqlite3_context = type { %struct.FuncDef*, %struct.VdbeFunc*, %struct.Mem, %struct.Mem*, i32, %struct.CollSeq* } + %struct.sqlite3_file = type { %struct.sqlite3_io_methods* } + %struct.sqlite3_index_constraint = type { i32, i8, i8, i32 } + %struct.sqlite3_index_constraint_usage = type { i32, i8 } + %struct.sqlite3_index_info = type { i32, %struct.sqlite3_index_constraint*, i32, %struct.sqlite3_index_constraint_usage*, %struct.sqlite3_index_constraint_usage*, i32, i8*, i32, i32, double } + %struct.sqlite3_io_methods = type { i32, i32 (%struct.sqlite3_file*)*, i32 (%struct.sqlite3_file*, i8*, i32, i64)*, i32 (%struct.sqlite3_file*, i8*, i32, i64)*, i32 (%struct.sqlite3_file*, i64)*, i32 (%struct.sqlite3_file*, i32)*, i32 (%struct.sqlite3_file*, i64*)*, i32 (%struct.sqlite3_file*, i32)*, i32 (%struct.sqlite3_file*, i32)*, i32 (%struct.sqlite3_file*)*, i32 (%struct.sqlite3_file*, i32, i8*)*, i32 (%struct.sqlite3_file*)*, i32 (%struct.sqlite3_file*)* } + %struct.sqlite3_module = type { i32, i32 (%struct.sqlite3*, i8*, i32, i8**, %struct.sqlite3_vtab**, i8**)*, i32 (%struct.sqlite3*, i8*, i32, i8**, %struct.sqlite3_vtab**, i8**)*, i32 (%struct.sqlite3_vtab*, %struct.sqlite3_index_info*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*, %struct.sqlite3_vtab_cursor**)*, i32 (%struct.sqlite3_vtab_cursor*)*, i32 (%struct.sqlite3_vtab_cursor*, i32, i8*, i32, %struct.Mem**)*, i32 (%struct.sqlite3_vtab_cursor*)*, i32 (%struct.sqlite3_vtab_cursor*)*, i32 (%struct.sqlite3_vtab_cursor*, %struct.sqlite3_context*, i32)*, i32 (%struct.sqlite3_vtab_cursor*, i64*)*, i32 (%struct.sqlite3_vtab*, i32, %struct.Mem**, i64*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*, i32, i8*, void (%struct.sqlite3_context*, i32, %struct.Mem**)**, i8**)*, i32 (%struct.sqlite3_vtab*, i8*)* } + %struct.sqlite3_mutex = type opaque + %struct.sqlite3_vfs = type { i32, i32, i32, %struct.sqlite3_vfs*, i8*, i8*, i32 (%struct.sqlite3_vfs*, i8*, %struct.sqlite3_file*, i32, i32*)*, i32 (%struct.sqlite3_vfs*, i8*, i32)*, i32 (%struct.sqlite3_vfs*, i8*, i32)*, i32 (%struct.sqlite3_vfs*, i32, i8*)*, i32 (%struct.sqlite3_vfs*, i8*, i32, i8*)*, i8* (%struct.sqlite3_vfs*, i8*)*, void (%struct.sqlite3_vfs*, i32, i8*)*, i8* (%struct.sqlite3_vfs*, i8*, i8*)*, void (%struct.sqlite3_vfs*, i8*)*, i32 (%struct.sqlite3_vfs*, i32, i8*)*, i32 (%struct.sqlite3_vfs*, i32)*, i32 (%struct.sqlite3_vfs*, double*)* } + %struct.sqlite3_vtab = type { %struct.sqlite3_module*, i32, i8* } + %struct.sqlite3_vtab_cursor = type { %struct.sqlite3_vtab* } + at llvm.used = appending global [1 x i8*] [i8* bitcast (void (%struct.MemPage*, i32, i32)* @dropCell to i8*)], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define fastcc void @dropCell(%struct.MemPage* nocapture %pPage, i32 %idx, i32 %sz) nounwind ssp { +entry: + %0 = getelementptr %struct.MemPage* %pPage, i64 0, i32 18 ; [#uses=1] + %1 = load i8** %0, align 8 ; [#uses=34] + %2 = getelementptr %struct.MemPage* %pPage, i64 0, i32 12 ; [#uses=1] + %3 = load i16* %2, align 2 ; [#uses=1] + %4 = zext i16 %3 to i32 ; [#uses=2] + %5 = shl i32 %idx, 1 ; [#uses=2] + %6 = add i32 %4, %5 ; [#uses=1] + %7 = sext i32 %6 to i64 ; [#uses=2] + %8 = getelementptr i8* %1, i64 %7 ; [#uses=1] + %9 = load i8* %8, align 1 ; [#uses=2] + %10 = zext i8 %9 to i32 ; [#uses=1] + %11 = shl i32 %10, 8 ; [#uses=1] + %.sum3 = add i64 %7, 1 ; [#uses=1] + %12 = getelementptr i8* %1, i64 %.sum3 ; [#uses=1] + %13 = load i8* %12, align 1 ; [#uses=2] + %14 = zext i8 %13 to i32 ; [#uses=1] + %15 = or i32 %11, %14 ; [#uses=3] + %16 = icmp slt i32 %sz, 4 ; [#uses=1] + %size_addr.0.i = select i1 %16, i32 4, i32 %sz ; [#uses=3] + %17 = getelementptr %struct.MemPage* %pPage, i64 0, i32 8 ; [#uses=5] + %18 = load i8* %17, align 8 ; [#uses=1] + %19 = zext i8 %18 to i32 ; [#uses=4] + %20 = add i32 %19, 1 ; [#uses=2] + br label %bb3.i + +bb3.i: ; preds = %bb3.i, %entry + %addr.0.i = phi i32 [ %20, %entry ], [ %29, %bb3.i ] ; [#uses=1] + %21 = sext i32 %addr.0.i to i64 ; [#uses=2] + %22 = getelementptr i8* %1, i64 %21 ; [#uses=2] + %23 = load i8* %22, align 1 ; [#uses=2] + %24 = zext i8 %23 to i32 ; [#uses=1] + %25 = shl i32 %24, 8 ; [#uses=1] + %.sum34.i = add i64 %21, 1 ; [#uses=1] + %26 = getelementptr i8* %1, i64 %.sum34.i ; [#uses=2] + %27 = load i8* %26, align 1 ; [#uses=2] + %28 = zext i8 %27 to i32 ; [#uses=1] + %29 = or i32 %25, %28 ; [#uses=3] + %.not.i = icmp uge i32 %29, %15 ; [#uses=1] + %30 = icmp eq i32 %29, 0 ; [#uses=1] + %or.cond.i = or i1 %30, %.not.i ; [#uses=1] + br i1 %or.cond.i, label %bb5.i, label %bb3.i + +bb5.i: ; preds = %bb3.i + store i8 %9, i8* %22, align 1 + store i8 %13, i8* %26, align 1 + %31 = zext i32 %15 to i64 ; [#uses=2] + %32 = getelementptr i8* %1, i64 %31 ; [#uses=1] + store i8 %23, i8* %32, align 1 + %.sum32.i = add i64 %31, 1 ; [#uses=1] + %33 = getelementptr i8* %1, i64 %.sum32.i ; [#uses=1] + store i8 %27, i8* %33, align 1 + %34 = add i32 %15, 2 ; [#uses=1] + %35 = zext i32 %34 to i64 ; [#uses=2] + %36 = getelementptr i8* %1, i64 %35 ; [#uses=1] + %37 = lshr i32 %size_addr.0.i, 8 ; [#uses=1] + %38 = trunc i32 %37 to i8 ; [#uses=1] + store i8 %38, i8* %36, align 1 + %39 = trunc i32 %size_addr.0.i to i8 ; [#uses=1] + %.sum31.i = add i64 %35, 1 ; [#uses=1] + %40 = getelementptr i8* %1, i64 %.sum31.i ; [#uses=1] + store i8 %39, i8* %40, align 1 + %41 = getelementptr %struct.MemPage* %pPage, i64 0, i32 14 ; [#uses=4] + %42 = load i16* %41, align 2 ; [#uses=1] + %43 = trunc i32 %size_addr.0.i to i16 ; [#uses=1] + %44 = add i16 %42, %43 ; [#uses=1] + store i16 %44, i16* %41, align 2 + %45 = load i8* %17, align 8 ; [#uses=1] + %46 = zext i8 %45 to i32 ; [#uses=1] + %47 = add i32 %46, 1 ; [#uses=1] + br label %bb11.outer.i + +bb11.outer.i: ; preds = %bb6.i, %bb5.i + %addr.1.ph.i = phi i32 [ %47, %bb5.i ], [ %111, %bb6.i ] ; [#uses=1] + %48 = sext i32 %addr.1.ph.i to i64 ; [#uses=2] + %49 = getelementptr i8* %1, i64 %48 ; [#uses=1] + %.sum30.i = add i64 %48, 1 ; [#uses=1] + %50 = getelementptr i8* %1, i64 %.sum30.i ; [#uses=1] + br label %bb11.i + +bb6.i: ; preds = %bb11.i + %51 = zext i32 %111 to i64 ; [#uses=2] + %52 = getelementptr i8* %1, i64 %51 ; [#uses=2] + %53 = load i8* %52, align 1 ; [#uses=1] + %54 = zext i8 %53 to i32 ; [#uses=1] + %55 = shl i32 %54, 8 ; [#uses=1] + %.sum24.i = add i64 %51, 1 ; [#uses=1] + %56 = getelementptr i8* %1, i64 %.sum24.i ; [#uses=2] + %57 = load i8* %56, align 1 ; [#uses=3] + %58 = zext i8 %57 to i32 ; [#uses=1] + %59 = or i32 %55, %58 ; [#uses=5] + %60 = add i32 %111, 2 ; [#uses=1] + %61 = zext i32 %60 to i64 ; [#uses=2] + %62 = getelementptr i8* %1, i64 %61 ; [#uses=2] + %63 = load i8* %62, align 1 ; [#uses=1] + %64 = zext i8 %63 to i32 ; [#uses=1] + %65 = shl i32 %64, 8 ; [#uses=1] + %.sum23.i = add i64 %61, 1 ; [#uses=1] + %66 = getelementptr i8* %1, i64 %.sum23.i ; [#uses=2] + %67 = load i8* %66, align 1 ; [#uses=2] + %68 = zext i8 %67 to i32 ; [#uses=1] + %69 = or i32 %65, %68 ; [#uses=1] + %70 = add i32 %111, 3 ; [#uses=1] + %71 = add i32 %70, %69 ; [#uses=1] + %72 = icmp sge i32 %71, %59 ; [#uses=1] + %73 = icmp ne i32 %59, 0 ; [#uses=1] + %74 = and i1 %72, %73 ; [#uses=1] + br i1 %74, label %bb9.i, label %bb11.outer.i + +bb9.i: ; preds = %bb6.i + %75 = load i8* %17, align 8 ; [#uses=1] + %76 = zext i8 %75 to i32 ; [#uses=1] + %77 = add i32 %76, 7 ; [#uses=1] + %78 = zext i32 %77 to i64 ; [#uses=1] + %79 = getelementptr i8* %1, i64 %78 ; [#uses=2] + %80 = load i8* %79, align 1 ; [#uses=1] + %81 = sub i8 %109, %57 ; [#uses=1] + %82 = add i8 %81, %67 ; [#uses=1] + %83 = add i8 %82, %80 ; [#uses=1] + store i8 %83, i8* %79, align 1 + %84 = zext i32 %59 to i64 ; [#uses=2] + %85 = getelementptr i8* %1, i64 %84 ; [#uses=1] + %86 = load i8* %85, align 1 ; [#uses=1] + store i8 %86, i8* %52, align 1 + %.sum22.i = add i64 %84, 1 ; [#uses=1] + %87 = getelementptr i8* %1, i64 %.sum22.i ; [#uses=1] + %88 = load i8* %87, align 1 ; [#uses=1] + store i8 %88, i8* %56, align 1 + %89 = add i32 %59, 2 ; [#uses=1] + %90 = zext i32 %89 to i64 ; [#uses=2] + %91 = getelementptr i8* %1, i64 %90 ; [#uses=1] + %92 = load i8* %91, align 1 ; [#uses=1] + %93 = zext i8 %92 to i32 ; [#uses=1] + %94 = shl i32 %93, 8 ; [#uses=1] + %.sum20.i = add i64 %90, 1 ; [#uses=1] + %95 = getelementptr i8* %1, i64 %.sum20.i ; [#uses=2] + %96 = load i8* %95, align 1 ; [#uses=1] + %97 = zext i8 %96 to i32 ; [#uses=1] + %98 = or i32 %94, %97 ; [#uses=1] + %99 = sub i32 %59, %111 ; [#uses=1] + %100 = add i32 %99, %98 ; [#uses=1] + %101 = lshr i32 %100, 8 ; [#uses=1] + %102 = trunc i32 %101 to i8 ; [#uses=1] + store i8 %102, i8* %62, align 1 + %103 = load i8* %95, align 1 ; [#uses=1] + %104 = sub i8 %57, %109 ; [#uses=1] + %105 = add i8 %104, %103 ; [#uses=1] + store i8 %105, i8* %66, align 1 + br label %bb11.i + +bb11.i: ; preds = %bb9.i, %bb11.outer.i + %106 = load i8* %49, align 1 ; [#uses=1] + %107 = zext i8 %106 to i32 ; [#uses=1] + %108 = shl i32 %107, 8 ; [#uses=1] + %109 = load i8* %50, align 1 ; [#uses=3] + %110 = zext i8 %109 to i32 ; [#uses=1] + %111 = or i32 %108, %110 ; [#uses=6] + %112 = icmp eq i32 %111, 0 ; [#uses=1] + br i1 %112, label %bb12.i, label %bb6.i + +bb12.i: ; preds = %bb11.i + %113 = zext i32 %20 to i64 ; [#uses=2] + %114 = getelementptr i8* %1, i64 %113 ; [#uses=2] + %115 = load i8* %114, align 1 ; [#uses=2] + %116 = add i32 %19, 5 ; [#uses=1] + %117 = zext i32 %116 to i64 ; [#uses=2] + %118 = getelementptr i8* %1, i64 %117 ; [#uses=3] + %119 = load i8* %118, align 1 ; [#uses=1] + %120 = icmp eq i8 %115, %119 ; [#uses=1] + br i1 %120, label %bb13.i, label %bb1.preheader + +bb13.i: ; preds = %bb12.i + %121 = add i32 %19, 2 ; [#uses=1] + %122 = zext i32 %121 to i64 ; [#uses=1] + %123 = getelementptr i8* %1, i64 %122 ; [#uses=1] + %124 = load i8* %123, align 1 ; [#uses=1] + %125 = add i32 %19, 6 ; [#uses=1] + %126 = zext i32 %125 to i64 ; [#uses=1] + %127 = getelementptr i8* %1, i64 %126 ; [#uses=1] + %128 = load i8* %127, align 1 ; [#uses=1] + %129 = icmp eq i8 %124, %128 ; [#uses=1] + br i1 %129, label %bb14.i, label %bb1.preheader + +bb14.i: ; preds = %bb13.i + %130 = zext i8 %115 to i32 ; [#uses=1] + %131 = shl i32 %130, 8 ; [#uses=1] + %.sum29.i = add i64 %113, 1 ; [#uses=1] + %132 = getelementptr i8* %1, i64 %.sum29.i ; [#uses=1] + %133 = load i8* %132, align 1 ; [#uses=1] + %134 = zext i8 %133 to i32 ; [#uses=1] + %135 = or i32 %134, %131 ; [#uses=2] + %136 = zext i32 %135 to i64 ; [#uses=1] + %137 = getelementptr i8* %1, i64 %136 ; [#uses=1] + %138 = bitcast i8* %137 to i16* ; [#uses=1] + %139 = bitcast i8* %114 to i16* ; [#uses=1] + %tmp.i = load i16* %138, align 1 ; [#uses=1] + store i16 %tmp.i, i16* %139, align 1 + %140 = load i8* %118, align 1 ; [#uses=1] + %141 = zext i8 %140 to i32 ; [#uses=1] + %142 = shl i32 %141, 8 ; [#uses=1] + %.sum28.i = add i64 %117, 1 ; [#uses=1] + %143 = getelementptr i8* %1, i64 %.sum28.i ; [#uses=2] + %144 = load i8* %143, align 1 ; [#uses=2] + %145 = zext i8 %144 to i32 ; [#uses=1] + %146 = or i32 %142, %145 ; [#uses=1] + %147 = add i32 %135, 2 ; [#uses=1] + %148 = zext i32 %147 to i64 ; [#uses=2] + %149 = getelementptr i8* %1, i64 %148 ; [#uses=1] + %150 = load i8* %149, align 1 ; [#uses=1] + %151 = zext i8 %150 to i32 ; [#uses=1] + %152 = shl i32 %151, 8 ; [#uses=1] + %.sum27.i = add i64 %148, 1 ; [#uses=1] + %153 = getelementptr i8* %1, i64 %.sum27.i ; [#uses=2] + %154 = load i8* %153, align 1 ; [#uses=1] + %155 = zext i8 %154 to i32 ; [#uses=1] + %156 = or i32 %152, %155 ; [#uses=1] + %157 = add i32 %156, %146 ; [#uses=1] + %158 = lshr i32 %157, 8 ; [#uses=1] + %159 = trunc i32 %158 to i8 ; [#uses=1] + store i8 %159, i8* %118, align 1 + %160 = load i8* %153, align 1 ; [#uses=1] + %161 = add i8 %160, %144 ; [#uses=1] + store i8 %161, i8* %143, align 1 + br label %bb1.preheader + +bb1.preheader: ; preds = %bb14.i, %bb13.i, %bb12.i + %i.08 = add i32 %idx, 1 ; [#uses=2] + %162 = getelementptr %struct.MemPage* %pPage, i64 0, i32 15 ; [#uses=4] + %163 = load i16* %162, align 4 ; [#uses=2] + %164 = zext i16 %163 to i32 ; [#uses=1] + %165 = icmp sgt i32 %164, %i.08 ; [#uses=1] + br i1 %165, label %bb, label %bb2 + +bb: ; preds = %bb, %bb1.preheader + %indvar = phi i64 [ 0, %bb1.preheader ], [ %indvar.next, %bb ] ; [#uses=3] + %tmp16 = add i32 %5, %4 ; [#uses=1] + %tmp.17 = sext i32 %tmp16 to i64 ; [#uses=1] + %tmp19 = shl i64 %indvar, 1 ; [#uses=1] + %ctg2.sum = add i64 %tmp.17, %tmp19 ; [#uses=4] + %ctg229 = getelementptr i8* %1, i64 %ctg2.sum ; [#uses=1] + %ctg229.sum31 = add i64 %ctg2.sum, 2 ; [#uses=1] + %166 = getelementptr i8* %1, i64 %ctg229.sum31 ; [#uses=1] + %167 = load i8* %166, align 1 ; [#uses=1] + store i8 %167, i8* %ctg229 + %ctg229.sum30 = add i64 %ctg2.sum, 3 ; [#uses=1] + %168 = getelementptr i8* %1, i64 %ctg229.sum30 ; [#uses=1] + %169 = load i8* %168, align 1 ; [#uses=1] + %ctg229.sum = add i64 %ctg2.sum, 1 ; [#uses=1] + %170 = getelementptr i8* %1, i64 %ctg229.sum ; [#uses=1] + store i8 %169, i8* %170, align 1 + %indvar15 = trunc i64 %indvar to i32 ; [#uses=1] + %i.09 = add i32 %indvar15, %i.08 ; [#uses=1] + %i.0 = add i32 %i.09, 1 ; [#uses=1] + %171 = load i16* %162, align 4 ; [#uses=2] + %172 = zext i16 %171 to i32 ; [#uses=1] + %173 = icmp sgt i32 %172, %i.0 ; [#uses=1] + %indvar.next = add i64 %indvar, 1 ; [#uses=1] + br i1 %173, label %bb, label %bb2 + +bb2: ; preds = %bb, %bb1.preheader + %174 = phi i16 [ %163, %bb1.preheader ], [ %171, %bb ] ; [#uses=1] + %175 = add i16 %174, -1 ; [#uses=2] + store i16 %175, i16* %162, align 4 + %176 = load i8* %17, align 8 ; [#uses=1] + %177 = zext i8 %176 to i32 ; [#uses=1] + %178 = add i32 %177, 3 ; [#uses=1] + %179 = zext i32 %178 to i64 ; [#uses=1] + %180 = getelementptr i8* %1, i64 %179 ; [#uses=1] + %181 = lshr i16 %175, 8 ; [#uses=1] + %182 = trunc i16 %181 to i8 ; [#uses=1] + store i8 %182, i8* %180, align 1 + %183 = load i8* %17, align 8 ; [#uses=1] + %184 = zext i8 %183 to i32 ; [#uses=1] + %185 = add i32 %184, 3 ; [#uses=1] + %186 = zext i32 %185 to i64 ; [#uses=1] + %187 = load i16* %162, align 4 ; [#uses=1] + %188 = trunc i16 %187 to i8 ; [#uses=1] + %.sum = add i64 %186, 1 ; [#uses=1] + %189 = getelementptr i8* %1, i64 %.sum ; [#uses=1] + store i8 %188, i8* %189, align 1 + %190 = load i16* %41, align 2 ; [#uses=1] + %191 = add i16 %190, 2 ; [#uses=1] + store i16 %191, i16* %41, align 2 + %192 = getelementptr %struct.MemPage* %pPage, i64 0, i32 1 ; [#uses=1] + store i8 1, i8* %192, align 1 + ret void +} From evan.cheng at apple.com Tue May 5 17:50:36 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 05 May 2009 22:50:36 -0000 Subject: [llvm-commits] [llvm] r71032 - in /llvm/trunk: include/llvm/Support/Mangler.h lib/VMCore/Mangler.cpp test/CodeGen/X86/private-2.ll Message-ID: <200905052250.n45MofxI014514@zion.cs.uiuc.edu> Author: evancheng Date: Tue May 5 17:50:29 2009 New Revision: 71032 URL: http://llvm.org/viewvc/llvm-project?rev=71032&view=rev Log: Quotes should be printed before private prefix; some code clean up. Added: llvm/trunk/test/CodeGen/X86/private-2.ll Modified: llvm/trunk/include/llvm/Support/Mangler.h llvm/trunk/lib/VMCore/Mangler.cpp Modified: llvm/trunk/include/llvm/Support/Mangler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Mangler.h?rev=71032&r1=71031&r2=71032&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/Mangler.h (original) +++ llvm/trunk/include/llvm/Support/Mangler.h Tue May 5 17:50:29 2009 @@ -29,7 +29,10 @@ /// symbol is marked as not needing this prefix. const char *Prefix; + /// PrivatePrefix - This string is emitted before each symbol with private + /// linkage. const char *PrivatePrefix; + /// UseQuotes - If this is set, the target accepts global names in quotes, /// e.g. "foo bar" is a legal name. This syntax is used instead of escaping /// the space character. By default, this is false. @@ -95,7 +98,8 @@ /// does this for you, so there's no point calling it on the result /// from getValueName. /// - std::string makeNameProper(const std::string &x, const char *Prefix = ""); + std::string makeNameProper(const std::string &x, const char *Prefix = 0, + const char *PrivatePrefix = 0); private: /// getTypeID - Return a unique ID for the specified LLVM type. Modified: llvm/trunk/lib/VMCore/Mangler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Mangler.cpp?rev=71032&r1=71031&r2=71032&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Mangler.cpp (original) +++ llvm/trunk/lib/VMCore/Mangler.cpp Tue May 5 17:50:29 2009 @@ -31,8 +31,8 @@ /// makeNameProper - We don't want identifier names non-C-identifier characters /// in them, so mangle them as appropriate. /// -std::string Mangler::makeNameProper(const std::string &X, const char *Prefix) { - std::string Result; +std::string Mangler::makeNameProper(const std::string &X, const char *Prefix, + const char *PrivatePrefix) { if (X.empty()) return X; // Empty names are uniqued by the caller. // If PreserveAsmNames is set, names with asm identifiers are not modified. @@ -40,12 +40,15 @@ return X; if (!UseQuotes) { + std::string Result; + // If X does not start with (char)1, add the prefix. + bool NeedPrefix = true; std::string::const_iterator I = X.begin(); - if (*I != 1) - Result = Prefix; - else + if (*I == 1) { + NeedPrefix = false; ++I; // Skip over the marker. + } // Mangle the first letter specially, don't allow numbers. if (*I >= '0' && *I <= '9') @@ -57,53 +60,71 @@ else Result += *I; } - } else { - bool NeedsQuotes = false; - - std::string::const_iterator I = X.begin(); - if (*I == 1) - ++I; // Skip over the marker. - // If the first character is a number, we need quotes. - if (*I >= '0' && *I <= '9') - NeedsQuotes = true; - - // Do an initial scan of the string, checking to see if we need quotes or - // to escape a '"' or not. - if (!NeedsQuotes) - for (std::string::const_iterator E = X.end(); I != E; ++I) - if (!isCharAcceptable(*I)) { - NeedsQuotes = true; - break; - } - - // In the common case, we don't need quotes. Handle this quickly. - if (!NeedsQuotes) { - if (*X.begin() != 1) - return Prefix+X; - else - return X.substr(1); + if (NeedPrefix) { + if (Prefix) + Result = Prefix + Result; + if (PrivatePrefix) + Result = PrivatePrefix + Result; } + return Result; + } + + bool NeedPrefix = true; + bool NeedQuotes = false; + std::string Result; + std::string::const_iterator I = X.begin(); + if (*I == 1) { + NeedPrefix = false; + ++I; // Skip over the marker. + } + + // If the first character is a number, we need quotes. + if (*I >= '0' && *I <= '9') + NeedQuotes = true; + + // Do an initial scan of the string, checking to see if we need quotes or + // to escape a '"' or not. + if (!NeedQuotes) + for (std::string::const_iterator E = X.end(); I != E; ++I) + if (!isCharAcceptable(*I)) { + NeedQuotes = true; + break; + } + + // In the common case, we don't need quotes. Handle this quickly. + if (!NeedQuotes) { + if (NeedPrefix) { + if (Prefix) + Result = Prefix + X; + else + Result = X; + if (PrivatePrefix) + Result = PrivatePrefix + Result; + return Result; + } else + return X.substr(1); + } - // Otherwise, construct the string the expensive way. - I = X.begin(); - - // If X does not start with (char)1, add the prefix. - if (*I != 1) - Result = Prefix; + // Otherwise, construct the string the expensive way. + for (std::string::const_iterator E = X.end(); I != E; ++I) { + if (*I == '"') + Result += "_QQ_"; + else if (*I == '\n') + Result += "_NL_"; else - ++I; // Skip the marker if present. - - for (std::string::const_iterator E = X.end(); I != E; ++I) { - if (*I == '"') - Result += "_QQ_"; - else if (*I == '\n') - Result += "_NL_"; - else - Result += *I; - } - Result = '"' + Result + '"'; + Result += *I; + } + + if (NeedPrefix) { + if (Prefix) + Result = Prefix + X; + else + Result = X; + if (PrivatePrefix) + Result = PrivatePrefix + Result; } + Result = '"' + Result + '"'; return Result; } @@ -146,13 +167,10 @@ static unsigned GlobalID = 0; Name = "__unnamed_" + utostr(TypeUniqueID) + "_" + utostr(GlobalID++); } else { - Name = makeNameProper(GV->getName() + Suffix, Prefix); - std::string prefix; if (GV->hasPrivateLinkage()) - prefix = PrivatePrefix; + Name = makeNameProper(GV->getName() + Suffix, Prefix, PrivatePrefix); else - prefix = ""; - Name = prefix + Name; + Name = makeNameProper(GV->getName() + Suffix, Prefix); } return Name; Added: llvm/trunk/test/CodeGen/X86/private-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/private-2.ll?rev=71032&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/private-2.ll (added) +++ llvm/trunk/test/CodeGen/X86/private-2.ll Tue May 5 17:50:29 2009 @@ -0,0 +1,13 @@ +; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin10 | grep L__ZZ20 +; Quote should be outside of private prefix. +; rdar://6855766x + + %struct.A = type { i32*, i32 } +@"_ZZ20-[Example1 whatever]E4C.91" = private constant %struct.A { i32* null, i32 1 } ; <%struct.A*> [#uses=1] + +define internal i32* @"\01-[Example1 whatever]"() nounwind optsize ssp { +entry: + %0 = getelementptr %struct.A* @"_ZZ20-[Example1 whatever]E4C.91", i64 0, i32 0 ; [#uses=1] + %1 = load i32** %0, align 8 ; [#uses=1] + ret i32* %1 +} From gohman at apple.com Tue May 5 17:59:59 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 05 May 2009 22:59:59 -0000 Subject: [llvm-commits] [llvm] r71033 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200905052259.n45MxxcN014803@zion.cs.uiuc.edu> Author: djg Date: Tue May 5 17:59:55 2009 New Revision: 71033 URL: http://llvm.org/viewvc/llvm-project?rev=71033&view=rev Log: Delete a FIXME which is no longer relevant, and add a FIXME that is. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=71033&r1=71032&r2=71033&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue May 5 17:59:55 2009 @@ -2464,8 +2464,9 @@ // computation of some other indvar to decide when to terminate the loop. OptimizeIndvars(L); - // FIXME: We can widen subreg IV's here for RISC targets. e.g. instead of - // doing computation in byte values, promote to 32-bit values if safe. + // FIXME: We can widen overlarge IV's here. e.g. if the code has + // computation in i64 values and the target doesn't support i64, demote + // the computation to 32-bit if safe. // FIXME: Attempt to reuse values across multiple IV's. In particular, we // could have something like "for(i) { foo(i*8); bar(i*16) }", which should From gohman at apple.com Tue May 5 18:02:39 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 05 May 2009 23:02:39 -0000 Subject: [llvm-commits] [llvm] r71035 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200905052302.n45N2dGg014901@zion.cs.uiuc.edu> Author: djg Date: Tue May 5 18:02:38 2009 New Revision: 71035 URL: http://llvm.org/viewvc/llvm-project?rev=71035&view=rev Log: Fix a copy+pasto in a comment. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=71035&r1=71034&r2=71035&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue May 5 18:02:38 2009 @@ -2464,7 +2464,7 @@ // computation of some other indvar to decide when to terminate the loop. OptimizeIndvars(L); - // FIXME: We can widen overlarge IV's here. e.g. if the code has + // FIXME: We can shrink overlarge IV's here. e.g. if the code has // computation in i64 values and the target doesn't support i64, demote // the computation to 32-bit if safe. From kremenek at apple.com Tue May 5 18:16:57 2009 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 05 May 2009 23:16:57 -0000 Subject: [llvm-commits] [llvm] r71039 - /llvm/tags/checker/checker-0.195/ Message-ID: <200905052316.n45NGvGe015497@zion.cs.uiuc.edu> Author: kremenek Date: Tue May 5 18:16:57 2009 New Revision: 71039 URL: http://llvm.org/viewvc/llvm-project?rev=71039&view=rev Log: Tagging checker-0.195. Added: llvm/tags/checker/checker-0.195/ - copied from r71038, llvm/trunk/ From foldr at codedgers.com Tue May 5 20:41:47 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Wed, 06 May 2009 01:41:47 -0000 Subject: [llvm-commits] [llvm] r71055 - in /llvm/trunk/docs: CompilerDriver.html CompilerDriverTutorial.html llvm.css Message-ID: <200905060141.n461fl71020434@zion.cs.uiuc.edu> Author: foldr Date: Tue May 5 20:41:47 2009 New Revision: 71055 URL: http://llvm.org/viewvc/llvm-project?rev=71055&view=rev Log: Regenerate documentation. Modified: llvm/trunk/docs/CompilerDriver.html llvm/trunk/docs/CompilerDriverTutorial.html llvm/trunk/docs/llvm.css Modified: llvm/trunk/docs/CompilerDriver.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CompilerDriver.html?rev=71055&r1=71054&r2=71055&view=diff ============================================================================== --- llvm/trunk/docs/CompilerDriver.html (original) +++ llvm/trunk/docs/CompilerDriver.html Tue May 5 20:41:47 2009 @@ -3,46 +3,47 @@ - + Customizing LLVMC: Reference Manual

Customizing LLVMC: Reference Manual

+ -
-

Contents

+

Written by Mikhail Glushenkov

-
+

Introduction

LLVMC is a generic compiler driver, designed to be customizable and extensible. It plays the same role for LLVM as the gcc program does for GCC - LLVMC's job is essentially to transform a set of input @@ -55,11 +56,11 @@ by plugins, which can be either statically or dynamically linked. This makes it possible to easily adapt LLVMC for other purposes - for example, as a build tool for game resources.

-

Because LLVMC employs TableGen as its configuration language, you +

Because LLVMC employs TableGen as its configuration language, you need to be familiar with it to customize LLVMC.

-
-

Compiling with LLVMC

+
+

Compiling with LLVMC

LLVMC tries hard to be as compatible with gcc as possible, although there are some small differences. Most of the time, however, you shouldn't be able to notice them:

@@ -96,8 +97,8 @@ also possible to choose the work-in-progress clang compiler with the -clang option.

-
-

Predefined options

+
+

Predefined options

LLVMC has some built-in options that can't be overridden in the configuration libraries:

    @@ -125,8 +126,8 @@ their standard meaning.
-
-

Compiling LLVMC plugins

+
+

Compiling LLVMC plugins

It's easiest to start working on your own LLVMC plugin by copying the skeleton project which lives under $LLVMC_DIR/plugins/Simple:

@@ -141,7 +142,7 @@
 description of the compilation graph; its format is documented in the
 following sections. PluginMain.cpp is just a helper file used to
 compile the auto-generated C++ code produced from TableGen source. It
-can also contain hook definitions (see below).

+can also contain hook definitions (see below).

The first thing that you should do is to change the LLVMC_PLUGIN variable in the Makefile to avoid conflicts (since this variable is used to name the resulting library):

@@ -178,8 +179,8 @@ $ make BUILTIN_PLUGINS=""
-
-

Customizing LLVMC: the compilation graph

+
+

Customizing LLVMC: the compilation graph

Each TableGen configuration file should include the common definitions:

@@ -246,8 +247,8 @@
 debugging), run llvmc --view-graph. You will need dot and
 gsview installed for this to work properly.

-
-

Describing options

+
+

Describing options

Command-line options that the plugin supports are defined by using an OptionList:

@@ -315,8 +316,8 @@
 
 
 
-
-

External options

+
+

External options

Sometimes, when linking several plugins together, one plugin needs to access options defined in some other plugin. Because of the way options are implemented, such options must be marked as @@ -327,11 +328,11 @@ (switch_option "E", (extern)) ...

-

See also the section on plugin priorities.

+

See also the section on plugin priorities.

-
-

Conditional evaluation

+
+

Conditional evaluation

The 'case' construct is the main means by which programmability is achieved in LLVMC. It can be used to calculate edge weights, program actions and modify the shell commands to be executed. The 'case' @@ -410,8 +411,8 @@

-
-

Writing a tool description

+
+

Writing a tool description

As was said earlier, nodes in the compilation graph represent tools, which are described separately. A tool definition looks like this (taken from the include/llvm/CompilerDriver/Tools.td file):

@@ -452,8 +453,8 @@ -
-

Actions

+
+

Actions

A tool often needs to react to command-line options, and this is precisely what the actions property is for. The next example illustrates this feature:

@@ -496,7 +497,7 @@ Example: (forward "Wall").
  • forward_as - Change the name of an option, but forward the argument unchanged. -Example: (forward_as "O0" "--disable-optimization").
  • +Example: (forward_as "O0", "--disable-optimization").
  • output_suffix - modify the output suffix of this tool. Example: (output_suffix "i").
  • @@ -513,8 +514,8 @@
    -
    -

    Language map

    +
    +

    Language map

    If you are adding support for a new language to LLVMC, you'll need to modify the language map, which defines mappings from file extensions to language names. It is used to choose the proper toolchain(s) for a @@ -536,10 +537,10 @@ multiple output languages, for nodes "inside" the graph the input and output languages should match. This is enforced at compile-time.

    -
    -

    More advanced topics

    -
    -

    Hooks and environment variables

    +
    +

    More advanced topics

    +
    +

    Hooks and environment variables

    Normally, LLVMC executes programs from the system PATH. Sometimes, this is not sufficient: for example, we may want to specify tool paths or names in the configuration file. This can be easily achieved via @@ -561,7 +562,7 @@ (cmd_line "$ENV(VAR1)/path/to/file -o $ENV(VAR2)")

    To change the command line string based on user-provided options use -the case expression (documented above):

    +the case expression (documented above):

     (cmd_line
       (case
    @@ -571,8 +572,8 @@
            "llvm-g++ -c -x c $INFILE -o $OUTFILE -emit-llvm"))
     
    -
    -

    How plugins are loaded

    +
    +

    How plugins are loaded

    It is possible for LLVMC plugins to depend on each other. For example, one can create edges between nodes defined in some other plugin. To make this work, however, that plugin should be loaded first. To @@ -587,12 +588,12 @@ with 0. Therefore, the plugin with the highest priority value will be loaded last.

    -
    -

    Debugging

    +
    +

    Debugging

    When writing LLVMC plugins, it can be useful to get a visual view of the resulting compilation graph. This can be achieved via the command -line option --view-graph. This command assumes that Graphviz and -Ghostview are installed. There is also a --write-graph option that +line option --view-graph. This command assumes that Graphviz and +Ghostview are installed. There is also a --write-graph option that creates a Graphviz source file (compilation-graph.dot) in the current directory.

    Another useful llvmc option is --check-graph. It checks the Modified: llvm/trunk/docs/CompilerDriverTutorial.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CompilerDriverTutorial.html?rev=71055&r1=71054&r2=71055&view=diff ============================================================================== --- llvm/trunk/docs/CompilerDriverTutorial.html (original) +++ llvm/trunk/docs/CompilerDriverTutorial.html Tue May 5 20:41:47 2009 @@ -3,28 +3,29 @@ - + Tutorial - Using LLVMC

    Tutorial - Using LLVMC

    + -
    -

    Contents

    +

    Written by Mikhail Glushenkov

    -
    +

    Introduction

    LLVMC is a generic compiler driver, which plays the same role for LLVM as the gcc program does for GCC - the difference being that LLVMC is designed to be more adaptable and easier to customize. Most of @@ -32,8 +33,8 @@ dynamically or compiled in. This tutorial describes the basic usage and configuration of LLVMC.

    -
    -

    Compiling with LLVMC

    +
    +

    Compiling with LLVMC

    In general, LLVMC tries to be command-line compatible with gcc as much as possible, so most of the familiar options work:

    @@ -45,9 +46,9 @@
     commands are executed by using the -v option). For further help on
     command-line LLVMC usage, refer to the llvmc --help output.

    -
    -

    Using LLVMC to generate toolchain drivers

    -

    LLVMC plugins are written mostly using TableGen, so you need to +

    +

    Using LLVMC to generate toolchain drivers

    +

    LLVMC plugins are written mostly using TableGen, so you need to be familiar with it to get anything done.

    Start by compiling plugins/Simple/Simple.td, which is a primitive wrapper for gcc:

    Modified: llvm/trunk/docs/llvm.css URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/llvm.css?rev=71055&r1=71054&r2=71055&view=diff ============================================================================== --- llvm/trunk/docs/llvm.css (original) +++ llvm/trunk/docs/llvm.css Tue May 5 20:41:47 2009 @@ -72,7 +72,7 @@ /* It is preferrable to use
     everywhere instead of the
      * 
    ...
    construct. - * + * * Once all docs use
     for code regions, this style can  be merged with the
      * one above, and we can drop the [pre] qualifier.
      */
    @@ -95,6 +95,6 @@
     
     /* ReST-specific */
     .title { margin-top: 0 }
    -#contents { display: none }
    +.topic-title{ display: none }
     div.contents ul { list-style-type: decimal }
     .toc-backref    { color: black; text-decoration: none; }
    
    
    
    
    From foldr at codedgers.com  Tue May  5 20:41:20 2009
    From: foldr at codedgers.com (Mikhail Glushenkov)
    Date: Wed, 06 May 2009 01:41:20 -0000
    Subject: [llvm-commits] [llvm] r71054 - in /llvm/trunk:
     test/LLVMC/ForwardAs.td tools/llvmc/doc/LLVMC-Reference.rst
     utils/TableGen/LLVMCConfigurationEmitter.cpp
    Message-ID: <200905060141.n461fKch020393@zion.cs.uiuc.edu>
    
    Author: foldr
    Date: Tue May  5 20:41:19 2009
    New Revision: 71054
    
    URL: http://llvm.org/viewvc/llvm-project?rev=71054&view=rev
    Log:
    The 'forward_as' property did not use its second argument.
    
    See PR4159 for details. Patch by Martin Nowack!
    
    Added:
        llvm/trunk/test/LLVMC/ForwardAs.td
    Modified:
        llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst
        llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp
    
    Added: llvm/trunk/test/LLVMC/ForwardAs.td
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/ForwardAs.td?rev=71054&view=auto
    
    ==============================================================================
    --- llvm/trunk/test/LLVMC/ForwardAs.td (added)
    +++ llvm/trunk/test/LLVMC/ForwardAs.td Tue May  5 20:41:19 2009
    @@ -0,0 +1,18 @@
    +// Check the fix for PR4159.
    +// http://llvm.org/bugs/show_bug.cgi?id=4159
    +// RUN: tblgen -I $srcroot/include --gen-llvmc %s -o %t
    +// RUN: grep unique_name %t
    +
    +include "llvm/CompilerDriver/Common.td"
    +
    +def OptList : OptionList<[(parameter_option "dummy", (extern))]>;
    +
    +def dummy_tool : Tool<[
    +(cmd_line "dummy_cmd"),
    +(in_language "dummy"),
    +(out_language "dummy"),
    +(actions (case
    +         (not_empty "dummy"), (forward_as "dummy", "unique_name")))
    +]>;
    +
    +def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>;
    
    Modified: llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst?rev=71054&r1=71053&r2=71054&view=diff
    
    ==============================================================================
    --- llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst (original)
    +++ llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Tue May  5 20:41:19 2009
    @@ -529,7 +529,7 @@
     
        - ``forward_as`` - Change the name of an option, but forward the
          argument unchanged.
    -     Example: ``(forward_as "O0" "--disable-optimization")``.
    +     Example: ``(forward_as "O0", "--disable-optimization")``.
     
        - ``output_suffix`` - modify the output suffix of this
          tool.
    
    Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=71054&r1=71053&r2=71054&view=diff
    
    ==============================================================================
    --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original)
    +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Tue May  5 20:41:19 2009
    @@ -1444,7 +1444,7 @@
         else if (ActionName == "forward_as") {
           checkNumberOfArguments(&Dag, 2);
           const std::string& Name = InitPtrToString(Dag.getArg(0));
    -      const std::string& NewName = InitPtrToString(Dag.getArg(0));
    +      const std::string& NewName = InitPtrToString(Dag.getArg(1));
           EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name),
                                                 IndentLevel, NewName, O);
         }
    
    
    
    
    From lhames at gmail.com  Tue May  5 21:36:28 2009
    From: lhames at gmail.com (Lang Hames)
    Date: Wed, 06 May 2009 02:36:28 -0000
    Subject: [llvm-commits] [llvm] r71057 - in /llvm/trunk:
     lib/CodeGen/RegAllocLinearScan.cpp lib/CodeGen/RegAllocPBQP.cpp
     lib/CodeGen/Spiller.cpp lib/CodeGen/Spiller.h
     lib/CodeGen/VirtRegRewriter.cpp lib/CodeGen/VirtRegRewriter.h
     test/CodeGen/X86/2009-03-16-SpillerBug.ll
    Message-ID: <200905060236.n462aYpI022331@zion.cs.uiuc.edu>
    
    Author: lhames
    Date: Tue May  5 21:36:21 2009
    New Revision: 71057
    
    URL: http://llvm.org/viewvc/llvm-project?rev=71057&view=rev
    Log:
    Renamed Spiller classes (plus uses and related files) to VirtRegRewriter.
    
    Added:
        llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp
          - copied, changed from r71041, llvm/trunk/lib/CodeGen/Spiller.cpp
        llvm/trunk/lib/CodeGen/VirtRegRewriter.h
          - copied, changed from r71041, llvm/trunk/lib/CodeGen/Spiller.h
    Removed:
        llvm/trunk/lib/CodeGen/Spiller.cpp
        llvm/trunk/lib/CodeGen/Spiller.h
    Modified:
        llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
        llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp
        llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll
    
    Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=71057&r1=71056&r2=71057&view=diff
    
    ==============================================================================
    --- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original)
    +++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Tue May  5 21:36:21 2009
    @@ -13,7 +13,7 @@
     
     #define DEBUG_TYPE "regalloc"
     #include "VirtRegMap.h"
    -#include "Spiller.h"
    +#include "VirtRegRewriter.h"
     #include "llvm/Function.h"
     #include "llvm/CodeGen/LiveIntervalAnalysis.h"
     #include "llvm/CodeGen/LiveStackAnalysis.h"
    @@ -125,7 +125,7 @@
         /// vrm_ - Tracks register assignments.
         VirtRegMap* vrm_;
     
    -    std::auto_ptr spiller_;
    +    std::auto_ptr rewriter_;
     
       public:
         virtual const char* getPassName() const {
    @@ -404,14 +404,14 @@
       initRegUses();
     
       vrm_ = &getAnalysis();
    -  if (!spiller_.get()) spiller_.reset(createSpiller());
    +  if (!rewriter_.get()) rewriter_.reset(createVirtRegRewriter());
     
       initIntervalSets();
     
       linearScan();
     
       // Rewrite spill code and update the PhysRegsUsed set.
    -  spiller_->runOnMachineFunction(*mf_, *vrm_, li_);
    +  rewriter_->runOnMachineFunction(*mf_, *vrm_, li_);
     
       assert(unhandled_.empty() && "Unhandled live intervals remain!");
     
    
    Modified: llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp?rev=71057&r1=71056&r2=71057&view=diff
    
    ==============================================================================
    --- llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp (original)
    +++ llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp Tue May  5 21:36:21 2009
    @@ -33,7 +33,7 @@
     
     #include "PBQP.h"
     #include "VirtRegMap.h"
    -#include "Spiller.h"
    +#include "VirtRegRewriter.h"
     #include "llvm/CodeGen/LiveIntervalAnalysis.h"
     #include "llvm/CodeGen/LiveStackAnalysis.h"
     #include "llvm/CodeGen/MachineFunctionPass.h"
    @@ -850,9 +850,10 @@
     
       DOUT << "Post alloc VirtRegMap:\n" << *vrm << "\n";
     
    -  // Run spiller
    -  std::auto_ptr spiller(createSpiller());
    -  spiller->runOnMachineFunction(*mf, *vrm, lis);
    +  // Run rewriter
    +  std::auto_ptr rewriter(createVirtRegRewriter());
    +
    +  rewriter->runOnMachineFunction(*mf, *vrm, lis);
     
       return true;
     }
    
    Removed: llvm/trunk/lib/CodeGen/Spiller.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Spiller.cpp?rev=71056&view=auto
    
    ==============================================================================
    --- llvm/trunk/lib/CodeGen/Spiller.cpp (original)
    +++ llvm/trunk/lib/CodeGen/Spiller.cpp (removed)
    @@ -1,1896 +0,0 @@
    -//===-- llvm/CodeGen/Spiller.cpp -  Spiller -------------------------------===//
    -//
    -//                     The LLVM Compiler Infrastructure
    -//
    -// This file is distributed under the University of Illinois Open Source
    -// License. See LICENSE.TXT for details.
    -//
    -//===----------------------------------------------------------------------===//
    -
    -#define DEBUG_TYPE "spiller"
    -#include "Spiller.h"
    -#include "llvm/Support/Compiler.h"
    -#include "llvm/ADT/DepthFirstIterator.h"
    -#include "llvm/ADT/Statistic.h"
    -#include "llvm/ADT/STLExtras.h"
    -#include 
    -using namespace llvm;
    -
    -STATISTIC(NumDSE     , "Number of dead stores elided");
    -STATISTIC(NumDSS     , "Number of dead spill slots removed");
    -STATISTIC(NumCommutes, "Number of instructions commuted");
    -STATISTIC(NumDRM     , "Number of re-materializable defs elided");
    -STATISTIC(NumStores  , "Number of stores added");
    -STATISTIC(NumPSpills , "Number of physical register spills");
    -STATISTIC(NumOmitted , "Number of reloads omited");
    -STATISTIC(NumAvoided , "Number of reloads deemed unnecessary");
    -STATISTIC(NumCopified, "Number of available reloads turned into copies");
    -STATISTIC(NumReMats  , "Number of re-materialization");
    -STATISTIC(NumLoads   , "Number of loads added");
    -STATISTIC(NumReused  , "Number of values reused");
    -STATISTIC(NumDCE     , "Number of copies elided");
    -STATISTIC(NumSUnfold , "Number of stores unfolded");
    -STATISTIC(NumModRefUnfold, "Number of modref unfolded");
    -
    -namespace {
    -  enum SpillerName { simple, local };
    -}
    -
    -static cl::opt
    -SpillerOpt("spiller",
    -           cl::desc("Spiller to use: (default: local)"),
    -           cl::Prefix,
    -           cl::values(clEnumVal(simple, "simple spiller"),
    -                      clEnumVal(local,  "local spiller"),
    -                      clEnumValEnd),
    -           cl::init(local));
    -
    -// ****************************** //
    -// Simple Spiller Implementation  //
    -// ****************************** //
    -
    -Spiller::~Spiller() {}
    -
    -bool SimpleSpiller::runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM,
    -                                         LiveIntervals* LIs) {
    -  DOUT << "********** REWRITE MACHINE CODE **********\n";
    -  DOUT << "********** Function: " << MF.getFunction()->getName() << '\n';
    -  const TargetMachine &TM = MF.getTarget();
    -  const TargetInstrInfo &TII = *TM.getInstrInfo();
    -  const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
    -
    -
    -  // LoadedRegs - Keep track of which vregs are loaded, so that we only load
    -  // each vreg once (in the case where a spilled vreg is used by multiple
    -  // operands).  This is always smaller than the number of operands to the
    -  // current machine instr, so it should be small.
    -  std::vector LoadedRegs;
    -
    -  for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end();
    -       MBBI != E; ++MBBI) {
    -    DOUT << MBBI->getBasicBlock()->getName() << ":\n";
    -    MachineBasicBlock &MBB = *MBBI;
    -    for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
    -         MII != E; ++MII) {
    -      MachineInstr &MI = *MII;
    -      for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    -        MachineOperand &MO = MI.getOperand(i);
    -        if (MO.isReg() && MO.getReg()) {
    -          if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
    -            unsigned VirtReg = MO.getReg();
    -            unsigned SubIdx = MO.getSubReg();
    -            unsigned PhysReg = VRM.getPhys(VirtReg);
    -            unsigned RReg = SubIdx ? TRI.getSubReg(PhysReg, SubIdx) : PhysReg;
    -            if (!VRM.isAssignedReg(VirtReg)) {
    -              int StackSlot = VRM.getStackSlot(VirtReg);
    -              const TargetRegisterClass* RC = 
    -                                           MF.getRegInfo().getRegClass(VirtReg);
    -              
    -              if (MO.isUse() &&
    -                  std::find(LoadedRegs.begin(), LoadedRegs.end(), VirtReg)
    -                           == LoadedRegs.end()) {
    -                TII.loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot, RC);
    -                MachineInstr *LoadMI = prior(MII);
    -                VRM.addSpillSlotUse(StackSlot, LoadMI);
    -                LoadedRegs.push_back(VirtReg);
    -                ++NumLoads;
    -                DOUT << '\t' << *LoadMI;
    -              }
    -
    -              if (MO.isDef()) {
    -                TII.storeRegToStackSlot(MBB, next(MII), PhysReg, true,   
    -                                        StackSlot, RC);
    -                MachineInstr *StoreMI = next(MII);
    -                VRM.addSpillSlotUse(StackSlot, StoreMI);
    -                ++NumStores;
    -              }
    -            }
    -            MF.getRegInfo().setPhysRegUsed(RReg);
    -            MI.getOperand(i).setReg(RReg);
    -            MI.getOperand(i).setSubReg(0);
    -          } else {
    -            MF.getRegInfo().setPhysRegUsed(MO.getReg());
    -          }
    -        }
    -      }
    -
    -      DOUT << '\t' << MI;
    -      LoadedRegs.clear();
    -    }
    -  }
    -  return true;
    -}
    -
    -// ****************** //
    -// Utility Functions  //
    -// ****************** //
    -
    -/// InvalidateKill - A MI that defines the specified register is being deleted,
    -/// invalidate the register kill information.
    -static void InvalidateKill(unsigned Reg, BitVector &RegKills,
    -                           std::vector &KillOps) {
    -  if (RegKills[Reg]) {
    -    KillOps[Reg]->setIsKill(false);
    -    KillOps[Reg] = NULL;
    -    RegKills.reset(Reg);
    -  }
    -}
    -
    -/// findSinglePredSuccessor - Return via reference a vector of machine basic
    -/// blocks each of which is a successor of the specified BB and has no other
    -/// predecessor.
    -static void findSinglePredSuccessor(MachineBasicBlock *MBB,
    -                                   SmallVectorImpl &Succs) {
    -  for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
    -         SE = MBB->succ_end(); SI != SE; ++SI) {
    -    MachineBasicBlock *SuccMBB = *SI;
    -    if (SuccMBB->pred_size() == 1)
    -      Succs.push_back(SuccMBB);
    -  }
    -}
    -
    -/// InvalidateKills - MI is going to be deleted. If any of its operands are
    -/// marked kill, then invalidate the information.
    -static void InvalidateKills(MachineInstr &MI, BitVector &RegKills,
    -                            std::vector &KillOps,
    -                            SmallVector *KillRegs = NULL) {
    -  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    -    MachineOperand &MO = MI.getOperand(i);
    -    if (!MO.isReg() || !MO.isUse() || !MO.isKill())
    -      continue;
    -    unsigned Reg = MO.getReg();
    -    if (TargetRegisterInfo::isVirtualRegister(Reg))
    -      continue;
    -    if (KillRegs)
    -      KillRegs->push_back(Reg);
    -    assert(Reg < KillOps.size());
    -    if (KillOps[Reg] == &MO) {
    -      RegKills.reset(Reg);
    -      KillOps[Reg] = NULL;
    -    }
    -  }
    -}
    -
    -/// InvalidateRegDef - If the def operand of the specified def MI is now dead
    -/// (since it's spill instruction is removed), mark it isDead. Also checks if
    -/// the def MI has other definition operands that are not dead. Returns it by
    -/// reference.
    -static bool InvalidateRegDef(MachineBasicBlock::iterator I,
    -                             MachineInstr &NewDef, unsigned Reg,
    -                             bool &HasLiveDef) {
    -  // Due to remat, it's possible this reg isn't being reused. That is,
    -  // the def of this reg (by prev MI) is now dead.
    -  MachineInstr *DefMI = I;
    -  MachineOperand *DefOp = NULL;
    -  for (unsigned i = 0, e = DefMI->getNumOperands(); i != e; ++i) {
    -    MachineOperand &MO = DefMI->getOperand(i);
    -    if (MO.isReg() && MO.isDef()) {
    -      if (MO.getReg() == Reg)
    -        DefOp = &MO;
    -      else if (!MO.isDead())
    -        HasLiveDef = true;
    -    }
    -  }
    -  if (!DefOp)
    -    return false;
    -
    -  bool FoundUse = false, Done = false;
    -  MachineBasicBlock::iterator E = &NewDef;
    -  ++I; ++E;
    -  for (; !Done && I != E; ++I) {
    -    MachineInstr *NMI = I;
    -    for (unsigned j = 0, ee = NMI->getNumOperands(); j != ee; ++j) {
    -      MachineOperand &MO = NMI->getOperand(j);
    -      if (!MO.isReg() || MO.getReg() != Reg)
    -        continue;
    -      if (MO.isUse())
    -        FoundUse = true;
    -      Done = true; // Stop after scanning all the operands of this MI.
    -    }
    -  }
    -  if (!FoundUse) {
    -    // Def is dead!
    -    DefOp->setIsDead();
    -    return true;
    -  }
    -  return false;
    -}
    -
    -/// UpdateKills - Track and update kill info. If a MI reads a register that is
    -/// marked kill, then it must be due to register reuse. Transfer the kill info
    -/// over.
    -static void UpdateKills(MachineInstr &MI, BitVector &RegKills,
    -                        std::vector &KillOps,
    -                        const TargetRegisterInfo* TRI) {
    -  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    -    MachineOperand &MO = MI.getOperand(i);
    -    if (!MO.isReg() || !MO.isUse())
    -      continue;
    -    unsigned Reg = MO.getReg();
    -    if (Reg == 0)
    -      continue;
    -    
    -    if (RegKills[Reg] && KillOps[Reg]->getParent() != &MI) {
    -      // That can't be right. Register is killed but not re-defined and it's
    -      // being reused. Let's fix that.
    -      KillOps[Reg]->setIsKill(false);
    -      KillOps[Reg] = NULL;
    -      RegKills.reset(Reg);
    -      if (!MI.isRegTiedToDefOperand(i))
    -        // Unless it's a two-address operand, this is the new kill.
    -        MO.setIsKill();
    -    }
    -    if (MO.isKill()) {
    -      RegKills.set(Reg);
    -      KillOps[Reg] = &MO;
    -    }
    -  }
    -
    -  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    -    const MachineOperand &MO = MI.getOperand(i);
    -    if (!MO.isReg() || !MO.isDef())
    -      continue;
    -    unsigned Reg = MO.getReg();
    -    RegKills.reset(Reg);
    -    KillOps[Reg] = NULL;
    -    // It also defines (or partially define) aliases.
    -    for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS) {
    -      RegKills.reset(*AS);
    -      KillOps[*AS] = NULL;
    -    }
    -  }
    -}
    -
    -/// ReMaterialize - Re-materialize definition for Reg targetting DestReg.
    -///
    -static void ReMaterialize(MachineBasicBlock &MBB,
    -                          MachineBasicBlock::iterator &MII,
    -                          unsigned DestReg, unsigned Reg,
    -                          const TargetInstrInfo *TII,
    -                          const TargetRegisterInfo *TRI,
    -                          VirtRegMap &VRM) {
    -  TII->reMaterialize(MBB, MII, DestReg, VRM.getReMaterializedMI(Reg));
    -  MachineInstr *NewMI = prior(MII);
    -  for (unsigned i = 0, e = NewMI->getNumOperands(); i != e; ++i) {
    -    MachineOperand &MO = NewMI->getOperand(i);
    -    if (!MO.isReg() || MO.getReg() == 0)
    -      continue;
    -    unsigned VirtReg = MO.getReg();
    -    if (TargetRegisterInfo::isPhysicalRegister(VirtReg))
    -      continue;
    -    assert(MO.isUse());
    -    unsigned SubIdx = MO.getSubReg();
    -    unsigned Phys = VRM.getPhys(VirtReg);
    -    assert(Phys);
    -    unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys;
    -    MO.setReg(RReg);
    -    MO.setSubReg(0);
    -  }
    -  ++NumReMats;
    -}
    -
    -/// findSuperReg - Find the SubReg's super-register of given register class
    -/// where its SubIdx sub-register is SubReg.
    -static unsigned findSuperReg(const TargetRegisterClass *RC, unsigned SubReg,
    -                             unsigned SubIdx, const TargetRegisterInfo *TRI) {
    -  for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end();
    -       I != E; ++I) {
    -    unsigned Reg = *I;
    -    if (TRI->getSubReg(Reg, SubIdx) == SubReg)
    -      return Reg;
    -  }
    -  return 0;
    -}
    -
    -// ******************************** //
    -// Available Spills Implementation  //
    -// ******************************** //
    -
    -/// disallowClobberPhysRegOnly - Unset the CanClobber bit of the specified
    -/// stackslot register. The register is still available but is no longer
    -/// allowed to be modifed.
    -void AvailableSpills::disallowClobberPhysRegOnly(unsigned PhysReg) {
    -  std::multimap::iterator I =
    -    PhysRegsAvailable.lower_bound(PhysReg);
    -  while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
    -    int SlotOrReMat = I->second;
    -    I++;
    -    assert((SpillSlotsOrReMatsAvailable[SlotOrReMat] >> 1) == PhysReg &&
    -           "Bidirectional map mismatch!");
    -    SpillSlotsOrReMatsAvailable[SlotOrReMat] &= ~1;
    -    DOUT << "PhysReg " << TRI->getName(PhysReg)
    -         << " copied, it is available for use but can no longer be modified\n";
    -  }
    -}
    -
    -/// disallowClobberPhysReg - Unset the CanClobber bit of the specified
    -/// stackslot register and its aliases. The register and its aliases may
    -/// still available but is no longer allowed to be modifed.
    -void AvailableSpills::disallowClobberPhysReg(unsigned PhysReg) {
    -  for (const unsigned *AS = TRI->getAliasSet(PhysReg); *AS; ++AS)
    -    disallowClobberPhysRegOnly(*AS);
    -  disallowClobberPhysRegOnly(PhysReg);
    -}
    -
    -/// ClobberPhysRegOnly - This is called when the specified physreg changes
    -/// value.  We use this to invalidate any info about stuff we thing lives in it.
    -void AvailableSpills::ClobberPhysRegOnly(unsigned PhysReg) {
    -  std::multimap::iterator I =
    -    PhysRegsAvailable.lower_bound(PhysReg);
    -  while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
    -    int SlotOrReMat = I->second;
    -    PhysRegsAvailable.erase(I++);
    -    assert((SpillSlotsOrReMatsAvailable[SlotOrReMat] >> 1) == PhysReg &&
    -           "Bidirectional map mismatch!");
    -    SpillSlotsOrReMatsAvailable.erase(SlotOrReMat);
    -    DOUT << "PhysReg " << TRI->getName(PhysReg)
    -         << " clobbered, invalidating ";
    -    if (SlotOrReMat > VirtRegMap::MAX_STACK_SLOT)
    -      DOUT << "RM#" << SlotOrReMat-VirtRegMap::MAX_STACK_SLOT-1 << "\n";
    -    else
    -      DOUT << "SS#" << SlotOrReMat << "\n";
    -  }
    -}
    -
    -/// ClobberPhysReg - This is called when the specified physreg changes
    -/// value.  We use this to invalidate any info about stuff we thing lives in
    -/// it and any of its aliases.
    -void AvailableSpills::ClobberPhysReg(unsigned PhysReg) {
    -  for (const unsigned *AS = TRI->getAliasSet(PhysReg); *AS; ++AS)
    -    ClobberPhysRegOnly(*AS);
    -  ClobberPhysRegOnly(PhysReg);
    -}
    -
    -/// AddAvailableRegsToLiveIn - Availability information is being kept coming
    -/// into the specified MBB. Add available physical registers as potential
    -/// live-in's. If they are reused in the MBB, they will be added to the
    -/// live-in set to make register scavenger and post-allocation scheduler.
    -void AvailableSpills::AddAvailableRegsToLiveIn(MachineBasicBlock &MBB,
    -                                        BitVector &RegKills,
    -                                        std::vector &KillOps) {
    -  std::set NotAvailable;
    -  for (std::multimap::iterator
    -         I = PhysRegsAvailable.begin(), E = PhysRegsAvailable.end();
    -       I != E; ++I) {
    -    unsigned Reg = I->first;
    -    const TargetRegisterClass* RC = TRI->getPhysicalRegisterRegClass(Reg);
    -    // FIXME: A temporary workaround. We can't reuse available value if it's
    -    // not safe to move the def of the virtual register's class. e.g.
    -    // X86::RFP* register classes. Do not add it as a live-in.
    -    if (!TII->isSafeToMoveRegClassDefs(RC))
    -      // This is no longer available.
    -      NotAvailable.insert(Reg);
    -    else {
    -      MBB.addLiveIn(Reg);
    -      InvalidateKill(Reg, RegKills, KillOps);
    -    }
    -
    -    // Skip over the same register.
    -    std::multimap::iterator NI = next(I);
    -    while (NI != E && NI->first == Reg) {
    -      ++I;
    -      ++NI;
    -    }
    -  }
    -
    -  for (std::set::iterator I = NotAvailable.begin(),
    -         E = NotAvailable.end(); I != E; ++I) {
    -    ClobberPhysReg(*I);
    -    for (const unsigned *SubRegs = TRI->getSubRegisters(*I);
    -       *SubRegs; ++SubRegs)
    -      ClobberPhysReg(*SubRegs);
    -  }
    -}
    -
    -/// ModifyStackSlotOrReMat - This method is called when the value in a stack
    -/// slot changes.  This removes information about which register the previous
    -/// value for this slot lives in (as the previous value is dead now).
    -void AvailableSpills::ModifyStackSlotOrReMat(int SlotOrReMat) {
    -  std::map::iterator It =
    -    SpillSlotsOrReMatsAvailable.find(SlotOrReMat);
    -  if (It == SpillSlotsOrReMatsAvailable.end()) return;
    -  unsigned Reg = It->second >> 1;
    -  SpillSlotsOrReMatsAvailable.erase(It);
    -  
    -  // This register may hold the value of multiple stack slots, only remove this
    -  // stack slot from the set of values the register contains.
    -  std::multimap::iterator I = PhysRegsAvailable.lower_bound(Reg);
    -  for (; ; ++I) {
    -    assert(I != PhysRegsAvailable.end() && I->first == Reg &&
    -           "Map inverse broken!");
    -    if (I->second == SlotOrReMat) break;
    -  }
    -  PhysRegsAvailable.erase(I);
    -}
    -
    -// ************************** //
    -// Reuse Info Implementation  //
    -// ************************** //
    -
    -/// GetRegForReload - We are about to emit a reload into PhysReg.  If there
    -/// is some other operand that is using the specified register, either pick
    -/// a new register to use, or evict the previous reload and use this reg.
    -unsigned ReuseInfo::GetRegForReload(unsigned PhysReg, MachineInstr *MI,
    -                         AvailableSpills &Spills,
    -                         std::vector &MaybeDeadStores,
    -                         SmallSet &Rejected,
    -                         BitVector &RegKills,
    -                         std::vector &KillOps,
    -                         VirtRegMap &VRM) {
    -  const TargetInstrInfo* TII = MI->getParent()->getParent()->getTarget()
    -                               .getInstrInfo();
    -  
    -  if (Reuses.empty()) return PhysReg;  // This is most often empty.
    -
    -  for (unsigned ro = 0, e = Reuses.size(); ro != e; ++ro) {
    -    ReusedOp &Op = Reuses[ro];
    -    // If we find some other reuse that was supposed to use this register
    -    // exactly for its reload, we can change this reload to use ITS reload
    -    // register. That is, unless its reload register has already been
    -    // considered and subsequently rejected because it has also been reused
    -    // by another operand.
    -    if (Op.PhysRegReused == PhysReg &&
    -        Rejected.count(Op.AssignedPhysReg) == 0) {
    -      // Yup, use the reload register that we didn't use before.
    -      unsigned NewReg = Op.AssignedPhysReg;
    -      Rejected.insert(PhysReg);
    -      return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores, Rejected,
    -                             RegKills, KillOps, VRM);
    -    } else {
    -      // Otherwise, we might also have a problem if a previously reused
    -      // value aliases the new register.  If so, codegen the previous reload
    -      // and use this one.          
    -      unsigned PRRU = Op.PhysRegReused;
    -      const TargetRegisterInfo *TRI = Spills.getRegInfo();
    -      if (TRI->areAliases(PRRU, PhysReg)) {
    -        // Okay, we found out that an alias of a reused register
    -        // was used.  This isn't good because it means we have
    -        // to undo a previous reuse.
    -        MachineBasicBlock *MBB = MI->getParent();
    -        const TargetRegisterClass *AliasRC =
    -          MBB->getParent()->getRegInfo().getRegClass(Op.VirtReg);
    -
    -        // Copy Op out of the vector and remove it, we're going to insert an
    -        // explicit load for it.
    -        ReusedOp NewOp = Op;
    -        Reuses.erase(Reuses.begin()+ro);
    -
    -        // Ok, we're going to try to reload the assigned physreg into the
    -        // slot that we were supposed to in the first place.  However, that
    -        // register could hold a reuse.  Check to see if it conflicts or
    -        // would prefer us to use a different register.
    -        unsigned NewPhysReg = GetRegForReload(NewOp.AssignedPhysReg,
    -                                              MI, Spills, MaybeDeadStores,
    -                                          Rejected, RegKills, KillOps, VRM);
    -        
    -        MachineBasicBlock::iterator MII = MI;
    -        if (NewOp.StackSlotOrReMat > VirtRegMap::MAX_STACK_SLOT) {
    -          ReMaterialize(*MBB, MII, NewPhysReg, NewOp.VirtReg, TII, TRI,VRM);
    -        } else {
    -          TII->loadRegFromStackSlot(*MBB, MII, NewPhysReg,
    -                                    NewOp.StackSlotOrReMat, AliasRC);
    -          MachineInstr *LoadMI = prior(MII);
    -          VRM.addSpillSlotUse(NewOp.StackSlotOrReMat, LoadMI);
    -          // Any stores to this stack slot are not dead anymore.
    -          MaybeDeadStores[NewOp.StackSlotOrReMat] = NULL;            
    -          ++NumLoads;
    -        }
    -        Spills.ClobberPhysReg(NewPhysReg);
    -        Spills.ClobberPhysReg(NewOp.PhysRegReused);
    -
    -        unsigned SubIdx = MI->getOperand(NewOp.Operand).getSubReg();
    -        unsigned RReg = SubIdx ? TRI->getSubReg(NewPhysReg, SubIdx) : NewPhysReg;
    -        MI->getOperand(NewOp.Operand).setReg(RReg);
    -        MI->getOperand(NewOp.Operand).setSubReg(0);
    -
    -        Spills.addAvailable(NewOp.StackSlotOrReMat, NewPhysReg);
    -        --MII;
    -        UpdateKills(*MII, RegKills, KillOps, TRI);
    -        DOUT << '\t' << *MII;
    -        
    -        DOUT << "Reuse undone!\n";
    -        --NumReused;
    -        
    -        // Finally, PhysReg is now available, go ahead and use it.
    -        return PhysReg;
    -      }
    -    }
    -  }
    -  return PhysReg;
    -}
    -
    -// ***************************** //
    -// Local Spiller Implementation  //
    -// ***************************** //
    -
    -bool LocalSpiller::runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM,
    -                                        LiveIntervals* LIs) {
    -  RegInfo = &MF.getRegInfo(); 
    -  TRI = MF.getTarget().getRegisterInfo();
    -  TII = MF.getTarget().getInstrInfo();
    -  AllocatableRegs = TRI->getAllocatableSet(MF);
    -  DOUT << "\n**** Local spiller rewriting function '"
    -       << MF.getFunction()->getName() << "':\n";
    -  DOUT << "**** Machine Instrs (NOTE! Does not include spills and reloads!)"
    -          " ****\n";
    -  DEBUG(MF.dump());
    -
    -  // Spills - Keep track of which spilled values are available in physregs
    -  // so that we can choose to reuse the physregs instead of emitting
    -  // reloads. This is usually refreshed per basic block.
    -  AvailableSpills Spills(TRI, TII);
    -
    -  // Keep track of kill information.
    -  BitVector RegKills(TRI->getNumRegs());
    -  std::vector KillOps;
    -  KillOps.resize(TRI->getNumRegs(), NULL);
    -
    -  // SingleEntrySuccs - Successor blocks which have a single predecessor.
    -  SmallVector SinglePredSuccs;
    -  SmallPtrSet EarlyVisited;
    -
    -  // Traverse the basic blocks depth first.
    -  MachineBasicBlock *Entry = MF.begin();
    -  SmallPtrSet Visited;
    -  for (df_ext_iterator >
    -         DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited);
    -       DFI != E; ++DFI) {
    -    MachineBasicBlock *MBB = *DFI;
    -    if (!EarlyVisited.count(MBB))
    -      RewriteMBB(*MBB, VRM, LIs, Spills, RegKills, KillOps);
    -
    -    // If this MBB is the only predecessor of a successor. Keep the
    -    // availability information and visit it next.
    -    do {
    -      // Keep visiting single predecessor successor as long as possible.
    -      SinglePredSuccs.clear();
    -      findSinglePredSuccessor(MBB, SinglePredSuccs);
    -      if (SinglePredSuccs.empty())
    -        MBB = 0;
    -      else {
    -        // FIXME: More than one successors, each of which has MBB has
    -        // the only predecessor.
    -        MBB = SinglePredSuccs[0];
    -        if (!Visited.count(MBB) && EarlyVisited.insert(MBB)) {
    -          Spills.AddAvailableRegsToLiveIn(*MBB, RegKills, KillOps);
    -          RewriteMBB(*MBB, VRM, LIs, Spills, RegKills, KillOps);
    -        }
    -      }
    -    } while (MBB);
    -
    -    // Clear the availability info.
    -    Spills.clear();
    -  }
    -
    -  DOUT << "**** Post Machine Instrs ****\n";
    -  DEBUG(MF.dump());
    -
    -  // Mark unused spill slots.
    -  MachineFrameInfo *MFI = MF.getFrameInfo();
    -  int SS = VRM.getLowSpillSlot();
    -  if (SS != VirtRegMap::NO_STACK_SLOT)
    -    for (int e = VRM.getHighSpillSlot(); SS <= e; ++SS)
    -      if (!VRM.isSpillSlotUsed(SS)) {
    -        MFI->RemoveStackObject(SS);
    -        ++NumDSS;
    -      }
    -
    -  return true;
    -}
    -
    -
    -/// FoldsStackSlotModRef - Return true if the specified MI folds the specified
    -/// stack slot mod/ref. It also checks if it's possible to unfold the
    -/// instruction by having it define a specified physical register instead.
    -static bool FoldsStackSlotModRef(MachineInstr &MI, int SS, unsigned PhysReg,
    -                                 const TargetInstrInfo *TII,
    -                                 const TargetRegisterInfo *TRI,
    -                                 VirtRegMap &VRM) {
    -  if (VRM.hasEmergencySpills(&MI) || VRM.isSpillPt(&MI))
    -    return false;
    -
    -  bool Found = false;
    -  VirtRegMap::MI2VirtMapTy::const_iterator I, End;
    -  for (tie(I, End) = VRM.getFoldedVirts(&MI); I != End; ++I) {
    -    unsigned VirtReg = I->second.first;
    -    VirtRegMap::ModRef MR = I->second.second;
    -    if (MR & VirtRegMap::isModRef)
    -      if (VRM.getStackSlot(VirtReg) == SS) {
    -        Found= TII->getOpcodeAfterMemoryUnfold(MI.getOpcode(), true, true) != 0;
    -        break;
    -      }
    -  }
    -  if (!Found)
    -    return false;
    -
    -  // Does the instruction uses a register that overlaps the scratch register?
    -  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    -    MachineOperand &MO = MI.getOperand(i);
    -    if (!MO.isReg() || MO.getReg() == 0)
    -      continue;
    -    unsigned Reg = MO.getReg();
    -    if (TargetRegisterInfo::isVirtualRegister(Reg)) {
    -      if (!VRM.hasPhys(Reg))
    -        continue;
    -      Reg = VRM.getPhys(Reg);
    -    }
    -    if (TRI->regsOverlap(PhysReg, Reg))
    -      return false;
    -  }
    -  return true;
    -}
    -
    -/// FindFreeRegister - Find a free register of a given register class by looking
    -/// at (at most) the last two machine instructions.
    -static unsigned FindFreeRegister(MachineBasicBlock::iterator MII,
    -                                 MachineBasicBlock &MBB,
    -                                 const TargetRegisterClass *RC,
    -                                 const TargetRegisterInfo *TRI,
    -                                 BitVector &AllocatableRegs) {
    -  BitVector Defs(TRI->getNumRegs());
    -  BitVector Uses(TRI->getNumRegs());
    -  SmallVector LocalUses;
    -  SmallVector Kills;
    -
    -  // Take a look at 2 instructions at most.
    -  for (unsigned Count = 0; Count < 2; ++Count) {
    -    if (MII == MBB.begin())
    -      break;
    -    MachineInstr *PrevMI = prior(MII);
    -    for (unsigned i = 0, e = PrevMI->getNumOperands(); i != e; ++i) {
    -      MachineOperand &MO = PrevMI->getOperand(i);
    -      if (!MO.isReg() || MO.getReg() == 0)
    -        continue;
    -      unsigned Reg = MO.getReg();
    -      if (MO.isDef()) {
    -        Defs.set(Reg);
    -        for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS)
    -          Defs.set(*AS);
    -      } else  {
    -        LocalUses.push_back(Reg);
    -        if (MO.isKill() && AllocatableRegs[Reg])
    -          Kills.push_back(Reg);
    -      }
    -    }
    -
    -    for (unsigned i = 0, e = Kills.size(); i != e; ++i) {
    -      unsigned Kill = Kills[i];
    -      if (!Defs[Kill] && !Uses[Kill] &&
    -          TRI->getPhysicalRegisterRegClass(Kill) == RC)
    -        return Kill;
    -    }
    -    for (unsigned i = 0, e = LocalUses.size(); i != e; ++i) {
    -      unsigned Reg = LocalUses[i];
    -      Uses.set(Reg);
    -      for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS)
    -        Uses.set(*AS);
    -    }
    -
    -    MII = PrevMI;
    -  }
    -
    -  return 0;
    -}
    -
    -static
    -void AssignPhysToVirtReg(MachineInstr *MI, unsigned VirtReg, unsigned PhysReg) {
    -  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
    -    MachineOperand &MO = MI->getOperand(i);
    -    if (MO.isReg() && MO.getReg() == VirtReg)
    -      MO.setReg(PhysReg);
    -  }
    -}
    -
    -/// OptimizeByUnfold2 - Unfold a series of load / store folding instructions if
    -/// a scratch register is available.
    -///     xorq  %r12, %r13
    -///     addq  %rax, -184(%rbp)
    -///     addq  %r13, -184(%rbp)
    -/// ==>
    -///     xorq  %r12, %r13
    -///     movq  -184(%rbp), %r12
    -///     addq  %rax, %r12
    -///     addq  %r13, %r12
    -///     movq  %r12, -184(%rbp)
    -bool LocalSpiller::OptimizeByUnfold2(unsigned VirtReg, int SS,
    -                                    MachineBasicBlock &MBB,
    -                                    MachineBasicBlock::iterator &MII,
    -                                    std::vector &MaybeDeadStores,
    -                                    AvailableSpills &Spills,
    -                                    BitVector &RegKills,
    -                                    std::vector &KillOps,
    -                                    VirtRegMap &VRM) {
    -  MachineBasicBlock::iterator NextMII = next(MII);
    -  if (NextMII == MBB.end())
    -    return false;
    -
    -  if (TII->getOpcodeAfterMemoryUnfold(MII->getOpcode(), true, true) == 0)
    -    return false;
    -
    -  // Now let's see if the last couple of instructions happens to have freed up
    -  // a register.
    -  const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -  unsigned PhysReg = FindFreeRegister(MII, MBB, RC, TRI, AllocatableRegs);
    -  if (!PhysReg)
    -    return false;
    -
    -  MachineFunction &MF = *MBB.getParent();
    -  TRI = MF.getTarget().getRegisterInfo();
    -  MachineInstr &MI = *MII;
    -  if (!FoldsStackSlotModRef(MI, SS, PhysReg, TII, TRI, VRM))
    -    return false;
    -
    -  // If the next instruction also folds the same SS modref and can be unfoled,
    -  // then it's worthwhile to issue a load from SS into the free register and
    -  // then unfold these instructions.
    -  if (!FoldsStackSlotModRef(*NextMII, SS, PhysReg, TII, TRI, VRM))
    -    return false;
    -
    -  // Load from SS to the spare physical register.
    -  TII->loadRegFromStackSlot(MBB, MII, PhysReg, SS, RC);
    -  // This invalidates Phys.
    -  Spills.ClobberPhysReg(PhysReg);
    -  // Remember it's available.
    -  Spills.addAvailable(SS, PhysReg);
    -  MaybeDeadStores[SS] = NULL;
    -
    -  // Unfold current MI.
    -  SmallVector NewMIs;
    -  if (!TII->unfoldMemoryOperand(MF, &MI, VirtReg, false, false, NewMIs))
    -    assert(0 && "Unable unfold the load / store folding instruction!");
    -  assert(NewMIs.size() == 1);
    -  AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg);
    -  VRM.transferRestorePts(&MI, NewMIs[0]);
    -  MII = MBB.insert(MII, NewMIs[0]);
    -  InvalidateKills(MI, RegKills, KillOps);
    -  VRM.RemoveMachineInstrFromMaps(&MI);
    -  MBB.erase(&MI);
    -  ++NumModRefUnfold;
    -
    -  // Unfold next instructions that fold the same SS.
    -  do {
    -    MachineInstr &NextMI = *NextMII;
    -    NextMII = next(NextMII);
    -    NewMIs.clear();
    -    if (!TII->unfoldMemoryOperand(MF, &NextMI, VirtReg, false, false, NewMIs))
    -      assert(0 && "Unable unfold the load / store folding instruction!");
    -    assert(NewMIs.size() == 1);
    -    AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg);
    -    VRM.transferRestorePts(&NextMI, NewMIs[0]);
    -    MBB.insert(NextMII, NewMIs[0]);
    -    InvalidateKills(NextMI, RegKills, KillOps);
    -    VRM.RemoveMachineInstrFromMaps(&NextMI);
    -    MBB.erase(&NextMI);
    -    ++NumModRefUnfold;
    -  } while (FoldsStackSlotModRef(*NextMII, SS, PhysReg, TII, TRI, VRM));
    -
    -  // Store the value back into SS.
    -  TII->storeRegToStackSlot(MBB, NextMII, PhysReg, true, SS, RC);
    -  MachineInstr *StoreMI = prior(NextMII);
    -  VRM.addSpillSlotUse(SS, StoreMI);
    -  VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod);
    -
    -  return true;
    -}
    -
    -/// OptimizeByUnfold - Turn a store folding instruction into a load folding
    -/// instruction. e.g.
    -///     xorl  %edi, %eax
    -///     movl  %eax, -32(%ebp)
    -///     movl  -36(%ebp), %eax
    -///     orl   %eax, -32(%ebp)
    -/// ==>
    -///     xorl  %edi, %eax
    -///     orl   -36(%ebp), %eax
    -///     mov   %eax, -32(%ebp)
    -/// This enables unfolding optimization for a subsequent instruction which will
    -/// also eliminate the newly introduced store instruction.
    -bool LocalSpiller::OptimizeByUnfold(MachineBasicBlock &MBB,
    -                                    MachineBasicBlock::iterator &MII,
    -                                    std::vector &MaybeDeadStores,
    -                                    AvailableSpills &Spills,
    -                                    BitVector &RegKills,
    -                                    std::vector &KillOps,
    -                                    VirtRegMap &VRM) {
    -  MachineFunction &MF = *MBB.getParent();
    -  MachineInstr &MI = *MII;
    -  unsigned UnfoldedOpc = 0;
    -  unsigned UnfoldPR = 0;
    -  unsigned UnfoldVR = 0;
    -  int FoldedSS = VirtRegMap::NO_STACK_SLOT;
    -  VirtRegMap::MI2VirtMapTy::const_iterator I, End;
    -  for (tie(I, End) = VRM.getFoldedVirts(&MI); I != End; ) {
    -    // Only transform a MI that folds a single register.
    -    if (UnfoldedOpc)
    -      return false;
    -    UnfoldVR = I->second.first;
    -    VirtRegMap::ModRef MR = I->second.second;
    -    // MI2VirtMap be can updated which invalidate the iterator.
    -    // Increment the iterator first.
    -    ++I; 
    -    if (VRM.isAssignedReg(UnfoldVR))
    -      continue;
    -    // If this reference is not a use, any previous store is now dead.
    -    // Otherwise, the store to this stack slot is not dead anymore.
    -    FoldedSS = VRM.getStackSlot(UnfoldVR);
    -    MachineInstr* DeadStore = MaybeDeadStores[FoldedSS];
    -    if (DeadStore && (MR & VirtRegMap::isModRef)) {
    -      unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(FoldedSS);
    -      if (!PhysReg || !DeadStore->readsRegister(PhysReg))
    -        continue;
    -      UnfoldPR = PhysReg;
    -      UnfoldedOpc = TII->getOpcodeAfterMemoryUnfold(MI.getOpcode(),
    -                                                    false, true);
    -    }
    -  }
    -
    -  if (!UnfoldedOpc) {
    -    if (!UnfoldVR)
    -      return false;
    -
    -    // Look for other unfolding opportunities.
    -    return OptimizeByUnfold2(UnfoldVR, FoldedSS, MBB, MII,
    -                             MaybeDeadStores, Spills, RegKills, KillOps, VRM);
    -  }
    -
    -  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    -    MachineOperand &MO = MI.getOperand(i);
    -    if (!MO.isReg() || MO.getReg() == 0 || !MO.isUse())
    -      continue;
    -    unsigned VirtReg = MO.getReg();
    -    if (TargetRegisterInfo::isPhysicalRegister(VirtReg) || MO.getSubReg())
    -      continue;
    -    if (VRM.isAssignedReg(VirtReg)) {
    -      unsigned PhysReg = VRM.getPhys(VirtReg);
    -      if (PhysReg && TRI->regsOverlap(PhysReg, UnfoldPR))
    -        return false;
    -    } else if (VRM.isReMaterialized(VirtReg))
    -      continue;
    -    int SS = VRM.getStackSlot(VirtReg);
    -    unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS);
    -    if (PhysReg) {
    -      if (TRI->regsOverlap(PhysReg, UnfoldPR))
    -        return false;
    -      continue;
    -    }
    -    if (VRM.hasPhys(VirtReg)) {
    -      PhysReg = VRM.getPhys(VirtReg);
    -      if (!TRI->regsOverlap(PhysReg, UnfoldPR))
    -        continue;
    -    }
    -
    -    // Ok, we'll need to reload the value into a register which makes
    -    // it impossible to perform the store unfolding optimization later.
    -    // Let's see if it is possible to fold the load if the store is
    -    // unfolded. This allows us to perform the store unfolding
    -    // optimization.
    -    SmallVector NewMIs;
    -    if (TII->unfoldMemoryOperand(MF, &MI, UnfoldVR, false, false, NewMIs)) {
    -      assert(NewMIs.size() == 1);
    -      MachineInstr *NewMI = NewMIs.back();
    -      NewMIs.clear();
    -      int Idx = NewMI->findRegisterUseOperandIdx(VirtReg, false);
    -      assert(Idx != -1);
    -      SmallVector Ops;
    -      Ops.push_back(Idx);
    -      MachineInstr *FoldedMI = TII->foldMemoryOperand(MF, NewMI, Ops, SS);
    -      if (FoldedMI) {
    -        VRM.addSpillSlotUse(SS, FoldedMI);
    -        if (!VRM.hasPhys(UnfoldVR))
    -          VRM.assignVirt2Phys(UnfoldVR, UnfoldPR);
    -        VRM.virtFolded(VirtReg, FoldedMI, VirtRegMap::isRef);
    -        MII = MBB.insert(MII, FoldedMI);
    -        InvalidateKills(MI, RegKills, KillOps);
    -        VRM.RemoveMachineInstrFromMaps(&MI);
    -        MBB.erase(&MI);
    -        MF.DeleteMachineInstr(NewMI);
    -        return true;
    -      }
    -      MF.DeleteMachineInstr(NewMI);
    -    }
    -  }
    -
    -  return false;
    -}
    -
    -/// CommuteToFoldReload -
    -/// Look for
    -/// r1 = load fi#1
    -/// r1 = op r1, r2
    -/// store r1, fi#1
    -///
    -/// If op is commutable and r2 is killed, then we can xform these to
    -/// r2 = op r2, fi#1
    -/// store r2, fi#1
    -bool LocalSpiller::CommuteToFoldReload(MachineBasicBlock &MBB,
    -                                    MachineBasicBlock::iterator &MII,
    -                                    unsigned VirtReg, unsigned SrcReg, int SS,
    -                                    AvailableSpills &Spills,
    -                                    BitVector &RegKills,
    -                                    std::vector &KillOps,
    -                                    const TargetRegisterInfo *TRI,
    -                                    VirtRegMap &VRM) {
    -  if (MII == MBB.begin() || !MII->killsRegister(SrcReg))
    -    return false;
    -
    -  MachineFunction &MF = *MBB.getParent();
    -  MachineInstr &MI = *MII;
    -  MachineBasicBlock::iterator DefMII = prior(MII);
    -  MachineInstr *DefMI = DefMII;
    -  const TargetInstrDesc &TID = DefMI->getDesc();
    -  unsigned NewDstIdx;
    -  if (DefMII != MBB.begin() &&
    -      TID.isCommutable() &&
    -      TII->CommuteChangesDestination(DefMI, NewDstIdx)) {
    -    MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx);
    -    unsigned NewReg = NewDstMO.getReg();
    -    if (!NewDstMO.isKill() || TRI->regsOverlap(NewReg, SrcReg))
    -      return false;
    -    MachineInstr *ReloadMI = prior(DefMII);
    -    int FrameIdx;
    -    unsigned DestReg = TII->isLoadFromStackSlot(ReloadMI, FrameIdx);
    -    if (DestReg != SrcReg || FrameIdx != SS)
    -      return false;
    -    int UseIdx = DefMI->findRegisterUseOperandIdx(DestReg, false);
    -    if (UseIdx == -1)
    -      return false;
    -    unsigned DefIdx;
    -    if (!MI.isRegTiedToDefOperand(UseIdx, &DefIdx))
    -      return false;
    -    assert(DefMI->getOperand(DefIdx).isReg() &&
    -           DefMI->getOperand(DefIdx).getReg() == SrcReg);
    -
    -    // Now commute def instruction.
    -    MachineInstr *CommutedMI = TII->commuteInstruction(DefMI, true);
    -    if (!CommutedMI)
    -      return false;
    -    SmallVector Ops;
    -    Ops.push_back(NewDstIdx);
    -    MachineInstr *FoldedMI = TII->foldMemoryOperand(MF, CommutedMI, Ops, SS);
    -    // Not needed since foldMemoryOperand returns new MI.
    -    MF.DeleteMachineInstr(CommutedMI);
    -    if (!FoldedMI)
    -      return false;
    -
    -    VRM.addSpillSlotUse(SS, FoldedMI);
    -    VRM.virtFolded(VirtReg, FoldedMI, VirtRegMap::isRef);
    -    // Insert new def MI and spill MI.
    -    const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -    TII->storeRegToStackSlot(MBB, &MI, NewReg, true, SS, RC);
    -    MII = prior(MII);
    -    MachineInstr *StoreMI = MII;
    -    VRM.addSpillSlotUse(SS, StoreMI);
    -    VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod);
    -    MII = MBB.insert(MII, FoldedMI);  // Update MII to backtrack.
    -
    -    // Delete all 3 old instructions.
    -    InvalidateKills(*ReloadMI, RegKills, KillOps);
    -    VRM.RemoveMachineInstrFromMaps(ReloadMI);
    -    MBB.erase(ReloadMI);
    -    InvalidateKills(*DefMI, RegKills, KillOps);
    -    VRM.RemoveMachineInstrFromMaps(DefMI);
    -    MBB.erase(DefMI);
    -    InvalidateKills(MI, RegKills, KillOps);
    -    VRM.RemoveMachineInstrFromMaps(&MI);
    -    MBB.erase(&MI);
    -
    -    // If NewReg was previously holding value of some SS, it's now clobbered.
    -    // This has to be done now because it's a physical register. When this
    -    // instruction is re-visited, it's ignored.
    -    Spills.ClobberPhysReg(NewReg);
    -
    -    ++NumCommutes;
    -    return true;
    -  }
    -
    -  return false;
    -}
    -
    -/// SpillRegToStackSlot - Spill a register to a specified stack slot. Check if
    -/// the last store to the same slot is now dead. If so, remove the last store.
    -void LocalSpiller::SpillRegToStackSlot(MachineBasicBlock &MBB,
    -                                  MachineBasicBlock::iterator &MII,
    -                                  int Idx, unsigned PhysReg, int StackSlot,
    -                                  const TargetRegisterClass *RC,
    -                                  bool isAvailable, MachineInstr *&LastStore,
    -                                  AvailableSpills &Spills,
    -                                  SmallSet &ReMatDefs,
    -                                  BitVector &RegKills,
    -                                  std::vector &KillOps,
    -                                  VirtRegMap &VRM) {
    -  TII->storeRegToStackSlot(MBB, next(MII), PhysReg, true, StackSlot, RC);
    -  MachineInstr *StoreMI = next(MII);
    -  VRM.addSpillSlotUse(StackSlot, StoreMI);
    -  DOUT << "Store:\t" << *StoreMI;
    -
    -  // If there is a dead store to this stack slot, nuke it now.
    -  if (LastStore) {
    -    DOUT << "Removed dead store:\t" << *LastStore;
    -    ++NumDSE;
    -    SmallVector KillRegs;
    -    InvalidateKills(*LastStore, RegKills, KillOps, &KillRegs);
    -    MachineBasicBlock::iterator PrevMII = LastStore;
    -    bool CheckDef = PrevMII != MBB.begin();
    -    if (CheckDef)
    -      --PrevMII;
    -    VRM.RemoveMachineInstrFromMaps(LastStore);
    -    MBB.erase(LastStore);
    -    if (CheckDef) {
    -      // Look at defs of killed registers on the store. Mark the defs
    -      // as dead since the store has been deleted and they aren't
    -      // being reused.
    -      for (unsigned j = 0, ee = KillRegs.size(); j != ee; ++j) {
    -        bool HasOtherDef = false;
    -        if (InvalidateRegDef(PrevMII, *MII, KillRegs[j], HasOtherDef)) {
    -          MachineInstr *DeadDef = PrevMII;
    -          if (ReMatDefs.count(DeadDef) && !HasOtherDef) {
    -            // FIXME: This assumes a remat def does not have side
    -            // effects.
    -            VRM.RemoveMachineInstrFromMaps(DeadDef);
    -            MBB.erase(DeadDef);
    -            ++NumDRM;
    -          }
    -        }
    -      }
    -    }
    -  }
    -
    -  LastStore = next(MII);
    -
    -  // If the stack slot value was previously available in some other
    -  // register, change it now.  Otherwise, make the register available,
    -  // in PhysReg.
    -  Spills.ModifyStackSlotOrReMat(StackSlot);
    -  Spills.ClobberPhysReg(PhysReg);
    -  Spills.addAvailable(StackSlot, PhysReg, isAvailable);
    -  ++NumStores;
    -}
    -
    -/// TransferDeadness - A identity copy definition is dead and it's being
    -/// removed. Find the last def or use and mark it as dead / kill.
    -void LocalSpiller::TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
    -                                    unsigned Reg, BitVector &RegKills,
    -                                    std::vector &KillOps) {
    -  int LastUDDist = -1;
    -  MachineInstr *LastUDMI = NULL;
    -  for (MachineRegisterInfo::reg_iterator RI = RegInfo->reg_begin(Reg),
    -         RE = RegInfo->reg_end(); RI != RE; ++RI) {
    -    MachineInstr *UDMI = &*RI;
    -    if (UDMI->getParent() != MBB)
    -      continue;
    -    DenseMap::iterator DI = DistanceMap.find(UDMI);
    -    if (DI == DistanceMap.end() || DI->second > CurDist)
    -      continue;
    -    if ((int)DI->second < LastUDDist)
    -      continue;
    -    LastUDDist = DI->second;
    -    LastUDMI = UDMI;
    -  }
    -
    -  if (LastUDMI) {
    -    MachineOperand *LastUD = NULL;
    -    for (unsigned i = 0, e = LastUDMI->getNumOperands(); i != e; ++i) {
    -      MachineOperand &MO = LastUDMI->getOperand(i);
    -      if (!MO.isReg() || MO.getReg() != Reg)
    -        continue;
    -      if (!LastUD || (LastUD->isUse() && MO.isDef()))
    -        LastUD = &MO;
    -      if (LastUDMI->isRegTiedToDefOperand(i))
    -        return;
    -    }
    -    if (LastUD->isDef())
    -      LastUD->setIsDead();
    -    else {
    -      LastUD->setIsKill();
    -      RegKills.set(Reg);
    -      KillOps[Reg] = LastUD;
    -    }
    -  }
    -}
    -
    -/// rewriteMBB - Keep track of which spills are available even after the
    -/// register allocator is done with them.  If possible, avid reloading vregs.
    -void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
    -                              LiveIntervals *LIs,
    -                              AvailableSpills &Spills, BitVector &RegKills,
    -                              std::vector &KillOps) {
    -  DOUT << "\n**** Local spiller rewriting MBB '"
    -       << MBB.getBasicBlock()->getName() << "':\n";
    -
    -  MachineFunction &MF = *MBB.getParent();
    -  
    -  // MaybeDeadStores - When we need to write a value back into a stack slot,
    -  // keep track of the inserted store.  If the stack slot value is never read
    -  // (because the value was used from some available register, for example), and
    -  // subsequently stored to, the original store is dead.  This map keeps track
    -  // of inserted stores that are not used.  If we see a subsequent store to the
    -  // same stack slot, the original store is deleted.
    -  std::vector MaybeDeadStores;
    -  MaybeDeadStores.resize(MF.getFrameInfo()->getObjectIndexEnd(), NULL);
    -
    -  // ReMatDefs - These are rematerializable def MIs which are not deleted.
    -  SmallSet ReMatDefs;
    -
    -  // Clear kill info.
    -  SmallSet KilledMIRegs;
    -  RegKills.reset();
    -  KillOps.clear();
    -  KillOps.resize(TRI->getNumRegs(), NULL);
    -
    -  unsigned Dist = 0;
    -  DistanceMap.clear();
    -  for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
    -       MII != E; ) {
    -    MachineBasicBlock::iterator NextMII = next(MII);
    -
    -    VirtRegMap::MI2VirtMapTy::const_iterator I, End;
    -    bool Erased = false;
    -    bool BackTracked = false;
    -    if (OptimizeByUnfold(MBB, MII,
    -                         MaybeDeadStores, Spills, RegKills, KillOps, VRM))
    -      NextMII = next(MII);
    -
    -    MachineInstr &MI = *MII;
    -
    -    if (VRM.hasEmergencySpills(&MI)) {
    -      // Spill physical register(s) in the rare case the allocator has run out
    -      // of registers to allocate.
    -      SmallSet UsedSS;
    -      std::vector &EmSpills = VRM.getEmergencySpills(&MI);
    -      for (unsigned i = 0, e = EmSpills.size(); i != e; ++i) {
    -        unsigned PhysReg = EmSpills[i];
    -        const TargetRegisterClass *RC =
    -          TRI->getPhysicalRegisterRegClass(PhysReg);
    -        assert(RC && "Unable to determine register class!");
    -        int SS = VRM.getEmergencySpillSlot(RC);
    -        if (UsedSS.count(SS))
    -          assert(0 && "Need to spill more than one physical registers!");
    -        UsedSS.insert(SS);
    -        TII->storeRegToStackSlot(MBB, MII, PhysReg, true, SS, RC);
    -        MachineInstr *StoreMI = prior(MII);
    -        VRM.addSpillSlotUse(SS, StoreMI);
    -        TII->loadRegFromStackSlot(MBB, next(MII), PhysReg, SS, RC);
    -        MachineInstr *LoadMI = next(MII);
    -        VRM.addSpillSlotUse(SS, LoadMI);
    -        ++NumPSpills;
    -      }
    -      NextMII = next(MII);
    -    }
    -
    -    // Insert restores here if asked to.
    -    if (VRM.isRestorePt(&MI)) {
    -      std::vector &RestoreRegs = VRM.getRestorePtRestores(&MI);
    -      for (unsigned i = 0, e = RestoreRegs.size(); i != e; ++i) {
    -        unsigned VirtReg = RestoreRegs[e-i-1];  // Reverse order.
    -        if (!VRM.getPreSplitReg(VirtReg))
    -          continue; // Split interval spilled again.
    -        unsigned Phys = VRM.getPhys(VirtReg);
    -        RegInfo->setPhysRegUsed(Phys);
    -
    -        // Check if the value being restored if available. If so, it must be
    -        // from a predecessor BB that fallthrough into this BB. We do not
    -        // expect:
    -        // BB1:
    -        // r1 = load fi#1
    -        // ...
    -        //    = r1
    -        // ... # r1 not clobbered
    -        // ...
    -        //    = load fi#1
    -        bool DoReMat = VRM.isReMaterialized(VirtReg);
    -        int SSorRMId = DoReMat
    -          ? VRM.getReMatId(VirtReg) : VRM.getStackSlot(VirtReg);
    -        const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -        unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SSorRMId);
    -        if (InReg == Phys) {
    -          // If the value is already available in the expected register, save
    -          // a reload / remat.
    -          if (SSorRMId)
    -            DOUT << "Reusing RM#" << SSorRMId-VirtRegMap::MAX_STACK_SLOT-1;
    -          else
    -            DOUT << "Reusing SS#" << SSorRMId;
    -          DOUT << " from physreg "
    -               << TRI->getName(InReg) << " for vreg"
    -               << VirtReg <<" instead of reloading into physreg "
    -               << TRI->getName(Phys) << "\n";
    -          ++NumOmitted;
    -          continue;
    -        } else if (InReg && InReg != Phys) {
    -          if (SSorRMId)
    -            DOUT << "Reusing RM#" << SSorRMId-VirtRegMap::MAX_STACK_SLOT-1;
    -          else
    -            DOUT << "Reusing SS#" << SSorRMId;
    -          DOUT << " from physreg "
    -               << TRI->getName(InReg) << " for vreg"
    -               << VirtReg <<" by copying it into physreg "
    -               << TRI->getName(Phys) << "\n";
    -
    -          // If the reloaded / remat value is available in another register,
    -          // copy it to the desired register.
    -          TII->copyRegToReg(MBB, &MI, Phys, InReg, RC, RC);
    -
    -          // This invalidates Phys.
    -          Spills.ClobberPhysReg(Phys);
    -          // Remember it's available.
    -          Spills.addAvailable(SSorRMId, Phys);
    -
    -          // Mark is killed.
    -          MachineInstr *CopyMI = prior(MII);
    -          MachineOperand *KillOpnd = CopyMI->findRegisterUseOperand(InReg);
    -          KillOpnd->setIsKill();
    -          UpdateKills(*CopyMI, RegKills, KillOps, TRI);
    -
    -          DOUT << '\t' << *CopyMI;
    -          ++NumCopified;
    -          continue;
    -        }
    -
    -        if (VRM.isReMaterialized(VirtReg)) {
    -          ReMaterialize(MBB, MII, Phys, VirtReg, TII, TRI, VRM);
    -        } else {
    -          const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -          TII->loadRegFromStackSlot(MBB, &MI, Phys, SSorRMId, RC);
    -          MachineInstr *LoadMI = prior(MII);
    -          VRM.addSpillSlotUse(SSorRMId, LoadMI);
    -          ++NumLoads;
    -        }
    -
    -        // This invalidates Phys.
    -        Spills.ClobberPhysReg(Phys);
    -        // Remember it's available.
    -        Spills.addAvailable(SSorRMId, Phys);
    -
    -        UpdateKills(*prior(MII), RegKills, KillOps, TRI);
    -        DOUT << '\t' << *prior(MII);
    -      }
    -    }
    -
    -    // Insert spills here if asked to.
    -    if (VRM.isSpillPt(&MI)) {
    -      std::vector > &SpillRegs =
    -        VRM.getSpillPtSpills(&MI);
    -      for (unsigned i = 0, e = SpillRegs.size(); i != e; ++i) {
    -        unsigned VirtReg = SpillRegs[i].first;
    -        bool isKill = SpillRegs[i].second;
    -        if (!VRM.getPreSplitReg(VirtReg))
    -          continue; // Split interval spilled again.
    -        const TargetRegisterClass *RC = RegInfo->getRegClass(VirtReg);
    -        unsigned Phys = VRM.getPhys(VirtReg);
    -        int StackSlot = VRM.getStackSlot(VirtReg);
    -        TII->storeRegToStackSlot(MBB, next(MII), Phys, isKill, StackSlot, RC);
    -        MachineInstr *StoreMI = next(MII);
    -        VRM.addSpillSlotUse(StackSlot, StoreMI);
    -        DOUT << "Store:\t" << *StoreMI;
    -        VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod);
    -      }
    -      NextMII = next(MII);
    -    }
    -
    -    /// ReusedOperands - Keep track of operand reuse in case we need to undo
    -    /// reuse.
    -    ReuseInfo ReusedOperands(MI, TRI);
    -    SmallVector VirtUseOps;
    -    for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    -      MachineOperand &MO = MI.getOperand(i);
    -      if (!MO.isReg() || MO.getReg() == 0)
    -        continue;   // Ignore non-register operands.
    -      
    -      unsigned VirtReg = MO.getReg();
    -      if (TargetRegisterInfo::isPhysicalRegister(VirtReg)) {
    -        // Ignore physregs for spilling, but remember that it is used by this
    -        // function.
    -        RegInfo->setPhysRegUsed(VirtReg);
    -        continue;
    -      }
    -
    -      // We want to process implicit virtual register uses first.
    -      if (MO.isImplicit())
    -        // If the virtual register is implicitly defined, emit a implicit_def
    -        // before so scavenger knows it's "defined".
    -        VirtUseOps.insert(VirtUseOps.begin(), i);
    -      else
    -        VirtUseOps.push_back(i);
    -    }
    -
    -    // Process all of the spilled uses and all non spilled reg references.
    -    SmallVector PotentialDeadStoreSlots;
    -    KilledMIRegs.clear();
    -    for (unsigned j = 0, e = VirtUseOps.size(); j != e; ++j) {
    -      unsigned i = VirtUseOps[j];
    -      MachineOperand &MO = MI.getOperand(i);
    -      unsigned VirtReg = MO.getReg();
    -      assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
    -             "Not a virtual register?");
    -
    -      unsigned SubIdx = MO.getSubReg();
    -      if (VRM.isAssignedReg(VirtReg)) {
    -        // This virtual register was assigned a physreg!
    -        unsigned Phys = VRM.getPhys(VirtReg);
    -        RegInfo->setPhysRegUsed(Phys);
    -        if (MO.isDef())
    -          ReusedOperands.markClobbered(Phys);
    -        unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys;
    -        MI.getOperand(i).setReg(RReg);
    -        MI.getOperand(i).setSubReg(0);
    -        if (VRM.isImplicitlyDefined(VirtReg))
    -          BuildMI(MBB, &MI, MI.getDebugLoc(),
    -                  TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg);
    -        continue;
    -      }
    -      
    -      // This virtual register is now known to be a spilled value.
    -      if (!MO.isUse())
    -        continue;  // Handle defs in the loop below (handle use&def here though)
    -
    -      bool AvoidReload = false;
    -      if (LIs->hasInterval(VirtReg)) {
    -        LiveInterval &LI = LIs->getInterval(VirtReg);
    -        if (!LI.liveAt(LIs->getUseIndex(LI.beginNumber())))
    -          // Must be defined by an implicit def. It should not be spilled. Note,
    -          // this is for correctness reason. e.g.
    -          // 8   %reg1024 = IMPLICIT_DEF
    -          // 12  %reg1024 = INSERT_SUBREG %reg1024, %reg1025, 2
    -          // The live range [12, 14) are not part of the r1024 live interval since
    -          // it's defined by an implicit def. It will not conflicts with live
    -          // interval of r1025. Now suppose both registers are spilled, you can
    -          // easily see a situation where both registers are reloaded before
    -          // the INSERT_SUBREG and both target registers that would overlap.
    -          AvoidReload = true;
    -      }
    -
    -      bool DoReMat = VRM.isReMaterialized(VirtReg);
    -      int SSorRMId = DoReMat
    -        ? VRM.getReMatId(VirtReg) : VRM.getStackSlot(VirtReg);
    -      int ReuseSlot = SSorRMId;
    -
    -      // Check to see if this stack slot is available.
    -      unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SSorRMId);
    -
    -      // If this is a sub-register use, make sure the reuse register is in the
    -      // right register class. For example, for x86 not all of the 32-bit
    -      // registers have accessible sub-registers.
    -      // Similarly so for EXTRACT_SUBREG. Consider this:
    -      // EDI = op
    -      // MOV32_mr fi#1, EDI
    -      // ...
    -      //       = EXTRACT_SUBREG fi#1
    -      // fi#1 is available in EDI, but it cannot be reused because it's not in
    -      // the right register file.
    -      if (PhysReg && !AvoidReload &&
    -          (SubIdx || MI.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)) {
    -        const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -        if (!RC->contains(PhysReg))
    -          PhysReg = 0;
    -      }
    -
    -      if (PhysReg && !AvoidReload) {
    -        // This spilled operand might be part of a two-address operand.  If this
    -        // is the case, then changing it will necessarily require changing the 
    -        // def part of the instruction as well.  However, in some cases, we
    -        // aren't allowed to modify the reused register.  If none of these cases
    -        // apply, reuse it.
    -        bool CanReuse = true;
    -        bool isTied = MI.isRegTiedToDefOperand(i);
    -        if (isTied) {
    -          // Okay, we have a two address operand.  We can reuse this physreg as
    -          // long as we are allowed to clobber the value and there isn't an
    -          // earlier def that has already clobbered the physreg.
    -          CanReuse = !ReusedOperands.isClobbered(PhysReg) &&
    -            Spills.canClobberPhysReg(PhysReg);
    -        }
    -        
    -        if (CanReuse) {
    -          // If this stack slot value is already available, reuse it!
    -          if (ReuseSlot > VirtRegMap::MAX_STACK_SLOT)
    -            DOUT << "Reusing RM#" << ReuseSlot-VirtRegMap::MAX_STACK_SLOT-1;
    -          else
    -            DOUT << "Reusing SS#" << ReuseSlot;
    -          DOUT << " from physreg "
    -               << TRI->getName(PhysReg) << " for vreg"
    -               << VirtReg <<" instead of reloading into physreg "
    -               << TRI->getName(VRM.getPhys(VirtReg)) << "\n";
    -          unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
    -          MI.getOperand(i).setReg(RReg);
    -          MI.getOperand(i).setSubReg(0);
    -
    -          // The only technical detail we have is that we don't know that
    -          // PhysReg won't be clobbered by a reloaded stack slot that occurs
    -          // later in the instruction.  In particular, consider 'op V1, V2'.
    -          // If V1 is available in physreg R0, we would choose to reuse it
    -          // here, instead of reloading it into the register the allocator
    -          // indicated (say R1).  However, V2 might have to be reloaded
    -          // later, and it might indicate that it needs to live in R0.  When
    -          // this occurs, we need to have information available that
    -          // indicates it is safe to use R1 for the reload instead of R0.
    -          //
    -          // To further complicate matters, we might conflict with an alias,
    -          // or R0 and R1 might not be compatible with each other.  In this
    -          // case, we actually insert a reload for V1 in R1, ensuring that
    -          // we can get at R0 or its alias.
    -          ReusedOperands.addReuse(i, ReuseSlot, PhysReg,
    -                                  VRM.getPhys(VirtReg), VirtReg);
    -          if (isTied)
    -            // Only mark it clobbered if this is a use&def operand.
    -            ReusedOperands.markClobbered(PhysReg);
    -          ++NumReused;
    -
    -          if (MI.getOperand(i).isKill() &&
    -              ReuseSlot <= VirtRegMap::MAX_STACK_SLOT) {
    -
    -            // The store of this spilled value is potentially dead, but we
    -            // won't know for certain until we've confirmed that the re-use
    -            // above is valid, which means waiting until the other operands
    -            // are processed. For now we just track the spill slot, we'll
    -            // remove it after the other operands are processed if valid.
    -
    -            PotentialDeadStoreSlots.push_back(ReuseSlot);
    -          }
    -
    -          // Mark is isKill if it's there no other uses of the same virtual
    -          // register and it's not a two-address operand. IsKill will be
    -          // unset if reg is reused.
    -          if (!isTied && KilledMIRegs.count(VirtReg) == 0) {
    -            MI.getOperand(i).setIsKill();
    -            KilledMIRegs.insert(VirtReg);
    -          }
    -
    -          continue;
    -        }  // CanReuse
    -        
    -        // Otherwise we have a situation where we have a two-address instruction
    -        // whose mod/ref operand needs to be reloaded.  This reload is already
    -        // available in some register "PhysReg", but if we used PhysReg as the
    -        // operand to our 2-addr instruction, the instruction would modify
    -        // PhysReg.  This isn't cool if something later uses PhysReg and expects
    -        // to get its initial value.
    -        //
    -        // To avoid this problem, and to avoid doing a load right after a store,
    -        // we emit a copy from PhysReg into the designated register for this
    -        // operand.
    -        unsigned DesignatedReg = VRM.getPhys(VirtReg);
    -        assert(DesignatedReg && "Must map virtreg to physreg!");
    -
    -        // Note that, if we reused a register for a previous operand, the
    -        // register we want to reload into might not actually be
    -        // available.  If this occurs, use the register indicated by the
    -        // reuser.
    -        if (ReusedOperands.hasReuses())
    -          DesignatedReg = ReusedOperands.GetRegForReload(DesignatedReg, &MI, 
    -                               Spills, MaybeDeadStores, RegKills, KillOps, VRM);
    -        
    -        // If the mapped designated register is actually the physreg we have
    -        // incoming, we don't need to inserted a dead copy.
    -        if (DesignatedReg == PhysReg) {
    -          // If this stack slot value is already available, reuse it!
    -          if (ReuseSlot > VirtRegMap::MAX_STACK_SLOT)
    -            DOUT << "Reusing RM#" << ReuseSlot-VirtRegMap::MAX_STACK_SLOT-1;
    -          else
    -            DOUT << "Reusing SS#" << ReuseSlot;
    -          DOUT << " from physreg " << TRI->getName(PhysReg)
    -               << " for vreg" << VirtReg
    -               << " instead of reloading into same physreg.\n";
    -          unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
    -          MI.getOperand(i).setReg(RReg);
    -          MI.getOperand(i).setSubReg(0);
    -          ReusedOperands.markClobbered(RReg);
    -          ++NumReused;
    -          continue;
    -        }
    -        
    -        const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -        RegInfo->setPhysRegUsed(DesignatedReg);
    -        ReusedOperands.markClobbered(DesignatedReg);
    -        TII->copyRegToReg(MBB, &MI, DesignatedReg, PhysReg, RC, RC);
    -
    -        MachineInstr *CopyMI = prior(MII);
    -        UpdateKills(*CopyMI, RegKills, KillOps, TRI);
    -
    -        // This invalidates DesignatedReg.
    -        Spills.ClobberPhysReg(DesignatedReg);
    -        
    -        Spills.addAvailable(ReuseSlot, DesignatedReg);
    -        unsigned RReg =
    -          SubIdx ? TRI->getSubReg(DesignatedReg, SubIdx) : DesignatedReg;
    -        MI.getOperand(i).setReg(RReg);
    -        MI.getOperand(i).setSubReg(0);
    -        DOUT << '\t' << *prior(MII);
    -        ++NumReused;
    -        continue;
    -      } // if (PhysReg)
    -      
    -      // Otherwise, reload it and remember that we have it.
    -      PhysReg = VRM.getPhys(VirtReg);
    -      assert(PhysReg && "Must map virtreg to physreg!");
    -
    -      // Note that, if we reused a register for a previous operand, the
    -      // register we want to reload into might not actually be
    -      // available.  If this occurs, use the register indicated by the
    -      // reuser.
    -      if (ReusedOperands.hasReuses())
    -        PhysReg = ReusedOperands.GetRegForReload(PhysReg, &MI, 
    -                               Spills, MaybeDeadStores, RegKills, KillOps, VRM);
    -      
    -      RegInfo->setPhysRegUsed(PhysReg);
    -      ReusedOperands.markClobbered(PhysReg);
    -      if (AvoidReload)
    -        ++NumAvoided;
    -      else {
    -        if (DoReMat) {
    -          ReMaterialize(MBB, MII, PhysReg, VirtReg, TII, TRI, VRM);
    -        } else {
    -          const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -          TII->loadRegFromStackSlot(MBB, &MI, PhysReg, SSorRMId, RC);
    -          MachineInstr *LoadMI = prior(MII);
    -          VRM.addSpillSlotUse(SSorRMId, LoadMI);
    -          ++NumLoads;
    -        }
    -        // This invalidates PhysReg.
    -        Spills.ClobberPhysReg(PhysReg);
    -
    -        // Any stores to this stack slot are not dead anymore.
    -        if (!DoReMat)
    -          MaybeDeadStores[SSorRMId] = NULL;
    -        Spills.addAvailable(SSorRMId, PhysReg);
    -        // Assumes this is the last use. IsKill will be unset if reg is reused
    -        // unless it's a two-address operand.
    -        if (!MI.isRegTiedToDefOperand(i) &&
    -            KilledMIRegs.count(VirtReg) == 0) {
    -          MI.getOperand(i).setIsKill();
    -          KilledMIRegs.insert(VirtReg);
    -        }
    -
    -        UpdateKills(*prior(MII), RegKills, KillOps, TRI);
    -        DOUT << '\t' << *prior(MII);
    -      }
    -      unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
    -      MI.getOperand(i).setReg(RReg);
    -      MI.getOperand(i).setSubReg(0);
    -    }
    -
    -    // Ok - now we can remove stores that have been confirmed dead.
    -    for (unsigned j = 0, e = PotentialDeadStoreSlots.size(); j != e; ++j) {
    -      // This was the last use and the spilled value is still available
    -      // for reuse. That means the spill was unnecessary!
    -      int PDSSlot = PotentialDeadStoreSlots[j];
    -      MachineInstr* DeadStore = MaybeDeadStores[PDSSlot];
    -      if (DeadStore) {
    -        DOUT << "Removed dead store:\t" << *DeadStore;
    -        InvalidateKills(*DeadStore, RegKills, KillOps);
    -        VRM.RemoveMachineInstrFromMaps(DeadStore);
    -        MBB.erase(DeadStore);
    -        MaybeDeadStores[PDSSlot] = NULL;
    -        ++NumDSE;
    -      }
    -    }
    -
    -
    -    DOUT << '\t' << MI;
    -
    -
    -    // If we have folded references to memory operands, make sure we clear all
    -    // physical registers that may contain the value of the spilled virtual
    -    // register
    -    SmallSet FoldedSS;
    -    for (tie(I, End) = VRM.getFoldedVirts(&MI); I != End; ) {
    -      unsigned VirtReg = I->second.first;
    -      VirtRegMap::ModRef MR = I->second.second;
    -      DOUT << "Folded vreg: " << VirtReg << "  MR: " << MR;
    -
    -      // MI2VirtMap be can updated which invalidate the iterator.
    -      // Increment the iterator first.
    -      ++I;
    -      int SS = VRM.getStackSlot(VirtReg);
    -      if (SS == VirtRegMap::NO_STACK_SLOT)
    -        continue;
    -      FoldedSS.insert(SS);
    -      DOUT << " - StackSlot: " << SS << "\n";
    -      
    -      // If this folded instruction is just a use, check to see if it's a
    -      // straight load from the virt reg slot.
    -      if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) {
    -        int FrameIdx;
    -        unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx);
    -        if (DestReg && FrameIdx == SS) {
    -          // If this spill slot is available, turn it into a copy (or nothing)
    -          // instead of leaving it as a load!
    -          if (unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SS)) {
    -            DOUT << "Promoted Load To Copy: " << MI;
    -            if (DestReg != InReg) {
    -              const TargetRegisterClass *RC = RegInfo->getRegClass(VirtReg);
    -              TII->copyRegToReg(MBB, &MI, DestReg, InReg, RC, RC);
    -              MachineOperand *DefMO = MI.findRegisterDefOperand(DestReg);
    -              unsigned SubIdx = DefMO->getSubReg();
    -              // Revisit the copy so we make sure to notice the effects of the
    -              // operation on the destreg (either needing to RA it if it's 
    -              // virtual or needing to clobber any values if it's physical).
    -              NextMII = &MI;
    -              --NextMII;  // backtrack to the copy.
    -              // Propagate the sub-register index over.
    -              if (SubIdx) {
    -                DefMO = NextMII->findRegisterDefOperand(DestReg);
    -                DefMO->setSubReg(SubIdx);
    -              }
    -
    -              // Mark is killed.
    -              MachineOperand *KillOpnd = NextMII->findRegisterUseOperand(InReg);
    -              KillOpnd->setIsKill();
    -
    -              BackTracked = true;
    -            } else {
    -              DOUT << "Removing now-noop copy: " << MI;
    -              // Unset last kill since it's being reused.
    -              InvalidateKill(InReg, RegKills, KillOps);
    -              Spills.disallowClobberPhysReg(InReg);
    -            }
    -
    -            InvalidateKills(MI, RegKills, KillOps);
    -            VRM.RemoveMachineInstrFromMaps(&MI);
    -            MBB.erase(&MI);
    -            Erased = true;
    -            goto ProcessNextInst;
    -          }
    -        } else {
    -          unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS);
    -          SmallVector NewMIs;
    -          if (PhysReg &&
    -              TII->unfoldMemoryOperand(MF, &MI, PhysReg, false, false, NewMIs)) {
    -            MBB.insert(MII, NewMIs[0]);
    -            InvalidateKills(MI, RegKills, KillOps);
    -            VRM.RemoveMachineInstrFromMaps(&MI);
    -            MBB.erase(&MI);
    -            Erased = true;
    -            --NextMII;  // backtrack to the unfolded instruction.
    -            BackTracked = true;
    -            goto ProcessNextInst;
    -          }
    -        }
    -      }
    -
    -      // If this reference is not a use, any previous store is now dead.
    -      // Otherwise, the store to this stack slot is not dead anymore.
    -      MachineInstr* DeadStore = MaybeDeadStores[SS];
    -      if (DeadStore) {
    -        bool isDead = !(MR & VirtRegMap::isRef);
    -        MachineInstr *NewStore = NULL;
    -        if (MR & VirtRegMap::isModRef) {
    -          unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS);
    -          SmallVector NewMIs;
    -          // We can reuse this physreg as long as we are allowed to clobber
    -          // the value and there isn't an earlier def that has already clobbered
    -          // the physreg.
    -          if (PhysReg &&
    -              !ReusedOperands.isClobbered(PhysReg) &&
    -              Spills.canClobberPhysReg(PhysReg) &&
    -              !TII->isStoreToStackSlot(&MI, SS)) { // Not profitable!
    -            MachineOperand *KillOpnd =
    -              DeadStore->findRegisterUseOperand(PhysReg, true);
    -            // Note, if the store is storing a sub-register, it's possible the
    -            // super-register is needed below.
    -            if (KillOpnd && !KillOpnd->getSubReg() &&
    -                TII->unfoldMemoryOperand(MF, &MI, PhysReg, false, true,NewMIs)){
    -              MBB.insert(MII, NewMIs[0]);
    -              NewStore = NewMIs[1];
    -              MBB.insert(MII, NewStore);
    -              VRM.addSpillSlotUse(SS, NewStore);
    -              InvalidateKills(MI, RegKills, KillOps);
    -              VRM.RemoveMachineInstrFromMaps(&MI);
    -              MBB.erase(&MI);
    -              Erased = true;
    -              --NextMII;
    -              --NextMII;  // backtrack to the unfolded instruction.
    -              BackTracked = true;
    -              isDead = true;
    -              ++NumSUnfold;
    -            }
    -          }
    -        }
    -
    -        if (isDead) {  // Previous store is dead.
    -          // If we get here, the store is dead, nuke it now.
    -          DOUT << "Removed dead store:\t" << *DeadStore;
    -          InvalidateKills(*DeadStore, RegKills, KillOps);
    -          VRM.RemoveMachineInstrFromMaps(DeadStore);
    -          MBB.erase(DeadStore);
    -          if (!NewStore)
    -            ++NumDSE;
    -        }
    -
    -        MaybeDeadStores[SS] = NULL;
    -        if (NewStore) {
    -          // Treat this store as a spill merged into a copy. That makes the
    -          // stack slot value available.
    -          VRM.virtFolded(VirtReg, NewStore, VirtRegMap::isMod);
    -          goto ProcessNextInst;
    -        }
    -      }
    -
    -      // If the spill slot value is available, and this is a new definition of
    -      // the value, the value is not available anymore.
    -      if (MR & VirtRegMap::isMod) {
    -        // Notice that the value in this stack slot has been modified.
    -        Spills.ModifyStackSlotOrReMat(SS);
    -        
    -        // If this is *just* a mod of the value, check to see if this is just a
    -        // store to the spill slot (i.e. the spill got merged into the copy). If
    -        // so, realize that the vreg is available now, and add the store to the
    -        // MaybeDeadStore info.
    -        int StackSlot;
    -        if (!(MR & VirtRegMap::isRef)) {
    -          if (unsigned SrcReg = TII->isStoreToStackSlot(&MI, StackSlot)) {
    -            assert(TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
    -                   "Src hasn't been allocated yet?");
    -
    -            if (CommuteToFoldReload(MBB, MII, VirtReg, SrcReg, StackSlot,
    -                                    Spills, RegKills, KillOps, TRI, VRM)) {
    -              NextMII = next(MII);
    -              BackTracked = true;
    -              goto ProcessNextInst;
    -            }
    -
    -            // Okay, this is certainly a store of SrcReg to [StackSlot].  Mark
    -            // this as a potentially dead store in case there is a subsequent
    -            // store into the stack slot without a read from it.
    -            MaybeDeadStores[StackSlot] = &MI;
    -
    -            // If the stack slot value was previously available in some other
    -            // register, change it now.  Otherwise, make the register
    -            // available in PhysReg.
    -            Spills.addAvailable(StackSlot, SrcReg, MI.killsRegister(SrcReg));
    -          }
    -        }
    -      }
    -    }
    -
    -    // Process all of the spilled defs.
    -    for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    -      MachineOperand &MO = MI.getOperand(i);
    -      if (!(MO.isReg() && MO.getReg() && MO.isDef()))
    -        continue;
    -
    -      unsigned VirtReg = MO.getReg();
    -      if (!TargetRegisterInfo::isVirtualRegister(VirtReg)) {
    -        // Check to see if this is a noop copy.  If so, eliminate the
    -        // instruction before considering the dest reg to be changed.
    -        unsigned Src, Dst, SrcSR, DstSR;
    -        if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) {
    -          ++NumDCE;
    -          DOUT << "Removing now-noop copy: " << MI;
    -          SmallVector KillRegs;
    -          InvalidateKills(MI, RegKills, KillOps, &KillRegs);
    -          if (MO.isDead() && !KillRegs.empty()) {
    -            // Source register or an implicit super/sub-register use is killed.
    -            assert(KillRegs[0] == Dst ||
    -                   TRI->isSubRegister(KillRegs[0], Dst) ||
    -                   TRI->isSuperRegister(KillRegs[0], Dst));
    -            // Last def is now dead.
    -            TransferDeadness(&MBB, Dist, Src, RegKills, KillOps);
    -          }
    -          VRM.RemoveMachineInstrFromMaps(&MI);
    -          MBB.erase(&MI);
    -          Erased = true;
    -          Spills.disallowClobberPhysReg(VirtReg);
    -          goto ProcessNextInst;
    -        }
    -          
    -        // If it's not a no-op copy, it clobbers the value in the destreg.
    -        Spills.ClobberPhysReg(VirtReg);
    -        ReusedOperands.markClobbered(VirtReg);
    - 
    -        // Check to see if this instruction is a load from a stack slot into
    -        // a register.  If so, this provides the stack slot value in the reg.
    -        int FrameIdx;
    -        if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
    -          assert(DestReg == VirtReg && "Unknown load situation!");
    -
    -          // If it is a folded reference, then it's not safe to clobber.
    -          bool Folded = FoldedSS.count(FrameIdx);
    -          // Otherwise, if it wasn't available, remember that it is now!
    -          Spills.addAvailable(FrameIdx, DestReg, !Folded);
    -          goto ProcessNextInst;
    -        }
    -            
    -        continue;
    -      }
    -
    -      unsigned SubIdx = MO.getSubReg();
    -      bool DoReMat = VRM.isReMaterialized(VirtReg);
    -      if (DoReMat)
    -        ReMatDefs.insert(&MI);
    -
    -      // The only vregs left are stack slot definitions.
    -      int StackSlot = VRM.getStackSlot(VirtReg);
    -      const TargetRegisterClass *RC = RegInfo->getRegClass(VirtReg);
    -
    -      // If this def is part of a two-address operand, make sure to execute
    -      // the store from the correct physical register.
    -      unsigned PhysReg;
    -      unsigned TiedOp;
    -      if (MI.isRegTiedToUseOperand(i, &TiedOp)) {
    -        PhysReg = MI.getOperand(TiedOp).getReg();
    -        if (SubIdx) {
    -          unsigned SuperReg = findSuperReg(RC, PhysReg, SubIdx, TRI);
    -          assert(SuperReg && TRI->getSubReg(SuperReg, SubIdx) == PhysReg &&
    -                 "Can't find corresponding super-register!");
    -          PhysReg = SuperReg;
    -        }
    -      } else {
    -        PhysReg = VRM.getPhys(VirtReg);
    -        if (ReusedOperands.isClobbered(PhysReg)) {
    -          // Another def has taken the assigned physreg. It must have been a
    -          // use&def which got it due to reuse. Undo the reuse!
    -          PhysReg = ReusedOperands.GetRegForReload(PhysReg, &MI, 
    -                               Spills, MaybeDeadStores, RegKills, KillOps, VRM);
    -        }
    -      }
    -
    -      assert(PhysReg && "VR not assigned a physical register?");
    -      RegInfo->setPhysRegUsed(PhysReg);
    -      unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
    -      ReusedOperands.markClobbered(RReg);
    -      MI.getOperand(i).setReg(RReg);
    -      MI.getOperand(i).setSubReg(0);
    -
    -      if (!MO.isDead()) {
    -        MachineInstr *&LastStore = MaybeDeadStores[StackSlot];
    -        SpillRegToStackSlot(MBB, MII, -1, PhysReg, StackSlot, RC, true,
    -                          LastStore, Spills, ReMatDefs, RegKills, KillOps, VRM);
    -        NextMII = next(MII);
    -
    -        // Check to see if this is a noop copy.  If so, eliminate the
    -        // instruction before considering the dest reg to be changed.
    -        {
    -          unsigned Src, Dst, SrcSR, DstSR;
    -          if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) {
    -            ++NumDCE;
    -            DOUT << "Removing now-noop copy: " << MI;
    -            InvalidateKills(MI, RegKills, KillOps);
    -            VRM.RemoveMachineInstrFromMaps(&MI);
    -            MBB.erase(&MI);
    -            Erased = true;
    -            UpdateKills(*LastStore, RegKills, KillOps, TRI);
    -            goto ProcessNextInst;
    -          }
    -        }
    -      }    
    -    }
    -  ProcessNextInst:
    -    DistanceMap.insert(std::make_pair(&MI, Dist++));
    -    if (!Erased && !BackTracked) {
    -      for (MachineBasicBlock::iterator II = &MI; II != NextMII; ++II)
    -        UpdateKills(*II, RegKills, KillOps, TRI);
    -    }
    -    MII = NextMII;
    -  }
    -
    -}
    -
    -llvm::Spiller* llvm::createSpiller() {
    -  switch (SpillerOpt) {
    -  default: assert(0 && "Unreachable!");
    -  case local:
    -    return new LocalSpiller();
    -  case simple:
    -    return new SimpleSpiller();
    -  }
    -}
    
    Removed: llvm/trunk/lib/CodeGen/Spiller.h
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Spiller.h?rev=71056&view=auto
    
    ==============================================================================
    --- llvm/trunk/lib/CodeGen/Spiller.h (original)
    +++ llvm/trunk/lib/CodeGen/Spiller.h (removed)
    @@ -1,340 +0,0 @@
    -//===-- llvm/CodeGen/Spiller.h - Spiller -*- C++ -*------------------------===//
    -//
    -//                     The LLVM Compiler Infrastructure
    -//
    -// This file is distributed under the University of Illinois Open Source
    -// License. See LICENSE.TXT for details.
    -//
    -//===----------------------------------------------------------------------===//
    -
    -#ifndef LLVM_CODEGEN_SPILLER_H
    -#define LLVM_CODEGEN_SPILLER_H
    -
    -#include "llvm/Target/TargetRegisterInfo.h"
    -#include "llvm/ADT/BitVector.h"
    -#include "llvm/ADT/IndexedMap.h"
    -#include "llvm/ADT/SmallPtrSet.h"
    -#include "llvm/ADT/SmallVector.h"
    -#include "llvm/Support/Streams.h"
    -#include "llvm/Function.h"
    -#include "llvm/CodeGen/LiveIntervalAnalysis.h"
    -#include "llvm/CodeGen/MachineFrameInfo.h"
    -#include "llvm/CodeGen/MachineFunction.h"
    -#include "llvm/CodeGen/MachineInstrBuilder.h"
    -#include "llvm/CodeGen/MachineRegisterInfo.h"
    -#include "llvm/Target/TargetMachine.h"
    -#include "llvm/Target/TargetInstrInfo.h"
    -#include "llvm/Support/CommandLine.h"
    -#include "llvm/Support/Debug.h"
    -#include "llvm/ADT/BitVector.h"
    -#include "llvm/ADT/DenseMap.h"
    -#include "llvm/ADT/SmallSet.h"
    -#include "VirtRegMap.h"
    -#include 
    -
    -namespace llvm {
    -  
    -  /// Spiller interface: Implementations of this interface assign spilled
    -  /// virtual registers to stack slots, rewriting the code.
    -  struct Spiller {
    -    virtual ~Spiller();
    -    virtual bool runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM,
    -                                      LiveIntervals* LIs) = 0;
    -  };
    -
    -  /// createSpiller - Create an return a spiller object, as specified on the
    -  /// command line.
    -  Spiller* createSpiller();
    -  
    -  // ************************************************************************ //
    -  
    -  // Simple Spiller Implementation
    -  struct VISIBILITY_HIDDEN SimpleSpiller : public Spiller {
    -    bool runOnMachineFunction(MachineFunction& mf, VirtRegMap &VRM,
    -                              LiveIntervals* LIs);
    -  };
    -  
    -  // ************************************************************************ //
    -  
    -  /// AvailableSpills - As the local spiller is scanning and rewriting an MBB
    -  /// from top down, keep track of which spills slots or remat are available in
    -  /// each register.
    -  ///
    -  /// Note that not all physregs are created equal here.  In particular, some
    -  /// physregs are reloads that we are allowed to clobber or ignore at any time.
    -  /// Other physregs are values that the register allocated program is using
    -  /// that we cannot CHANGE, but we can read if we like.  We keep track of this
    -  /// on a per-stack-slot / remat id basis as the low bit in the value of the
    -  /// SpillSlotsAvailable entries.  The predicate 'canClobberPhysReg()' checks
    -  /// this bit and addAvailable sets it if.
    -  class VISIBILITY_HIDDEN AvailableSpills {
    -    const TargetRegisterInfo *TRI;
    -    const TargetInstrInfo *TII;
    -
    -    // SpillSlotsOrReMatsAvailable - This map keeps track of all of the spilled
    -    // or remat'ed virtual register values that are still available, due to
    -    // being loaded or stored to, but not invalidated yet.
    -    std::map SpillSlotsOrReMatsAvailable;
    -
    -    // PhysRegsAvailable - This is the inverse of SpillSlotsOrReMatsAvailable,
    -    // indicating which stack slot values are currently held by a physreg.  This
    -    // is used to invalidate entries in SpillSlotsOrReMatsAvailable when a
    -    // physreg is modified.
    -    std::multimap PhysRegsAvailable;
    -
    -    void disallowClobberPhysRegOnly(unsigned PhysReg);
    -
    -    void ClobberPhysRegOnly(unsigned PhysReg);
    -  public:
    -    AvailableSpills(const TargetRegisterInfo *tri, const TargetInstrInfo *tii)
    -      : TRI(tri), TII(tii) {
    -    }
    -
    -    /// clear - Reset the state.
    -    void clear() {
    -      SpillSlotsOrReMatsAvailable.clear();
    -      PhysRegsAvailable.clear();
    -    }
    -
    -    const TargetRegisterInfo *getRegInfo() const { return TRI; }
    -
    -    /// getSpillSlotOrReMatPhysReg - If the specified stack slot or remat is
    -    /// available in a physical register, return that PhysReg, otherwise
    -    /// return 0.
    -    unsigned getSpillSlotOrReMatPhysReg(int Slot) const {
    -      std::map::const_iterator I =
    -        SpillSlotsOrReMatsAvailable.find(Slot);
    -      if (I != SpillSlotsOrReMatsAvailable.end()) {
    -        return I->second >> 1;  // Remove the CanClobber bit.
    -      }
    -      return 0;
    -    }
    -
    -    /// addAvailable - Mark that the specified stack slot / remat is available
    -    /// in the specified physreg.  If CanClobber is true, the physreg can be
    -    /// modified at any time without changing the semantics of the program.
    -    void addAvailable(int SlotOrReMat, unsigned Reg, bool CanClobber = true) {
    -      // If this stack slot is thought to be available in some other physreg, 
    -      // remove its record.
    -      ModifyStackSlotOrReMat(SlotOrReMat);
    -
    -      PhysRegsAvailable.insert(std::make_pair(Reg, SlotOrReMat));
    -      SpillSlotsOrReMatsAvailable[SlotOrReMat]= (Reg << 1) |
    -                                                (unsigned)CanClobber;
    -
    -      if (SlotOrReMat > VirtRegMap::MAX_STACK_SLOT)
    -        DOUT << "Remembering RM#" << SlotOrReMat-VirtRegMap::MAX_STACK_SLOT-1;
    -      else
    -        DOUT << "Remembering SS#" << SlotOrReMat;
    -      DOUT << " in physreg " << TRI->getName(Reg) << "\n";
    -    }
    -
    -    /// canClobberPhysRegForSS - Return true if the spiller is allowed to change
    -    /// the value of the specified stackslot register if it desires. The
    -    /// specified stack slot must be available in a physreg for this query to
    -    /// make sense.
    -    bool canClobberPhysRegForSS(int SlotOrReMat) const {
    -      assert(SpillSlotsOrReMatsAvailable.count(SlotOrReMat) &&
    -             "Value not available!");
    -      return SpillSlotsOrReMatsAvailable.find(SlotOrReMat)->second & 1;
    -    }
    -
    -    /// canClobberPhysReg - Return true if the spiller is allowed to clobber the
    -    /// physical register where values for some stack slot(s) might be
    -    /// available.
    -    bool canClobberPhysReg(unsigned PhysReg) const {
    -      std::multimap::const_iterator I =
    -        PhysRegsAvailable.lower_bound(PhysReg);
    -      while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
    -        int SlotOrReMat = I->second;
    -        I++;
    -        if (!canClobberPhysRegForSS(SlotOrReMat))
    -          return false;
    -      }
    -      return true;
    -    }
    -
    -    /// disallowClobberPhysReg - Unset the CanClobber bit of the specified
    -    /// stackslot register. The register is still available but is no longer
    -    /// allowed to be modifed.
    -    void disallowClobberPhysReg(unsigned PhysReg);
    -
    -    /// ClobberPhysReg - This is called when the specified physreg changes
    -    /// value.  We use this to invalidate any info about stuff that lives in
    -    /// it and any of its aliases.
    -    void ClobberPhysReg(unsigned PhysReg);
    -
    -    /// ModifyStackSlotOrReMat - This method is called when the value in a stack
    -    /// slot changes.  This removes information about which register the
    -    /// previous value for this slot lives in (as the previous value is dead
    -    /// now).
    -    void ModifyStackSlotOrReMat(int SlotOrReMat);
    -
    -    /// AddAvailableRegsToLiveIn - Availability information is being kept coming
    -    /// into the specified MBB. Add available physical registers as potential
    -    /// live-in's. If they are reused in the MBB, they will be added to the
    -    /// live-in set to make register scavenger and post-allocation scheduler.
    -    void AddAvailableRegsToLiveIn(MachineBasicBlock &MBB, BitVector &RegKills,
    -                                  std::vector &KillOps);
    -  };
    -  
    -  // ************************************************************************ //
    -  
    -  // ReusedOp - For each reused operand, we keep track of a bit of information,
    -  // in case we need to rollback upon processing a new operand.  See comments
    -  // below.
    -  struct ReusedOp {
    -    // The MachineInstr operand that reused an available value.
    -    unsigned Operand;
    -
    -    // StackSlotOrReMat - The spill slot or remat id of the value being reused.
    -    unsigned StackSlotOrReMat;
    -
    -    // PhysRegReused - The physical register the value was available in.
    -    unsigned PhysRegReused;
    -
    -    // AssignedPhysReg - The physreg that was assigned for use by the reload.
    -    unsigned AssignedPhysReg;
    -    
    -    // VirtReg - The virtual register itself.
    -    unsigned VirtReg;
    -
    -    ReusedOp(unsigned o, unsigned ss, unsigned prr, unsigned apr,
    -             unsigned vreg)
    -      : Operand(o), StackSlotOrReMat(ss), PhysRegReused(prr),
    -        AssignedPhysReg(apr), VirtReg(vreg) {}
    -  };
    -  
    -  /// ReuseInfo - This maintains a collection of ReuseOp's for each operand that
    -  /// is reused instead of reloaded.
    -  class VISIBILITY_HIDDEN ReuseInfo {
    -    MachineInstr &MI;
    -    std::vector Reuses;
    -    BitVector PhysRegsClobbered;
    -  public:
    -    ReuseInfo(MachineInstr &mi, const TargetRegisterInfo *tri) : MI(mi) {
    -      PhysRegsClobbered.resize(tri->getNumRegs());
    -    }
    -    
    -    bool hasReuses() const {
    -      return !Reuses.empty();
    -    }
    -    
    -    /// addReuse - If we choose to reuse a virtual register that is already
    -    /// available instead of reloading it, remember that we did so.
    -    void addReuse(unsigned OpNo, unsigned StackSlotOrReMat,
    -                  unsigned PhysRegReused, unsigned AssignedPhysReg,
    -                  unsigned VirtReg) {
    -      // If the reload is to the assigned register anyway, no undo will be
    -      // required.
    -      if (PhysRegReused == AssignedPhysReg) return;
    -      
    -      // Otherwise, remember this.
    -      Reuses.push_back(ReusedOp(OpNo, StackSlotOrReMat, PhysRegReused, 
    -                                AssignedPhysReg, VirtReg));
    -    }
    -
    -    void markClobbered(unsigned PhysReg) {
    -      PhysRegsClobbered.set(PhysReg);
    -    }
    -
    -    bool isClobbered(unsigned PhysReg) const {
    -      return PhysRegsClobbered.test(PhysReg);
    -    }
    -    
    -    /// GetRegForReload - We are about to emit a reload into PhysReg.  If there
    -    /// is some other operand that is using the specified register, either pick
    -    /// a new register to use, or evict the previous reload and use this reg. 
    -    unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
    -                             AvailableSpills &Spills,
    -                             std::vector &MaybeDeadStores,
    -                             SmallSet &Rejected,
    -                             BitVector &RegKills,
    -                             std::vector &KillOps,
    -                             VirtRegMap &VRM);
    -
    -    /// GetRegForReload - Helper for the above GetRegForReload(). Add a
    -    /// 'Rejected' set to remember which registers have been considered and
    -    /// rejected for the reload. This avoids infinite looping in case like
    -    /// this:
    -    /// t1 := op t2, t3
    -    /// t2 <- assigned r0 for use by the reload but ended up reuse r1
    -    /// t3 <- assigned r1 for use by the reload but ended up reuse r0
    -    /// t1 <- desires r1
    -    ///       sees r1 is taken by t2, tries t2's reload register r0
    -    ///       sees r0 is taken by t3, tries t3's reload register r1
    -    ///       sees r1 is taken by t2, tries t2's reload register r0 ...
    -    unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
    -                             AvailableSpills &Spills,
    -                             std::vector &MaybeDeadStores,
    -                             BitVector &RegKills,
    -                             std::vector &KillOps,
    -                             VirtRegMap &VRM) {
    -      SmallSet Rejected;
    -      return GetRegForReload(PhysReg, MI, Spills, MaybeDeadStores, Rejected,
    -                             RegKills, KillOps, VRM);
    -    }
    -  };
    -  
    -  // ************************************************************************ //
    -  
    -  /// LocalSpiller - This spiller does a simple pass over the machine basic
    -  /// block to attempt to keep spills in registers as much as possible for
    -  /// blocks that have low register pressure (the vreg may be spilled due to
    -  /// register pressure in other blocks).
    -  class VISIBILITY_HIDDEN LocalSpiller : public Spiller {
    -    MachineRegisterInfo *RegInfo;
    -    const TargetRegisterInfo *TRI;
    -    const TargetInstrInfo *TII;
    -    BitVector AllocatableRegs;
    -    DenseMap DistanceMap;
    -  public:
    -    bool runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM,
    -                              LiveIntervals* LI);
    -  private:
    -    void TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
    -                          unsigned Reg, BitVector &RegKills,
    -                          std::vector &KillOps);
    -
    -    bool OptimizeByUnfold(MachineBasicBlock &MBB,
    -                          MachineBasicBlock::iterator &MII,
    -                          std::vector &MaybeDeadStores,
    -                          AvailableSpills &Spills, BitVector &RegKills,
    -                          std::vector &KillOps,
    -                          VirtRegMap &VRM);
    -
    -    bool OptimizeByUnfold2(unsigned VirtReg, int SS,
    -                           MachineBasicBlock &MBB,
    -                           MachineBasicBlock::iterator &MII, 
    -                           std::vector &MaybeDeadStores,
    -                           AvailableSpills &Spills, BitVector &RegKills,
    -                           std::vector &KillOps,
    -                           VirtRegMap &VRM);
    -
    -    bool CommuteToFoldReload(MachineBasicBlock &MBB,
    -                             MachineBasicBlock::iterator &MII,
    -                             unsigned VirtReg, unsigned SrcReg, int SS,
    -                             AvailableSpills &Spills,
    -                             BitVector &RegKills,
    -                             std::vector &KillOps,
    -                             const TargetRegisterInfo *TRI,
    -                             VirtRegMap &VRM);
    -
    -    void SpillRegToStackSlot(MachineBasicBlock &MBB,
    -                             MachineBasicBlock::iterator &MII,
    -                             int Idx, unsigned PhysReg, int StackSlot,
    -                             const TargetRegisterClass *RC,
    -                             bool isAvailable, MachineInstr *&LastStore,
    -                             AvailableSpills &Spills,
    -                             SmallSet &ReMatDefs,
    -                             BitVector &RegKills,
    -                             std::vector &KillOps,
    -                             VirtRegMap &VRM);
    -
    -    void RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
    -                    LiveIntervals *LIs, AvailableSpills &Spills,
    -                    BitVector &RegKills, std::vector &KillOps);
    -  };
    -}
    -
    -#endif
    
    Copied: llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp (from r71041, llvm/trunk/lib/CodeGen/Spiller.cpp)
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp?p2=llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp&p1=llvm/trunk/lib/CodeGen/Spiller.cpp&r1=71041&r2=71057&rev=71057&view=diff
    
    ==============================================================================
    --- llvm/trunk/lib/CodeGen/Spiller.cpp (original)
    +++ llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Tue May  5 21:36:21 2009
    @@ -1,4 +1,4 @@
    -//===-- llvm/CodeGen/Spiller.cpp -  Spiller -------------------------------===//
    +//===-- llvm/CodeGen/Rewriter.cpp -  Rewriter -----------------------------===//
     //
     //                     The LLVM Compiler Infrastructure
     //
    @@ -7,8 +7,8 @@
     //
     //===----------------------------------------------------------------------===//
     
    -#define DEBUG_TYPE "spiller"
    -#include "Spiller.h"
    +#define DEBUG_TYPE "virtregrewriter"
    +#include "VirtRegRewriter.h"
     #include "llvm/Support/Compiler.h"
     #include "llvm/ADT/DepthFirstIterator.h"
     #include "llvm/ADT/Statistic.h"
    @@ -33,93 +33,321 @@
     STATISTIC(NumModRefUnfold, "Number of modref unfolded");
     
     namespace {
    -  enum SpillerName { simple, local };
    +  enum RewriterName { simple, local };
     }
     
    -static cl::opt
    -SpillerOpt("spiller",
    -           cl::desc("Spiller to use: (default: local)"),
    -           cl::Prefix,
    -           cl::values(clEnumVal(simple, "simple spiller"),
    -                      clEnumVal(local,  "local spiller"),
    -                      clEnumValEnd),
    -           cl::init(local));
    +static cl::opt
    +RewriterOpt("rewriter",
    +            cl::desc("Rewriter to use: (default: local)"),
    +            cl::Prefix,
    +            cl::values(clEnumVal(simple, "simple rewriter"),
    +                       clEnumVal(local,  "local rewriter"),
    +                       clEnumValEnd),
    +            cl::init(local));
     
    +VirtRegRewriter::~VirtRegRewriter() {}
    +
    + 
     // ****************************** //
     // Simple Spiller Implementation  //
     // ****************************** //
     
    -Spiller::~Spiller() {}
    +struct VISIBILITY_HIDDEN SimpleRewriter : public VirtRegRewriter {
     
    -bool SimpleSpiller::runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM,
    -                                         LiveIntervals* LIs) {
    -  DOUT << "********** REWRITE MACHINE CODE **********\n";
    -  DOUT << "********** Function: " << MF.getFunction()->getName() << '\n';
    -  const TargetMachine &TM = MF.getTarget();
    -  const TargetInstrInfo &TII = *TM.getInstrInfo();
    -  const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
    -
    -
    -  // LoadedRegs - Keep track of which vregs are loaded, so that we only load
    -  // each vreg once (in the case where a spilled vreg is used by multiple
    -  // operands).  This is always smaller than the number of operands to the
    -  // current machine instr, so it should be small.
    -  std::vector LoadedRegs;
    -
    -  for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end();
    -       MBBI != E; ++MBBI) {
    -    DOUT << MBBI->getBasicBlock()->getName() << ":\n";
    -    MachineBasicBlock &MBB = *MBBI;
    -    for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
    -         MII != E; ++MII) {
    -      MachineInstr &MI = *MII;
    -      for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    -        MachineOperand &MO = MI.getOperand(i);
    -        if (MO.isReg() && MO.getReg()) {
    -          if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
    -            unsigned VirtReg = MO.getReg();
    -            unsigned SubIdx = MO.getSubReg();
    -            unsigned PhysReg = VRM.getPhys(VirtReg);
    -            unsigned RReg = SubIdx ? TRI.getSubReg(PhysReg, SubIdx) : PhysReg;
    -            if (!VRM.isAssignedReg(VirtReg)) {
    -              int StackSlot = VRM.getStackSlot(VirtReg);
    -              const TargetRegisterClass* RC = 
    -                                           MF.getRegInfo().getRegClass(VirtReg);
    -              
    -              if (MO.isUse() &&
    -                  std::find(LoadedRegs.begin(), LoadedRegs.end(), VirtReg)
    -                           == LoadedRegs.end()) {
    -                TII.loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot, RC);
    -                MachineInstr *LoadMI = prior(MII);
    -                VRM.addSpillSlotUse(StackSlot, LoadMI);
    -                LoadedRegs.push_back(VirtReg);
    -                ++NumLoads;
    -                DOUT << '\t' << *LoadMI;
    -              }
    -
    -              if (MO.isDef()) {
    -                TII.storeRegToStackSlot(MBB, next(MII), PhysReg, true,   
    -                                        StackSlot, RC);
    -                MachineInstr *StoreMI = next(MII);
    -                VRM.addSpillSlotUse(StackSlot, StoreMI);
    -                ++NumStores;
    +  bool runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM,
    +                            LiveIntervals* LIs) {
    +    DOUT << "********** REWRITE MACHINE CODE **********\n";
    +    DOUT << "********** Function: " << MF.getFunction()->getName() << '\n';
    +    const TargetMachine &TM = MF.getTarget();
    +    const TargetInstrInfo &TII = *TM.getInstrInfo();
    +    const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
    +
    +
    +    // LoadedRegs - Keep track of which vregs are loaded, so that we only load
    +    // each vreg once (in the case where a spilled vreg is used by multiple
    +    // operands).  This is always smaller than the number of operands to the
    +    // current machine instr, so it should be small.
    +    std::vector LoadedRegs;
    +
    +    for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end();
    +         MBBI != E; ++MBBI) {
    +      DOUT << MBBI->getBasicBlock()->getName() << ":\n";
    +      MachineBasicBlock &MBB = *MBBI;
    +      for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
    +           MII != E; ++MII) {
    +        MachineInstr &MI = *MII;
    +        for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    +          MachineOperand &MO = MI.getOperand(i);
    +          if (MO.isReg() && MO.getReg()) {
    +            if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
    +              unsigned VirtReg = MO.getReg();
    +              unsigned SubIdx = MO.getSubReg();
    +              unsigned PhysReg = VRM.getPhys(VirtReg);
    +              unsigned RReg = SubIdx ? TRI.getSubReg(PhysReg, SubIdx) : PhysReg;
    +              if (!VRM.isAssignedReg(VirtReg)) {
    +                int StackSlot = VRM.getStackSlot(VirtReg);
    +                const TargetRegisterClass* RC = 
    +                                             MF.getRegInfo().getRegClass(VirtReg);
    +                
    +                if (MO.isUse() &&
    +                    std::find(LoadedRegs.begin(), LoadedRegs.end(), VirtReg)
    +                             == LoadedRegs.end()) {
    +                  TII.loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot, RC);
    +                  MachineInstr *LoadMI = prior(MII);
    +                  VRM.addSpillSlotUse(StackSlot, LoadMI);
    +                  LoadedRegs.push_back(VirtReg);
    +                  ++NumLoads;
    +                  DOUT << '\t' << *LoadMI;
    +                }
    +
    +                if (MO.isDef()) {
    +                  TII.storeRegToStackSlot(MBB, next(MII), PhysReg, true,   
    +                                          StackSlot, RC);
    +                  MachineInstr *StoreMI = next(MII);
    +                  VRM.addSpillSlotUse(StackSlot, StoreMI);
    +                  ++NumStores;
    +                }
                   }
    +              MF.getRegInfo().setPhysRegUsed(RReg);
    +              MI.getOperand(i).setReg(RReg);
    +              MI.getOperand(i).setSubReg(0);
    +            } else {
    +              MF.getRegInfo().setPhysRegUsed(MO.getReg());
                 }
    -            MF.getRegInfo().setPhysRegUsed(RReg);
    -            MI.getOperand(i).setReg(RReg);
    -            MI.getOperand(i).setSubReg(0);
    -          } else {
    -            MF.getRegInfo().setPhysRegUsed(MO.getReg());
               }
             }
    +
    +        DOUT << '\t' << MI;
    +        LoadedRegs.clear();
           }
    +    }
    +    return true;
    +  }
     
    -      DOUT << '\t' << MI;
    -      LoadedRegs.clear();
    +};
    + 
    +// ************************************************************************ //
    +
    +/// AvailableSpills - As the local rewriter is scanning and rewriting an MBB
    +/// from top down, keep track of which spill slots or remat are available in
    +/// each register.
    +///
    +/// Note that not all physregs are created equal here.  In particular, some
    +/// physregs are reloads that we are allowed to clobber or ignore at any time.
    +/// Other physregs are values that the register allocated program is using
    +/// that we cannot CHANGE, but we can read if we like.  We keep track of this
    +/// on a per-stack-slot / remat id basis as the low bit in the value of the
    +/// SpillSlotsAvailable entries.  The predicate 'canClobberPhysReg()' checks
    +/// this bit and addAvailable sets it if.
    +class VISIBILITY_HIDDEN AvailableSpills {
    +  const TargetRegisterInfo *TRI;
    +  const TargetInstrInfo *TII;
    +
    +  // SpillSlotsOrReMatsAvailable - This map keeps track of all of the spilled
    +  // or remat'ed virtual register values that are still available, due to
    +  // being loaded or stored to, but not invalidated yet.
    +  std::map SpillSlotsOrReMatsAvailable;
    +
    +  // PhysRegsAvailable - This is the inverse of SpillSlotsOrReMatsAvailable,
    +  // indicating which stack slot values are currently held by a physreg.  This
    +  // is used to invalidate entries in SpillSlotsOrReMatsAvailable when a
    +  // physreg is modified.
    +  std::multimap PhysRegsAvailable;
    +
    +  void disallowClobberPhysRegOnly(unsigned PhysReg);
    +
    +  void ClobberPhysRegOnly(unsigned PhysReg);
    +public:
    +  AvailableSpills(const TargetRegisterInfo *tri, const TargetInstrInfo *tii)
    +    : TRI(tri), TII(tii) {
    +  }
    +
    +  /// clear - Reset the state.
    +  void clear() {
    +    SpillSlotsOrReMatsAvailable.clear();
    +    PhysRegsAvailable.clear();
    +  }
    +
    +  const TargetRegisterInfo *getRegInfo() const { return TRI; }
    +
    +  /// getSpillSlotOrReMatPhysReg - If the specified stack slot or remat is
    +  /// available in a physical register, return that PhysReg, otherwise
    +  /// return 0.
    +  unsigned getSpillSlotOrReMatPhysReg(int Slot) const {
    +    std::map::const_iterator I =
    +      SpillSlotsOrReMatsAvailable.find(Slot);
    +    if (I != SpillSlotsOrReMatsAvailable.end()) {
    +      return I->second >> 1;  // Remove the CanClobber bit.
    +    }
    +    return 0;
    +  }
    +
    +  /// addAvailable - Mark that the specified stack slot / remat is available
    +  /// in the specified physreg.  If CanClobber is true, the physreg can be
    +  /// modified at any time without changing the semantics of the program.
    +  void addAvailable(int SlotOrReMat, unsigned Reg, bool CanClobber = true) {
    +    // If this stack slot is thought to be available in some other physreg, 
    +    // remove its record.
    +    ModifyStackSlotOrReMat(SlotOrReMat);
    +
    +    PhysRegsAvailable.insert(std::make_pair(Reg, SlotOrReMat));
    +    SpillSlotsOrReMatsAvailable[SlotOrReMat]= (Reg << 1) |
    +                                              (unsigned)CanClobber;
    +
    +    if (SlotOrReMat > VirtRegMap::MAX_STACK_SLOT)
    +      DOUT << "Remembering RM#" << SlotOrReMat-VirtRegMap::MAX_STACK_SLOT-1;
    +    else
    +      DOUT << "Remembering SS#" << SlotOrReMat;
    +    DOUT << " in physreg " << TRI->getName(Reg) << "\n";
    +  }
    +
    +  /// canClobberPhysRegForSS - Return true if the spiller is allowed to change
    +  /// the value of the specified stackslot register if it desires. The
    +  /// specified stack slot must be available in a physreg for this query to
    +  /// make sense.
    +  bool canClobberPhysRegForSS(int SlotOrReMat) const {
    +    assert(SpillSlotsOrReMatsAvailable.count(SlotOrReMat) &&
    +           "Value not available!");
    +    return SpillSlotsOrReMatsAvailable.find(SlotOrReMat)->second & 1;
    +  }
    +
    +  /// canClobberPhysReg - Return true if the spiller is allowed to clobber the
    +  /// physical register where values for some stack slot(s) might be
    +  /// available.
    +  bool canClobberPhysReg(unsigned PhysReg) const {
    +    std::multimap::const_iterator I =
    +      PhysRegsAvailable.lower_bound(PhysReg);
    +    while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
    +      int SlotOrReMat = I->second;
    +      I++;
    +      if (!canClobberPhysRegForSS(SlotOrReMat))
    +        return false;
         }
    +    return true;
       }
    -  return true;
    -}
    +
    +  /// disallowClobberPhysReg - Unset the CanClobber bit of the specified
    +  /// stackslot register. The register is still available but is no longer
    +  /// allowed to be modifed.
    +  void disallowClobberPhysReg(unsigned PhysReg);
    +
    +  /// ClobberPhysReg - This is called when the specified physreg changes
    +  /// value.  We use this to invalidate any info about stuff that lives in
    +  /// it and any of its aliases.
    +  void ClobberPhysReg(unsigned PhysReg);
    +
    +  /// ModifyStackSlotOrReMat - This method is called when the value in a stack
    +  /// slot changes.  This removes information about which register the
    +  /// previous value for this slot lives in (as the previous value is dead
    +  /// now).
    +  void ModifyStackSlotOrReMat(int SlotOrReMat);
    +
    +  /// AddAvailableRegsToLiveIn - Availability information is being kept coming
    +  /// into the specified MBB. Add available physical registers as potential
    +  /// live-in's. If they are reused in the MBB, they will be added to the
    +  /// live-in set to make register scavenger and post-allocation scheduler.
    +  void AddAvailableRegsToLiveIn(MachineBasicBlock &MBB, BitVector &RegKills,
    +                                std::vector &KillOps);
    +};
    +
    +// ************************************************************************ //
    +
    +// ReusedOp - For each reused operand, we keep track of a bit of information,
    +// in case we need to rollback upon processing a new operand.  See comments
    +// below.
    +struct ReusedOp {
    +  // The MachineInstr operand that reused an available value.
    +  unsigned Operand;
    +
    +  // StackSlotOrReMat - The spill slot or remat id of the value being reused.
    +  unsigned StackSlotOrReMat;
    +
    +  // PhysRegReused - The physical register the value was available in.
    +  unsigned PhysRegReused;
    +
    +  // AssignedPhysReg - The physreg that was assigned for use by the reload.
    +  unsigned AssignedPhysReg;
    +  
    +  // VirtReg - The virtual register itself.
    +  unsigned VirtReg;
    +
    +  ReusedOp(unsigned o, unsigned ss, unsigned prr, unsigned apr,
    +           unsigned vreg)
    +    : Operand(o), StackSlotOrReMat(ss), PhysRegReused(prr),
    +      AssignedPhysReg(apr), VirtReg(vreg) {}
    +};
    +
    +/// ReuseInfo - This maintains a collection of ReuseOp's for each operand that
    +/// is reused instead of reloaded.
    +class VISIBILITY_HIDDEN ReuseInfo {
    +  MachineInstr &MI;
    +  std::vector Reuses;
    +  BitVector PhysRegsClobbered;
    +public:
    +  ReuseInfo(MachineInstr &mi, const TargetRegisterInfo *tri) : MI(mi) {
    +    PhysRegsClobbered.resize(tri->getNumRegs());
    +  }
    +  
    +  bool hasReuses() const {
    +    return !Reuses.empty();
    +  }
    +  
    +  /// addReuse - If we choose to reuse a virtual register that is already
    +  /// available instead of reloading it, remember that we did so.
    +  void addReuse(unsigned OpNo, unsigned StackSlotOrReMat,
    +                unsigned PhysRegReused, unsigned AssignedPhysReg,
    +                unsigned VirtReg) {
    +    // If the reload is to the assigned register anyway, no undo will be
    +    // required.
    +    if (PhysRegReused == AssignedPhysReg) return;
    +    
    +    // Otherwise, remember this.
    +    Reuses.push_back(ReusedOp(OpNo, StackSlotOrReMat, PhysRegReused, 
    +                              AssignedPhysReg, VirtReg));
    +  }
    +
    +  void markClobbered(unsigned PhysReg) {
    +    PhysRegsClobbered.set(PhysReg);
    +  }
    +
    +  bool isClobbered(unsigned PhysReg) const {
    +    return PhysRegsClobbered.test(PhysReg);
    +  }
    +  
    +  /// GetRegForReload - We are about to emit a reload into PhysReg.  If there
    +  /// is some other operand that is using the specified register, either pick
    +  /// a new register to use, or evict the previous reload and use this reg. 
    +  unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
    +                           AvailableSpills &Spills,
    +                           std::vector &MaybeDeadStores,
    +                           SmallSet &Rejected,
    +                           BitVector &RegKills,
    +                           std::vector &KillOps,
    +                           VirtRegMap &VRM);
    +
    +  /// GetRegForReload - Helper for the above GetRegForReload(). Add a
    +  /// 'Rejected' set to remember which registers have been considered and
    +  /// rejected for the reload. This avoids infinite looping in case like
    +  /// this:
    +  /// t1 := op t2, t3
    +  /// t2 <- assigned r0 for use by the reload but ended up reuse r1
    +  /// t3 <- assigned r1 for use by the reload but ended up reuse r0
    +  /// t1 <- desires r1
    +  ///       sees r1 is taken by t2, tries t2's reload register r0
    +  ///       sees r0 is taken by t3, tries t3's reload register r1
    +  ///       sees r1 is taken by t2, tries t2's reload register r0 ...
    +  unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
    +                           AvailableSpills &Spills,
    +                           std::vector &MaybeDeadStores,
    +                           BitVector &RegKills,
    +                           std::vector &KillOps,
    +                           VirtRegMap &VRM) {
    +    SmallSet Rejected;
    +    return GetRegForReload(PhysReg, MI, Spills, MaybeDeadStores, Rejected,
    +                           RegKills, KillOps, VRM);
    +  }
    +};
    +
     
     // ****************** //
     // Utility Functions  //
    @@ -519,86 +747,7 @@
       return PhysReg;
     }
     
    -// ***************************** //
    -// Local Spiller Implementation  //
    -// ***************************** //
    -
    -bool LocalSpiller::runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM,
    -                                        LiveIntervals* LIs) {
    -  RegInfo = &MF.getRegInfo(); 
    -  TRI = MF.getTarget().getRegisterInfo();
    -  TII = MF.getTarget().getInstrInfo();
    -  AllocatableRegs = TRI->getAllocatableSet(MF);
    -  DOUT << "\n**** Local spiller rewriting function '"
    -       << MF.getFunction()->getName() << "':\n";
    -  DOUT << "**** Machine Instrs (NOTE! Does not include spills and reloads!)"
    -          " ****\n";
    -  DEBUG(MF.dump());
    -
    -  // Spills - Keep track of which spilled values are available in physregs
    -  // so that we can choose to reuse the physregs instead of emitting
    -  // reloads. This is usually refreshed per basic block.
    -  AvailableSpills Spills(TRI, TII);
    -
    -  // Keep track of kill information.
    -  BitVector RegKills(TRI->getNumRegs());
    -  std::vector KillOps;
    -  KillOps.resize(TRI->getNumRegs(), NULL);
    -
    -  // SingleEntrySuccs - Successor blocks which have a single predecessor.
    -  SmallVector SinglePredSuccs;
    -  SmallPtrSet EarlyVisited;
    -
    -  // Traverse the basic blocks depth first.
    -  MachineBasicBlock *Entry = MF.begin();
    -  SmallPtrSet Visited;
    -  for (df_ext_iterator >
    -         DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited);
    -       DFI != E; ++DFI) {
    -    MachineBasicBlock *MBB = *DFI;
    -    if (!EarlyVisited.count(MBB))
    -      RewriteMBB(*MBB, VRM, LIs, Spills, RegKills, KillOps);
    -
    -    // If this MBB is the only predecessor of a successor. Keep the
    -    // availability information and visit it next.
    -    do {
    -      // Keep visiting single predecessor successor as long as possible.
    -      SinglePredSuccs.clear();
    -      findSinglePredSuccessor(MBB, SinglePredSuccs);
    -      if (SinglePredSuccs.empty())
    -        MBB = 0;
    -      else {
    -        // FIXME: More than one successors, each of which has MBB has
    -        // the only predecessor.
    -        MBB = SinglePredSuccs[0];
    -        if (!Visited.count(MBB) && EarlyVisited.insert(MBB)) {
    -          Spills.AddAvailableRegsToLiveIn(*MBB, RegKills, KillOps);
    -          RewriteMBB(*MBB, VRM, LIs, Spills, RegKills, KillOps);
    -        }
    -      }
    -    } while (MBB);
    -
    -    // Clear the availability info.
    -    Spills.clear();
    -  }
    -
    -  DOUT << "**** Post Machine Instrs ****\n";
    -  DEBUG(MF.dump());
    -
    -  // Mark unused spill slots.
    -  MachineFrameInfo *MFI = MF.getFrameInfo();
    -  int SS = VRM.getLowSpillSlot();
    -  if (SS != VirtRegMap::NO_STACK_SLOT)
    -    for (int e = VRM.getHighSpillSlot(); SS <= e; ++SS)
    -      if (!VRM.isSpillSlotUsed(SS)) {
    -        MFI->RemoveStackObject(SS);
    -        ++NumDSS;
    -      }
    -
    -  return true;
    -}
    -
    +// ************************************************************************ //
     
     /// FoldsStackSlotModRef - Return true if the specified MI folds the specified
     /// stack slot mod/ref. It also checks if it's possible to unfold the
    @@ -702,1195 +851,1291 @@
       }
     }
     
    -/// OptimizeByUnfold2 - Unfold a series of load / store folding instructions if
    -/// a scratch register is available.
    -///     xorq  %r12, %r13
    -///     addq  %rax, -184(%rbp)
    -///     addq  %r13, -184(%rbp)
    -/// ==>
    -///     xorq  %r12, %r13
    -///     movq  -184(%rbp), %r12
    -///     addq  %rax, %r12
    -///     addq  %r13, %r12
    -///     movq  %r12, -184(%rbp)
    -bool LocalSpiller::OptimizeByUnfold2(unsigned VirtReg, int SS,
    -                                    MachineBasicBlock &MBB,
    -                                    MachineBasicBlock::iterator &MII,
    -                                    std::vector &MaybeDeadStores,
    -                                    AvailableSpills &Spills,
    -                                    BitVector &RegKills,
    -                                    std::vector &KillOps,
    -                                    VirtRegMap &VRM) {
    -  MachineBasicBlock::iterator NextMII = next(MII);
    -  if (NextMII == MBB.end())
    -    return false;
     
    -  if (TII->getOpcodeAfterMemoryUnfold(MII->getOpcode(), true, true) == 0)
    -    return false;
    +// ***************************** //
    +// Local Spiller Implementation  //
    +// ***************************** //
     
    -  // Now let's see if the last couple of instructions happens to have freed up
    -  // a register.
    -  const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -  unsigned PhysReg = FindFreeRegister(MII, MBB, RC, TRI, AllocatableRegs);
    -  if (!PhysReg)
    -    return false;
    +class VISIBILITY_HIDDEN LocalRewriter : public VirtRegRewriter {
    +  MachineRegisterInfo *RegInfo;
    +  const TargetRegisterInfo *TRI;
    +  const TargetInstrInfo *TII;
    +  BitVector AllocatableRegs;
    +  DenseMap DistanceMap;
    +public:
    +
    +  bool runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM,
    +                            LiveIntervals* LIs) {
    +    RegInfo = &MF.getRegInfo(); 
    +    TRI = MF.getTarget().getRegisterInfo();
    +    TII = MF.getTarget().getInstrInfo();
    +    AllocatableRegs = TRI->getAllocatableSet(MF);
    +    DOUT << "\n**** Local spiller rewriting function '"
    +         << MF.getFunction()->getName() << "':\n";
    +    DOUT << "**** Machine Instrs (NOTE! Does not include spills and reloads!)"
    +            " ****\n";
    +    DEBUG(MF.dump());
    +
    +    // Spills - Keep track of which spilled values are available in physregs
    +    // so that we can choose to reuse the physregs instead of emitting
    +    // reloads. This is usually refreshed per basic block.
    +    AvailableSpills Spills(TRI, TII);
    +
    +    // Keep track of kill information.
    +    BitVector RegKills(TRI->getNumRegs());
    +    std::vector KillOps;
    +    KillOps.resize(TRI->getNumRegs(), NULL);
    +
    +    // SingleEntrySuccs - Successor blocks which have a single predecessor.
    +    SmallVector SinglePredSuccs;
    +    SmallPtrSet EarlyVisited;
    +
    +    // Traverse the basic blocks depth first.
    +    MachineBasicBlock *Entry = MF.begin();
    +    SmallPtrSet Visited;
    +    for (df_ext_iterator >
    +           DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited);
    +         DFI != E; ++DFI) {
    +      MachineBasicBlock *MBB = *DFI;
    +      if (!EarlyVisited.count(MBB))
    +        RewriteMBB(*MBB, VRM, LIs, Spills, RegKills, KillOps);
    +
    +      // If this MBB is the only predecessor of a successor. Keep the
    +      // availability information and visit it next.
    +      do {
    +        // Keep visiting single predecessor successor as long as possible.
    +        SinglePredSuccs.clear();
    +        findSinglePredSuccessor(MBB, SinglePredSuccs);
    +        if (SinglePredSuccs.empty())
    +          MBB = 0;
    +        else {
    +          // FIXME: More than one successors, each of which has MBB has
    +          // the only predecessor.
    +          MBB = SinglePredSuccs[0];
    +          if (!Visited.count(MBB) && EarlyVisited.insert(MBB)) {
    +            Spills.AddAvailableRegsToLiveIn(*MBB, RegKills, KillOps);
    +            RewriteMBB(*MBB, VRM, LIs, Spills, RegKills, KillOps);
    +          }
    +        }
    +      } while (MBB);
     
    -  MachineFunction &MF = *MBB.getParent();
    -  TRI = MF.getTarget().getRegisterInfo();
    -  MachineInstr &MI = *MII;
    -  if (!FoldsStackSlotModRef(MI, SS, PhysReg, TII, TRI, VRM))
    -    return false;
    +      // Clear the availability info.
    +      Spills.clear();
    +    }
     
    -  // If the next instruction also folds the same SS modref and can be unfoled,
    -  // then it's worthwhile to issue a load from SS into the free register and
    -  // then unfold these instructions.
    -  if (!FoldsStackSlotModRef(*NextMII, SS, PhysReg, TII, TRI, VRM))
    -    return false;
    +    DOUT << "**** Post Machine Instrs ****\n";
    +    DEBUG(MF.dump());
     
    -  // Load from SS to the spare physical register.
    -  TII->loadRegFromStackSlot(MBB, MII, PhysReg, SS, RC);
    -  // This invalidates Phys.
    -  Spills.ClobberPhysReg(PhysReg);
    -  // Remember it's available.
    -  Spills.addAvailable(SS, PhysReg);
    -  MaybeDeadStores[SS] = NULL;
    -
    -  // Unfold current MI.
    -  SmallVector NewMIs;
    -  if (!TII->unfoldMemoryOperand(MF, &MI, VirtReg, false, false, NewMIs))
    -    assert(0 && "Unable unfold the load / store folding instruction!");
    -  assert(NewMIs.size() == 1);
    -  AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg);
    -  VRM.transferRestorePts(&MI, NewMIs[0]);
    -  MII = MBB.insert(MII, NewMIs[0]);
    -  InvalidateKills(MI, RegKills, KillOps);
    -  VRM.RemoveMachineInstrFromMaps(&MI);
    -  MBB.erase(&MI);
    -  ++NumModRefUnfold;
    -
    -  // Unfold next instructions that fold the same SS.
    -  do {
    -    MachineInstr &NextMI = *NextMII;
    -    NextMII = next(NextMII);
    -    NewMIs.clear();
    -    if (!TII->unfoldMemoryOperand(MF, &NextMI, VirtReg, false, false, NewMIs))
    -      assert(0 && "Unable unfold the load / store folding instruction!");
    -    assert(NewMIs.size() == 1);
    -    AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg);
    -    VRM.transferRestorePts(&NextMI, NewMIs[0]);
    -    MBB.insert(NextMII, NewMIs[0]);
    -    InvalidateKills(NextMI, RegKills, KillOps);
    -    VRM.RemoveMachineInstrFromMaps(&NextMI);
    -    MBB.erase(&NextMI);
    -    ++NumModRefUnfold;
    -  } while (FoldsStackSlotModRef(*NextMII, SS, PhysReg, TII, TRI, VRM));
    +    // Mark unused spill slots.
    +    MachineFrameInfo *MFI = MF.getFrameInfo();
    +    int SS = VRM.getLowSpillSlot();
    +    if (SS != VirtRegMap::NO_STACK_SLOT)
    +      for (int e = VRM.getHighSpillSlot(); SS <= e; ++SS)
    +        if (!VRM.isSpillSlotUsed(SS)) {
    +          MFI->RemoveStackObject(SS);
    +          ++NumDSS;
    +        }
     
    -  // Store the value back into SS.
    -  TII->storeRegToStackSlot(MBB, NextMII, PhysReg, true, SS, RC);
    -  MachineInstr *StoreMI = prior(NextMII);
    -  VRM.addSpillSlotUse(SS, StoreMI);
    -  VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod);
    +    return true;
    +  }
     
    -  return true;
    -}
    +private:
     
    -/// OptimizeByUnfold - Turn a store folding instruction into a load folding
    -/// instruction. e.g.
    -///     xorl  %edi, %eax
    -///     movl  %eax, -32(%ebp)
    -///     movl  -36(%ebp), %eax
    -///     orl   %eax, -32(%ebp)
    -/// ==>
    -///     xorl  %edi, %eax
    -///     orl   -36(%ebp), %eax
    -///     mov   %eax, -32(%ebp)
    -/// This enables unfolding optimization for a subsequent instruction which will
    -/// also eliminate the newly introduced store instruction.
    -bool LocalSpiller::OptimizeByUnfold(MachineBasicBlock &MBB,
    -                                    MachineBasicBlock::iterator &MII,
    -                                    std::vector &MaybeDeadStores,
    -                                    AvailableSpills &Spills,
    -                                    BitVector &RegKills,
    -                                    std::vector &KillOps,
    -                                    VirtRegMap &VRM) {
    -  MachineFunction &MF = *MBB.getParent();
    -  MachineInstr &MI = *MII;
    -  unsigned UnfoldedOpc = 0;
    -  unsigned UnfoldPR = 0;
    -  unsigned UnfoldVR = 0;
    -  int FoldedSS = VirtRegMap::NO_STACK_SLOT;
    -  VirtRegMap::MI2VirtMapTy::const_iterator I, End;
    -  for (tie(I, End) = VRM.getFoldedVirts(&MI); I != End; ) {
    -    // Only transform a MI that folds a single register.
    -    if (UnfoldedOpc)
    +  /// OptimizeByUnfold2 - Unfold a series of load / store folding instructions if
    +  /// a scratch register is available.
    +  ///     xorq  %r12, %r13
    +  ///     addq  %rax, -184(%rbp)
    +  ///     addq  %r13, -184(%rbp)
    +  /// ==>
    +  ///     xorq  %r12, %r13
    +  ///     movq  -184(%rbp), %r12
    +  ///     addq  %rax, %r12
    +  ///     addq  %r13, %r12
    +  ///     movq  %r12, -184(%rbp)
    +  bool OptimizeByUnfold2(unsigned VirtReg, int SS,
    +                         MachineBasicBlock &MBB,
    +                         MachineBasicBlock::iterator &MII,
    +                         std::vector &MaybeDeadStores,
    +                         AvailableSpills &Spills,
    +                         BitVector &RegKills,
    +                         std::vector &KillOps,
    +                         VirtRegMap &VRM) {
    +
    +    MachineBasicBlock::iterator NextMII = next(MII);
    +    if (NextMII == MBB.end())
           return false;
    -    UnfoldVR = I->second.first;
    -    VirtRegMap::ModRef MR = I->second.second;
    -    // MI2VirtMap be can updated which invalidate the iterator.
    -    // Increment the iterator first.
    -    ++I; 
    -    if (VRM.isAssignedReg(UnfoldVR))
    -      continue;
    -    // If this reference is not a use, any previous store is now dead.
    -    // Otherwise, the store to this stack slot is not dead anymore.
    -    FoldedSS = VRM.getStackSlot(UnfoldVR);
    -    MachineInstr* DeadStore = MaybeDeadStores[FoldedSS];
    -    if (DeadStore && (MR & VirtRegMap::isModRef)) {
    -      unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(FoldedSS);
    -      if (!PhysReg || !DeadStore->readsRegister(PhysReg))
    -        continue;
    -      UnfoldPR = PhysReg;
    -      UnfoldedOpc = TII->getOpcodeAfterMemoryUnfold(MI.getOpcode(),
    -                                                    false, true);
    -    }
    -  }
     
    -  if (!UnfoldedOpc) {
    -    if (!UnfoldVR)
    +    if (TII->getOpcodeAfterMemoryUnfold(MII->getOpcode(), true, true) == 0)
    +      return false;
    +
    +    // Now let's see if the last couple of instructions happens to have freed up
    +    // a register.
    +    const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    +    unsigned PhysReg = FindFreeRegister(MII, MBB, RC, TRI, AllocatableRegs);
    +    if (!PhysReg)
           return false;
     
    -    // Look for other unfolding opportunities.
    -    return OptimizeByUnfold2(UnfoldVR, FoldedSS, MBB, MII,
    -                             MaybeDeadStores, Spills, RegKills, KillOps, VRM);
    +    MachineFunction &MF = *MBB.getParent();
    +    TRI = MF.getTarget().getRegisterInfo();
    +    MachineInstr &MI = *MII;
    +    if (!FoldsStackSlotModRef(MI, SS, PhysReg, TII, TRI, VRM))
    +      return false;
    +
    +    // If the next instruction also folds the same SS modref and can be unfoled,
    +    // then it's worthwhile to issue a load from SS into the free register and
    +    // then unfold these instructions.
    +    if (!FoldsStackSlotModRef(*NextMII, SS, PhysReg, TII, TRI, VRM))
    +      return false;
    +
    +    // Load from SS to the spare physical register.
    +    TII->loadRegFromStackSlot(MBB, MII, PhysReg, SS, RC);
    +    // This invalidates Phys.
    +    Spills.ClobberPhysReg(PhysReg);
    +    // Remember it's available.
    +    Spills.addAvailable(SS, PhysReg);
    +    MaybeDeadStores[SS] = NULL;
    +
    +    // Unfold current MI.
    +    SmallVector NewMIs;
    +    if (!TII->unfoldMemoryOperand(MF, &MI, VirtReg, false, false, NewMIs))
    +      assert(0 && "Unable unfold the load / store folding instruction!");
    +    assert(NewMIs.size() == 1);
    +    AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg);
    +    VRM.transferRestorePts(&MI, NewMIs[0]);
    +    MII = MBB.insert(MII, NewMIs[0]);
    +    InvalidateKills(MI, RegKills, KillOps);
    +    VRM.RemoveMachineInstrFromMaps(&MI);
    +    MBB.erase(&MI);
    +    ++NumModRefUnfold;
    +
    +    // Unfold next instructions that fold the same SS.
    +    do {
    +      MachineInstr &NextMI = *NextMII;
    +      NextMII = next(NextMII);
    +      NewMIs.clear();
    +      if (!TII->unfoldMemoryOperand(MF, &NextMI, VirtReg, false, false, NewMIs))
    +        assert(0 && "Unable unfold the load / store folding instruction!");
    +      assert(NewMIs.size() == 1);
    +      AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg);
    +      VRM.transferRestorePts(&NextMI, NewMIs[0]);
    +      MBB.insert(NextMII, NewMIs[0]);
    +      InvalidateKills(NextMI, RegKills, KillOps);
    +      VRM.RemoveMachineInstrFromMaps(&NextMI);
    +      MBB.erase(&NextMI);
    +      ++NumModRefUnfold;
    +    } while (FoldsStackSlotModRef(*NextMII, SS, PhysReg, TII, TRI, VRM));
    +
    +    // Store the value back into SS.
    +    TII->storeRegToStackSlot(MBB, NextMII, PhysReg, true, SS, RC);
    +    MachineInstr *StoreMI = prior(NextMII);
    +    VRM.addSpillSlotUse(SS, StoreMI);
    +    VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod);
    +
    +    return true;
       }
     
    -  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    -    MachineOperand &MO = MI.getOperand(i);
    -    if (!MO.isReg() || MO.getReg() == 0 || !MO.isUse())
    -      continue;
    -    unsigned VirtReg = MO.getReg();
    -    if (TargetRegisterInfo::isPhysicalRegister(VirtReg) || MO.getSubReg())
    -      continue;
    -    if (VRM.isAssignedReg(VirtReg)) {
    -      unsigned PhysReg = VRM.getPhys(VirtReg);
    -      if (PhysReg && TRI->regsOverlap(PhysReg, UnfoldPR))
    +  /// OptimizeByUnfold - Turn a store folding instruction into a load folding
    +  /// instruction. e.g.
    +  ///     xorl  %edi, %eax
    +  ///     movl  %eax, -32(%ebp)
    +  ///     movl  -36(%ebp), %eax
    +  ///     orl   %eax, -32(%ebp)
    +  /// ==>
    +  ///     xorl  %edi, %eax
    +  ///     orl   -36(%ebp), %eax
    +  ///     mov   %eax, -32(%ebp)
    +  /// This enables unfolding optimization for a subsequent instruction which will
    +  /// also eliminate the newly introduced store instruction.
    +  bool OptimizeByUnfold(MachineBasicBlock &MBB,
    +                        MachineBasicBlock::iterator &MII,
    +                        std::vector &MaybeDeadStores,
    +                        AvailableSpills &Spills,
    +                        BitVector &RegKills,
    +                        std::vector &KillOps,
    +                        VirtRegMap &VRM) {
    +    MachineFunction &MF = *MBB.getParent();
    +    MachineInstr &MI = *MII;
    +    unsigned UnfoldedOpc = 0;
    +    unsigned UnfoldPR = 0;
    +    unsigned UnfoldVR = 0;
    +    int FoldedSS = VirtRegMap::NO_STACK_SLOT;
    +    VirtRegMap::MI2VirtMapTy::const_iterator I, End;
    +    for (tie(I, End) = VRM.getFoldedVirts(&MI); I != End; ) {
    +      // Only transform a MI that folds a single register.
    +      if (UnfoldedOpc)
             return false;
    -    } else if (VRM.isReMaterialized(VirtReg))
    -      continue;
    -    int SS = VRM.getStackSlot(VirtReg);
    -    unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS);
    -    if (PhysReg) {
    -      if (TRI->regsOverlap(PhysReg, UnfoldPR))
    +      UnfoldVR = I->second.first;
    +      VirtRegMap::ModRef MR = I->second.second;
    +      // MI2VirtMap be can updated which invalidate the iterator.
    +      // Increment the iterator first.
    +      ++I; 
    +      if (VRM.isAssignedReg(UnfoldVR))
    +        continue;
    +      // If this reference is not a use, any previous store is now dead.
    +      // Otherwise, the store to this stack slot is not dead anymore.
    +      FoldedSS = VRM.getStackSlot(UnfoldVR);
    +      MachineInstr* DeadStore = MaybeDeadStores[FoldedSS];
    +      if (DeadStore && (MR & VirtRegMap::isModRef)) {
    +        unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(FoldedSS);
    +        if (!PhysReg || !DeadStore->readsRegister(PhysReg))
    +          continue;
    +        UnfoldPR = PhysReg;
    +        UnfoldedOpc = TII->getOpcodeAfterMemoryUnfold(MI.getOpcode(),
    +                                                      false, true);
    +      }
    +    }
    +
    +    if (!UnfoldedOpc) {
    +      if (!UnfoldVR)
             return false;
    -      continue;
    +
    +      // Look for other unfolding opportunities.
    +      return OptimizeByUnfold2(UnfoldVR, FoldedSS, MBB, MII,
    +                               MaybeDeadStores, Spills, RegKills, KillOps, VRM);
         }
    -    if (VRM.hasPhys(VirtReg)) {
    -      PhysReg = VRM.getPhys(VirtReg);
    -      if (!TRI->regsOverlap(PhysReg, UnfoldPR))
    +
    +    for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    +      MachineOperand &MO = MI.getOperand(i);
    +      if (!MO.isReg() || MO.getReg() == 0 || !MO.isUse())
             continue;
    -    }
    +      unsigned VirtReg = MO.getReg();
    +      if (TargetRegisterInfo::isPhysicalRegister(VirtReg) || MO.getSubReg())
    +        continue;
    +      if (VRM.isAssignedReg(VirtReg)) {
    +        unsigned PhysReg = VRM.getPhys(VirtReg);
    +        if (PhysReg && TRI->regsOverlap(PhysReg, UnfoldPR))
    +          return false;
    +      } else if (VRM.isReMaterialized(VirtReg))
    +        continue;
    +      int SS = VRM.getStackSlot(VirtReg);
    +      unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS);
    +      if (PhysReg) {
    +        if (TRI->regsOverlap(PhysReg, UnfoldPR))
    +          return false;
    +        continue;
    +      }
    +      if (VRM.hasPhys(VirtReg)) {
    +        PhysReg = VRM.getPhys(VirtReg);
    +        if (!TRI->regsOverlap(PhysReg, UnfoldPR))
    +          continue;
    +      }
     
    -    // Ok, we'll need to reload the value into a register which makes
    -    // it impossible to perform the store unfolding optimization later.
    -    // Let's see if it is possible to fold the load if the store is
    -    // unfolded. This allows us to perform the store unfolding
    -    // optimization.
    -    SmallVector NewMIs;
    -    if (TII->unfoldMemoryOperand(MF, &MI, UnfoldVR, false, false, NewMIs)) {
    -      assert(NewMIs.size() == 1);
    -      MachineInstr *NewMI = NewMIs.back();
    -      NewMIs.clear();
    -      int Idx = NewMI->findRegisterUseOperandIdx(VirtReg, false);
    -      assert(Idx != -1);
    -      SmallVector Ops;
    -      Ops.push_back(Idx);
    -      MachineInstr *FoldedMI = TII->foldMemoryOperand(MF, NewMI, Ops, SS);
    -      if (FoldedMI) {
    -        VRM.addSpillSlotUse(SS, FoldedMI);
    -        if (!VRM.hasPhys(UnfoldVR))
    -          VRM.assignVirt2Phys(UnfoldVR, UnfoldPR);
    -        VRM.virtFolded(VirtReg, FoldedMI, VirtRegMap::isRef);
    -        MII = MBB.insert(MII, FoldedMI);
    -        InvalidateKills(MI, RegKills, KillOps);
    -        VRM.RemoveMachineInstrFromMaps(&MI);
    -        MBB.erase(&MI);
    +      // Ok, we'll need to reload the value into a register which makes
    +      // it impossible to perform the store unfolding optimization later.
    +      // Let's see if it is possible to fold the load if the store is
    +      // unfolded. This allows us to perform the store unfolding
    +      // optimization.
    +      SmallVector NewMIs;
    +      if (TII->unfoldMemoryOperand(MF, &MI, UnfoldVR, false, false, NewMIs)) {
    +        assert(NewMIs.size() == 1);
    +        MachineInstr *NewMI = NewMIs.back();
    +        NewMIs.clear();
    +        int Idx = NewMI->findRegisterUseOperandIdx(VirtReg, false);
    +        assert(Idx != -1);
    +        SmallVector Ops;
    +        Ops.push_back(Idx);
    +        MachineInstr *FoldedMI = TII->foldMemoryOperand(MF, NewMI, Ops, SS);
    +        if (FoldedMI) {
    +          VRM.addSpillSlotUse(SS, FoldedMI);
    +          if (!VRM.hasPhys(UnfoldVR))
    +            VRM.assignVirt2Phys(UnfoldVR, UnfoldPR);
    +          VRM.virtFolded(VirtReg, FoldedMI, VirtRegMap::isRef);
    +          MII = MBB.insert(MII, FoldedMI);
    +          InvalidateKills(MI, RegKills, KillOps);
    +          VRM.RemoveMachineInstrFromMaps(&MI);
    +          MBB.erase(&MI);
    +          MF.DeleteMachineInstr(NewMI);
    +          return true;
    +        }
             MF.DeleteMachineInstr(NewMI);
    -        return true;
           }
    -      MF.DeleteMachineInstr(NewMI);
         }
    -  }
    -
    -  return false;
    -}
     
    -/// CommuteToFoldReload -
    -/// Look for
    -/// r1 = load fi#1
    -/// r1 = op r1, r2
    -/// store r1, fi#1
    -///
    -/// If op is commutable and r2 is killed, then we can xform these to
    -/// r2 = op r2, fi#1
    -/// store r2, fi#1
    -bool LocalSpiller::CommuteToFoldReload(MachineBasicBlock &MBB,
    -                                    MachineBasicBlock::iterator &MII,
    -                                    unsigned VirtReg, unsigned SrcReg, int SS,
    -                                    AvailableSpills &Spills,
    -                                    BitVector &RegKills,
    -                                    std::vector &KillOps,
    -                                    const TargetRegisterInfo *TRI,
    -                                    VirtRegMap &VRM) {
    -  if (MII == MBB.begin() || !MII->killsRegister(SrcReg))
         return false;
    +  }
     
    -  MachineFunction &MF = *MBB.getParent();
    -  MachineInstr &MI = *MII;
    -  MachineBasicBlock::iterator DefMII = prior(MII);
    -  MachineInstr *DefMI = DefMII;
    -  const TargetInstrDesc &TID = DefMI->getDesc();
    -  unsigned NewDstIdx;
    -  if (DefMII != MBB.begin() &&
    -      TID.isCommutable() &&
    -      TII->CommuteChangesDestination(DefMI, NewDstIdx)) {
    -    MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx);
    -    unsigned NewReg = NewDstMO.getReg();
    -    if (!NewDstMO.isKill() || TRI->regsOverlap(NewReg, SrcReg))
    -      return false;
    -    MachineInstr *ReloadMI = prior(DefMII);
    -    int FrameIdx;
    -    unsigned DestReg = TII->isLoadFromStackSlot(ReloadMI, FrameIdx);
    -    if (DestReg != SrcReg || FrameIdx != SS)
    +  /// CommuteToFoldReload -
    +  /// Look for
    +  /// r1 = load fi#1
    +  /// r1 = op r1, r2
    +  /// store r1, fi#1
    +  ///
    +  /// If op is commutable and r2 is killed, then we can xform these to
    +  /// r2 = op r2, fi#1
    +  /// store r2, fi#1
    +  bool CommuteToFoldReload(MachineBasicBlock &MBB,
    +                           MachineBasicBlock::iterator &MII,
    +                           unsigned VirtReg, unsigned SrcReg, int SS,
    +                           AvailableSpills &Spills,
    +                           BitVector &RegKills,
    +                           std::vector &KillOps,
    +                           const TargetRegisterInfo *TRI,
    +                           VirtRegMap &VRM) {
    +    if (MII == MBB.begin() || !MII->killsRegister(SrcReg))
           return false;
    -    int UseIdx = DefMI->findRegisterUseOperandIdx(DestReg, false);
    -    if (UseIdx == -1)
    -      return false;
    -    unsigned DefIdx;
    -    if (!MI.isRegTiedToDefOperand(UseIdx, &DefIdx))
    -      return false;
    -    assert(DefMI->getOperand(DefIdx).isReg() &&
    -           DefMI->getOperand(DefIdx).getReg() == SrcReg);
     
    -    // Now commute def instruction.
    -    MachineInstr *CommutedMI = TII->commuteInstruction(DefMI, true);
    -    if (!CommutedMI)
    -      return false;
    -    SmallVector Ops;
    -    Ops.push_back(NewDstIdx);
    -    MachineInstr *FoldedMI = TII->foldMemoryOperand(MF, CommutedMI, Ops, SS);
    -    // Not needed since foldMemoryOperand returns new MI.
    -    MF.DeleteMachineInstr(CommutedMI);
    -    if (!FoldedMI)
    -      return false;
    +    MachineFunction &MF = *MBB.getParent();
    +    MachineInstr &MI = *MII;
    +    MachineBasicBlock::iterator DefMII = prior(MII);
    +    MachineInstr *DefMI = DefMII;
    +    const TargetInstrDesc &TID = DefMI->getDesc();
    +    unsigned NewDstIdx;
    +    if (DefMII != MBB.begin() &&
    +        TID.isCommutable() &&
    +        TII->CommuteChangesDestination(DefMI, NewDstIdx)) {
    +      MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx);
    +      unsigned NewReg = NewDstMO.getReg();
    +      if (!NewDstMO.isKill() || TRI->regsOverlap(NewReg, SrcReg))
    +        return false;
    +      MachineInstr *ReloadMI = prior(DefMII);
    +      int FrameIdx;
    +      unsigned DestReg = TII->isLoadFromStackSlot(ReloadMI, FrameIdx);
    +      if (DestReg != SrcReg || FrameIdx != SS)
    +        return false;
    +      int UseIdx = DefMI->findRegisterUseOperandIdx(DestReg, false);
    +      if (UseIdx == -1)
    +        return false;
    +      unsigned DefIdx;
    +      if (!MI.isRegTiedToDefOperand(UseIdx, &DefIdx))
    +        return false;
    +      assert(DefMI->getOperand(DefIdx).isReg() &&
    +             DefMI->getOperand(DefIdx).getReg() == SrcReg);
     
    -    VRM.addSpillSlotUse(SS, FoldedMI);
    -    VRM.virtFolded(VirtReg, FoldedMI, VirtRegMap::isRef);
    -    // Insert new def MI and spill MI.
    -    const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -    TII->storeRegToStackSlot(MBB, &MI, NewReg, true, SS, RC);
    -    MII = prior(MII);
    -    MachineInstr *StoreMI = MII;
    -    VRM.addSpillSlotUse(SS, StoreMI);
    -    VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod);
    -    MII = MBB.insert(MII, FoldedMI);  // Update MII to backtrack.
    +      // Now commute def instruction.
    +      MachineInstr *CommutedMI = TII->commuteInstruction(DefMI, true);
    +      if (!CommutedMI)
    +        return false;
    +      SmallVector Ops;
    +      Ops.push_back(NewDstIdx);
    +      MachineInstr *FoldedMI = TII->foldMemoryOperand(MF, CommutedMI, Ops, SS);
    +      // Not needed since foldMemoryOperand returns new MI.
    +      MF.DeleteMachineInstr(CommutedMI);
    +      if (!FoldedMI)
    +        return false;
     
    -    // Delete all 3 old instructions.
    -    InvalidateKills(*ReloadMI, RegKills, KillOps);
    -    VRM.RemoveMachineInstrFromMaps(ReloadMI);
    -    MBB.erase(ReloadMI);
    -    InvalidateKills(*DefMI, RegKills, KillOps);
    -    VRM.RemoveMachineInstrFromMaps(DefMI);
    -    MBB.erase(DefMI);
    -    InvalidateKills(MI, RegKills, KillOps);
    -    VRM.RemoveMachineInstrFromMaps(&MI);
    -    MBB.erase(&MI);
    +      VRM.addSpillSlotUse(SS, FoldedMI);
    +      VRM.virtFolded(VirtReg, FoldedMI, VirtRegMap::isRef);
    +      // Insert new def MI and spill MI.
    +      const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    +      TII->storeRegToStackSlot(MBB, &MI, NewReg, true, SS, RC);
    +      MII = prior(MII);
    +      MachineInstr *StoreMI = MII;
    +      VRM.addSpillSlotUse(SS, StoreMI);
    +      VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod);
    +      MII = MBB.insert(MII, FoldedMI);  // Update MII to backtrack.
    +
    +      // Delete all 3 old instructions.
    +      InvalidateKills(*ReloadMI, RegKills, KillOps);
    +      VRM.RemoveMachineInstrFromMaps(ReloadMI);
    +      MBB.erase(ReloadMI);
    +      InvalidateKills(*DefMI, RegKills, KillOps);
    +      VRM.RemoveMachineInstrFromMaps(DefMI);
    +      MBB.erase(DefMI);
    +      InvalidateKills(MI, RegKills, KillOps);
    +      VRM.RemoveMachineInstrFromMaps(&MI);
    +      MBB.erase(&MI);
    +
    +      // If NewReg was previously holding value of some SS, it's now clobbered.
    +      // This has to be done now because it's a physical register. When this
    +      // instruction is re-visited, it's ignored.
    +      Spills.ClobberPhysReg(NewReg);
     
    -    // If NewReg was previously holding value of some SS, it's now clobbered.
    -    // This has to be done now because it's a physical register. When this
    -    // instruction is re-visited, it's ignored.
    -    Spills.ClobberPhysReg(NewReg);
    +      ++NumCommutes;
    +      return true;
    +    }
     
    -    ++NumCommutes;
    -    return true;
    +    return false;
       }
     
    -  return false;
    -}
    -
    -/// SpillRegToStackSlot - Spill a register to a specified stack slot. Check if
    -/// the last store to the same slot is now dead. If so, remove the last store.
    -void LocalSpiller::SpillRegToStackSlot(MachineBasicBlock &MBB,
    -                                  MachineBasicBlock::iterator &MII,
    -                                  int Idx, unsigned PhysReg, int StackSlot,
    -                                  const TargetRegisterClass *RC,
    -                                  bool isAvailable, MachineInstr *&LastStore,
    -                                  AvailableSpills &Spills,
    -                                  SmallSet &ReMatDefs,
    -                                  BitVector &RegKills,
    -                                  std::vector &KillOps,
    -                                  VirtRegMap &VRM) {
    -  TII->storeRegToStackSlot(MBB, next(MII), PhysReg, true, StackSlot, RC);
    -  MachineInstr *StoreMI = next(MII);
    -  VRM.addSpillSlotUse(StackSlot, StoreMI);
    -  DOUT << "Store:\t" << *StoreMI;
    -
    -  // If there is a dead store to this stack slot, nuke it now.
    -  if (LastStore) {
    -    DOUT << "Removed dead store:\t" << *LastStore;
    -    ++NumDSE;
    -    SmallVector KillRegs;
    -    InvalidateKills(*LastStore, RegKills, KillOps, &KillRegs);
    -    MachineBasicBlock::iterator PrevMII = LastStore;
    -    bool CheckDef = PrevMII != MBB.begin();
    -    if (CheckDef)
    -      --PrevMII;
    -    VRM.RemoveMachineInstrFromMaps(LastStore);
    -    MBB.erase(LastStore);
    -    if (CheckDef) {
    -      // Look at defs of killed registers on the store. Mark the defs
    -      // as dead since the store has been deleted and they aren't
    -      // being reused.
    -      for (unsigned j = 0, ee = KillRegs.size(); j != ee; ++j) {
    -        bool HasOtherDef = false;
    -        if (InvalidateRegDef(PrevMII, *MII, KillRegs[j], HasOtherDef)) {
    -          MachineInstr *DeadDef = PrevMII;
    -          if (ReMatDefs.count(DeadDef) && !HasOtherDef) {
    -            // FIXME: This assumes a remat def does not have side
    -            // effects.
    -            VRM.RemoveMachineInstrFromMaps(DeadDef);
    -            MBB.erase(DeadDef);
    -            ++NumDRM;
    +  /// SpillRegToStackSlot - Spill a register to a specified stack slot. Check if
    +  /// the last store to the same slot is now dead. If so, remove the last store.
    +  void SpillRegToStackSlot(MachineBasicBlock &MBB,
    +                           MachineBasicBlock::iterator &MII,
    +                           int Idx, unsigned PhysReg, int StackSlot,
    +                           const TargetRegisterClass *RC,
    +                           bool isAvailable, MachineInstr *&LastStore,
    +                           AvailableSpills &Spills,
    +                           SmallSet &ReMatDefs,
    +                           BitVector &RegKills,
    +                           std::vector &KillOps,
    +                           VirtRegMap &VRM) {
    +
    +    TII->storeRegToStackSlot(MBB, next(MII), PhysReg, true, StackSlot, RC);
    +    MachineInstr *StoreMI = next(MII);
    +    VRM.addSpillSlotUse(StackSlot, StoreMI);
    +    DOUT << "Store:\t" << *StoreMI;
    +
    +    // If there is a dead store to this stack slot, nuke it now.
    +    if (LastStore) {
    +      DOUT << "Removed dead store:\t" << *LastStore;
    +      ++NumDSE;
    +      SmallVector KillRegs;
    +      InvalidateKills(*LastStore, RegKills, KillOps, &KillRegs);
    +      MachineBasicBlock::iterator PrevMII = LastStore;
    +      bool CheckDef = PrevMII != MBB.begin();
    +      if (CheckDef)
    +        --PrevMII;
    +      VRM.RemoveMachineInstrFromMaps(LastStore);
    +      MBB.erase(LastStore);
    +      if (CheckDef) {
    +        // Look at defs of killed registers on the store. Mark the defs
    +        // as dead since the store has been deleted and they aren't
    +        // being reused.
    +        for (unsigned j = 0, ee = KillRegs.size(); j != ee; ++j) {
    +          bool HasOtherDef = false;
    +          if (InvalidateRegDef(PrevMII, *MII, KillRegs[j], HasOtherDef)) {
    +            MachineInstr *DeadDef = PrevMII;
    +            if (ReMatDefs.count(DeadDef) && !HasOtherDef) {
    +              // FIXME: This assumes a remat def does not have side
    +              // effects.
    +              VRM.RemoveMachineInstrFromMaps(DeadDef);
    +              MBB.erase(DeadDef);
    +              ++NumDRM;
    +            }
               }
             }
           }
         }
    -  }
    -
    -  LastStore = next(MII);
    -
    -  // If the stack slot value was previously available in some other
    -  // register, change it now.  Otherwise, make the register available,
    -  // in PhysReg.
    -  Spills.ModifyStackSlotOrReMat(StackSlot);
    -  Spills.ClobberPhysReg(PhysReg);
    -  Spills.addAvailable(StackSlot, PhysReg, isAvailable);
    -  ++NumStores;
    -}
     
    -/// TransferDeadness - A identity copy definition is dead and it's being
    -/// removed. Find the last def or use and mark it as dead / kill.
    -void LocalSpiller::TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
    -                                    unsigned Reg, BitVector &RegKills,
    -                                    std::vector &KillOps) {
    -  int LastUDDist = -1;
    -  MachineInstr *LastUDMI = NULL;
    -  for (MachineRegisterInfo::reg_iterator RI = RegInfo->reg_begin(Reg),
    -         RE = RegInfo->reg_end(); RI != RE; ++RI) {
    -    MachineInstr *UDMI = &*RI;
    -    if (UDMI->getParent() != MBB)
    -      continue;
    -    DenseMap::iterator DI = DistanceMap.find(UDMI);
    -    if (DI == DistanceMap.end() || DI->second > CurDist)
    -      continue;
    -    if ((int)DI->second < LastUDDist)
    -      continue;
    -    LastUDDist = DI->second;
    -    LastUDMI = UDMI;
    -  }
    +    LastStore = next(MII);
     
    -  if (LastUDMI) {
    -    MachineOperand *LastUD = NULL;
    -    for (unsigned i = 0, e = LastUDMI->getNumOperands(); i != e; ++i) {
    -      MachineOperand &MO = LastUDMI->getOperand(i);
    -      if (!MO.isReg() || MO.getReg() != Reg)
    +    // If the stack slot value was previously available in some other
    +    // register, change it now.  Otherwise, make the register available,
    +    // in PhysReg.
    +    Spills.ModifyStackSlotOrReMat(StackSlot);
    +    Spills.ClobberPhysReg(PhysReg);
    +    Spills.addAvailable(StackSlot, PhysReg, isAvailable);
    +    ++NumStores;
    +  }
    +
    +  /// TransferDeadness - A identity copy definition is dead and it's being
    +  /// removed. Find the last def or use and mark it as dead / kill.
    +  void TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
    +                        unsigned Reg, BitVector &RegKills,
    +                        std::vector &KillOps) {
    +    int LastUDDist = -1;
    +    MachineInstr *LastUDMI = NULL;
    +    for (MachineRegisterInfo::reg_iterator RI = RegInfo->reg_begin(Reg),
    +           RE = RegInfo->reg_end(); RI != RE; ++RI) {
    +      MachineInstr *UDMI = &*RI;
    +      if (UDMI->getParent() != MBB)
    +        continue;
    +      DenseMap::iterator DI = DistanceMap.find(UDMI);
    +      if (DI == DistanceMap.end() || DI->second > CurDist)
             continue;
    -      if (!LastUD || (LastUD->isUse() && MO.isDef()))
    -        LastUD = &MO;
    -      if (LastUDMI->isRegTiedToDefOperand(i))
    -        return;
    +      if ((int)DI->second < LastUDDist)
    +        continue;
    +      LastUDDist = DI->second;
    +      LastUDMI = UDMI;
         }
    -    if (LastUD->isDef())
    -      LastUD->setIsDead();
    -    else {
    -      LastUD->setIsKill();
    -      RegKills.set(Reg);
    -      KillOps[Reg] = LastUD;
    +
    +    if (LastUDMI) {
    +      MachineOperand *LastUD = NULL;
    +      for (unsigned i = 0, e = LastUDMI->getNumOperands(); i != e; ++i) {
    +        MachineOperand &MO = LastUDMI->getOperand(i);
    +        if (!MO.isReg() || MO.getReg() != Reg)
    +          continue;
    +        if (!LastUD || (LastUD->isUse() && MO.isDef()))
    +          LastUD = &MO;
    +        if (LastUDMI->isRegTiedToDefOperand(i))
    +          return;
    +      }
    +      if (LastUD->isDef())
    +        LastUD->setIsDead();
    +      else {
    +        LastUD->setIsKill();
    +        RegKills.set(Reg);
    +        KillOps[Reg] = LastUD;
    +      }
         }
       }
    -}
     
    -/// rewriteMBB - Keep track of which spills are available even after the
    -/// register allocator is done with them.  If possible, avid reloading vregs.
    -void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
    -                              LiveIntervals *LIs,
    -                              AvailableSpills &Spills, BitVector &RegKills,
    -                              std::vector &KillOps) {
    -  DOUT << "\n**** Local spiller rewriting MBB '"
    -       << MBB.getBasicBlock()->getName() << "':\n";
    +  /// rewriteMBB - Keep track of which spills are available even after the
    +  /// register allocator is done with them.  If possible, avid reloading vregs.
    +  void RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
    +                  LiveIntervals *LIs,
    +                  AvailableSpills &Spills, BitVector &RegKills,
    +                  std::vector &KillOps) {
     
    -  MachineFunction &MF = *MBB.getParent();
    -  
    -  // MaybeDeadStores - When we need to write a value back into a stack slot,
    -  // keep track of the inserted store.  If the stack slot value is never read
    -  // (because the value was used from some available register, for example), and
    -  // subsequently stored to, the original store is dead.  This map keeps track
    -  // of inserted stores that are not used.  If we see a subsequent store to the
    -  // same stack slot, the original store is deleted.
    -  std::vector MaybeDeadStores;
    -  MaybeDeadStores.resize(MF.getFrameInfo()->getObjectIndexEnd(), NULL);
    -
    -  // ReMatDefs - These are rematerializable def MIs which are not deleted.
    -  SmallSet ReMatDefs;
    -
    -  // Clear kill info.
    -  SmallSet KilledMIRegs;
    -  RegKills.reset();
    -  KillOps.clear();
    -  KillOps.resize(TRI->getNumRegs(), NULL);
    -
    -  unsigned Dist = 0;
    -  DistanceMap.clear();
    -  for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
    -       MII != E; ) {
    -    MachineBasicBlock::iterator NextMII = next(MII);
    +    DOUT << "\n**** Local spiller rewriting MBB '"
    +         << MBB.getBasicBlock()->getName() << "':\n";
     
    -    VirtRegMap::MI2VirtMapTy::const_iterator I, End;
    -    bool Erased = false;
    -    bool BackTracked = false;
    -    if (OptimizeByUnfold(MBB, MII,
    -                         MaybeDeadStores, Spills, RegKills, KillOps, VRM))
    -      NextMII = next(MII);
    +    MachineFunction &MF = *MBB.getParent();
    +    
    +    // MaybeDeadStores - When we need to write a value back into a stack slot,
    +    // keep track of the inserted store.  If the stack slot value is never read
    +    // (because the value was used from some available register, for example), and
    +    // subsequently stored to, the original store is dead.  This map keeps track
    +    // of inserted stores that are not used.  If we see a subsequent store to the
    +    // same stack slot, the original store is deleted.
    +    std::vector MaybeDeadStores;
    +    MaybeDeadStores.resize(MF.getFrameInfo()->getObjectIndexEnd(), NULL);
    +
    +    // ReMatDefs - These are rematerializable def MIs which are not deleted.
    +    SmallSet ReMatDefs;
    +
    +    // Clear kill info.
    +    SmallSet KilledMIRegs;
    +    RegKills.reset();
    +    KillOps.clear();
    +    KillOps.resize(TRI->getNumRegs(), NULL);
     
    -    MachineInstr &MI = *MII;
    +    unsigned Dist = 0;
    +    DistanceMap.clear();
    +    for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
    +         MII != E; ) {
    +      MachineBasicBlock::iterator NextMII = next(MII);
    +
    +      VirtRegMap::MI2VirtMapTy::const_iterator I, End;
    +      bool Erased = false;
    +      bool BackTracked = false;
    +      if (OptimizeByUnfold(MBB, MII,
    +                           MaybeDeadStores, Spills, RegKills, KillOps, VRM))
    +        NextMII = next(MII);
    +
    +      MachineInstr &MI = *MII;
     
    -    if (VRM.hasEmergencySpills(&MI)) {
    -      // Spill physical register(s) in the rare case the allocator has run out
    -      // of registers to allocate.
    -      SmallSet UsedSS;
    -      std::vector &EmSpills = VRM.getEmergencySpills(&MI);
    -      for (unsigned i = 0, e = EmSpills.size(); i != e; ++i) {
    -        unsigned PhysReg = EmSpills[i];
    -        const TargetRegisterClass *RC =
    -          TRI->getPhysicalRegisterRegClass(PhysReg);
    -        assert(RC && "Unable to determine register class!");
    -        int SS = VRM.getEmergencySpillSlot(RC);
    -        if (UsedSS.count(SS))
    -          assert(0 && "Need to spill more than one physical registers!");
    -        UsedSS.insert(SS);
    -        TII->storeRegToStackSlot(MBB, MII, PhysReg, true, SS, RC);
    -        MachineInstr *StoreMI = prior(MII);
    -        VRM.addSpillSlotUse(SS, StoreMI);
    -        TII->loadRegFromStackSlot(MBB, next(MII), PhysReg, SS, RC);
    -        MachineInstr *LoadMI = next(MII);
    -        VRM.addSpillSlotUse(SS, LoadMI);
    -        ++NumPSpills;
    +      if (VRM.hasEmergencySpills(&MI)) {
    +        // Spill physical register(s) in the rare case the allocator has run out
    +        // of registers to allocate.
    +        SmallSet UsedSS;
    +        std::vector &EmSpills = VRM.getEmergencySpills(&MI);
    +        for (unsigned i = 0, e = EmSpills.size(); i != e; ++i) {
    +          unsigned PhysReg = EmSpills[i];
    +          const TargetRegisterClass *RC =
    +            TRI->getPhysicalRegisterRegClass(PhysReg);
    +          assert(RC && "Unable to determine register class!");
    +          int SS = VRM.getEmergencySpillSlot(RC);
    +          if (UsedSS.count(SS))
    +            assert(0 && "Need to spill more than one physical registers!");
    +          UsedSS.insert(SS);
    +          TII->storeRegToStackSlot(MBB, MII, PhysReg, true, SS, RC);
    +          MachineInstr *StoreMI = prior(MII);
    +          VRM.addSpillSlotUse(SS, StoreMI);
    +          TII->loadRegFromStackSlot(MBB, next(MII), PhysReg, SS, RC);
    +          MachineInstr *LoadMI = next(MII);
    +          VRM.addSpillSlotUse(SS, LoadMI);
    +          ++NumPSpills;
    +        }
    +        NextMII = next(MII);
           }
    -      NextMII = next(MII);
    -    }
     
    -    // Insert restores here if asked to.
    -    if (VRM.isRestorePt(&MI)) {
    -      std::vector &RestoreRegs = VRM.getRestorePtRestores(&MI);
    -      for (unsigned i = 0, e = RestoreRegs.size(); i != e; ++i) {
    -        unsigned VirtReg = RestoreRegs[e-i-1];  // Reverse order.
    -        if (!VRM.getPreSplitReg(VirtReg))
    -          continue; // Split interval spilled again.
    -        unsigned Phys = VRM.getPhys(VirtReg);
    -        RegInfo->setPhysRegUsed(Phys);
    -
    -        // Check if the value being restored if available. If so, it must be
    -        // from a predecessor BB that fallthrough into this BB. We do not
    -        // expect:
    -        // BB1:
    -        // r1 = load fi#1
    -        // ...
    -        //    = r1
    -        // ... # r1 not clobbered
    -        // ...
    -        //    = load fi#1
    -        bool DoReMat = VRM.isReMaterialized(VirtReg);
    -        int SSorRMId = DoReMat
    -          ? VRM.getReMatId(VirtReg) : VRM.getStackSlot(VirtReg);
    -        const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -        unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SSorRMId);
    -        if (InReg == Phys) {
    -          // If the value is already available in the expected register, save
    -          // a reload / remat.
    -          if (SSorRMId)
    -            DOUT << "Reusing RM#" << SSorRMId-VirtRegMap::MAX_STACK_SLOT-1;
    -          else
    -            DOUT << "Reusing SS#" << SSorRMId;
    -          DOUT << " from physreg "
    -               << TRI->getName(InReg) << " for vreg"
    -               << VirtReg <<" instead of reloading into physreg "
    -               << TRI->getName(Phys) << "\n";
    -          ++NumOmitted;
    -          continue;
    -        } else if (InReg && InReg != Phys) {
    -          if (SSorRMId)
    -            DOUT << "Reusing RM#" << SSorRMId-VirtRegMap::MAX_STACK_SLOT-1;
    -          else
    -            DOUT << "Reusing SS#" << SSorRMId;
    -          DOUT << " from physreg "
    -               << TRI->getName(InReg) << " for vreg"
    -               << VirtReg <<" by copying it into physreg "
    -               << TRI->getName(Phys) << "\n";
    -
    -          // If the reloaded / remat value is available in another register,
    -          // copy it to the desired register.
    -          TII->copyRegToReg(MBB, &MI, Phys, InReg, RC, RC);
    +      // Insert restores here if asked to.
    +      if (VRM.isRestorePt(&MI)) {
    +        std::vector &RestoreRegs = VRM.getRestorePtRestores(&MI);
    +        for (unsigned i = 0, e = RestoreRegs.size(); i != e; ++i) {
    +          unsigned VirtReg = RestoreRegs[e-i-1];  // Reverse order.
    +          if (!VRM.getPreSplitReg(VirtReg))
    +            continue; // Split interval spilled again.
    +          unsigned Phys = VRM.getPhys(VirtReg);
    +          RegInfo->setPhysRegUsed(Phys);
    +
    +          // Check if the value being restored if available. If so, it must be
    +          // from a predecessor BB that fallthrough into this BB. We do not
    +          // expect:
    +          // BB1:
    +          // r1 = load fi#1
    +          // ...
    +          //    = r1
    +          // ... # r1 not clobbered
    +          // ...
    +          //    = load fi#1
    +          bool DoReMat = VRM.isReMaterialized(VirtReg);
    +          int SSorRMId = DoReMat
    +            ? VRM.getReMatId(VirtReg) : VRM.getStackSlot(VirtReg);
    +          const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    +          unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SSorRMId);
    +          if (InReg == Phys) {
    +            // If the value is already available in the expected register, save
    +            // a reload / remat.
    +            if (SSorRMId)
    +              DOUT << "Reusing RM#" << SSorRMId-VirtRegMap::MAX_STACK_SLOT-1;
    +            else
    +              DOUT << "Reusing SS#" << SSorRMId;
    +            DOUT << " from physreg "
    +                 << TRI->getName(InReg) << " for vreg"
    +                 << VirtReg <<" instead of reloading into physreg "
    +                 << TRI->getName(Phys) << "\n";
    +            ++NumOmitted;
    +            continue;
    +          } else if (InReg && InReg != Phys) {
    +            if (SSorRMId)
    +              DOUT << "Reusing RM#" << SSorRMId-VirtRegMap::MAX_STACK_SLOT-1;
    +            else
    +              DOUT << "Reusing SS#" << SSorRMId;
    +            DOUT << " from physreg "
    +                 << TRI->getName(InReg) << " for vreg"
    +                 << VirtReg <<" by copying it into physreg "
    +                 << TRI->getName(Phys) << "\n";
    +
    +            // If the reloaded / remat value is available in another register,
    +            // copy it to the desired register.
    +            TII->copyRegToReg(MBB, &MI, Phys, InReg, RC, RC);
    +
    +            // This invalidates Phys.
    +            Spills.ClobberPhysReg(Phys);
    +            // Remember it's available.
    +            Spills.addAvailable(SSorRMId, Phys);
    +
    +            // Mark is killed.
    +            MachineInstr *CopyMI = prior(MII);
    +            MachineOperand *KillOpnd = CopyMI->findRegisterUseOperand(InReg);
    +            KillOpnd->setIsKill();
    +            UpdateKills(*CopyMI, RegKills, KillOps, TRI);
    +
    +            DOUT << '\t' << *CopyMI;
    +            ++NumCopified;
    +            continue;
    +          }
    +
    +          if (VRM.isReMaterialized(VirtReg)) {
    +            ReMaterialize(MBB, MII, Phys, VirtReg, TII, TRI, VRM);
    +          } else {
    +            const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    +            TII->loadRegFromStackSlot(MBB, &MI, Phys, SSorRMId, RC);
    +            MachineInstr *LoadMI = prior(MII);
    +            VRM.addSpillSlotUse(SSorRMId, LoadMI);
    +            ++NumLoads;
    +          }
     
               // This invalidates Phys.
               Spills.ClobberPhysReg(Phys);
               // Remember it's available.
               Spills.addAvailable(SSorRMId, Phys);
     
    -          // Mark is killed.
    -          MachineInstr *CopyMI = prior(MII);
    -          MachineOperand *KillOpnd = CopyMI->findRegisterUseOperand(InReg);
    -          KillOpnd->setIsKill();
    -          UpdateKills(*CopyMI, RegKills, KillOps, TRI);
    -
    -          DOUT << '\t' << *CopyMI;
    -          ++NumCopified;
    -          continue;
    +          UpdateKills(*prior(MII), RegKills, KillOps, TRI);
    +          DOUT << '\t' << *prior(MII);
             }
    +      }
     
    -        if (VRM.isReMaterialized(VirtReg)) {
    -          ReMaterialize(MBB, MII, Phys, VirtReg, TII, TRI, VRM);
    -        } else {
    -          const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -          TII->loadRegFromStackSlot(MBB, &MI, Phys, SSorRMId, RC);
    -          MachineInstr *LoadMI = prior(MII);
    -          VRM.addSpillSlotUse(SSorRMId, LoadMI);
    -          ++NumLoads;
    +      // Insert spills here if asked to.
    +      if (VRM.isSpillPt(&MI)) {
    +        std::vector > &SpillRegs =
    +          VRM.getSpillPtSpills(&MI);
    +        for (unsigned i = 0, e = SpillRegs.size(); i != e; ++i) {
    +          unsigned VirtReg = SpillRegs[i].first;
    +          bool isKill = SpillRegs[i].second;
    +          if (!VRM.getPreSplitReg(VirtReg))
    +            continue; // Split interval spilled again.
    +          const TargetRegisterClass *RC = RegInfo->getRegClass(VirtReg);
    +          unsigned Phys = VRM.getPhys(VirtReg);
    +          int StackSlot = VRM.getStackSlot(VirtReg);
    +          TII->storeRegToStackSlot(MBB, next(MII), Phys, isKill, StackSlot, RC);
    +          MachineInstr *StoreMI = next(MII);
    +          VRM.addSpillSlotUse(StackSlot, StoreMI);
    +          DOUT << "Store:\t" << *StoreMI;
    +          VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod);
             }
    -
    -        // This invalidates Phys.
    -        Spills.ClobberPhysReg(Phys);
    -        // Remember it's available.
    -        Spills.addAvailable(SSorRMId, Phys);
    -
    -        UpdateKills(*prior(MII), RegKills, KillOps, TRI);
    -        DOUT << '\t' << *prior(MII);
    +        NextMII = next(MII);
           }
    -    }
     
    -    // Insert spills here if asked to.
    -    if (VRM.isSpillPt(&MI)) {
    -      std::vector > &SpillRegs =
    -        VRM.getSpillPtSpills(&MI);
    -      for (unsigned i = 0, e = SpillRegs.size(); i != e; ++i) {
    -        unsigned VirtReg = SpillRegs[i].first;
    -        bool isKill = SpillRegs[i].second;
    -        if (!VRM.getPreSplitReg(VirtReg))
    -          continue; // Split interval spilled again.
    -        const TargetRegisterClass *RC = RegInfo->getRegClass(VirtReg);
    -        unsigned Phys = VRM.getPhys(VirtReg);
    -        int StackSlot = VRM.getStackSlot(VirtReg);
    -        TII->storeRegToStackSlot(MBB, next(MII), Phys, isKill, StackSlot, RC);
    -        MachineInstr *StoreMI = next(MII);
    -        VRM.addSpillSlotUse(StackSlot, StoreMI);
    -        DOUT << "Store:\t" << *StoreMI;
    -        VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod);
    -      }
    -      NextMII = next(MII);
    -    }
    +      /// ReusedOperands - Keep track of operand reuse in case we need to undo
    +      /// reuse.
    +      ReuseInfo ReusedOperands(MI, TRI);
    +      SmallVector VirtUseOps;
    +      for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    +        MachineOperand &MO = MI.getOperand(i);
    +        if (!MO.isReg() || MO.getReg() == 0)
    +          continue;   // Ignore non-register operands.
    +        
    +        unsigned VirtReg = MO.getReg();
    +        if (TargetRegisterInfo::isPhysicalRegister(VirtReg)) {
    +          // Ignore physregs for spilling, but remember that it is used by this
    +          // function.
    +          RegInfo->setPhysRegUsed(VirtReg);
    +          continue;
    +        }
     
    -    /// ReusedOperands - Keep track of operand reuse in case we need to undo
    -    /// reuse.
    -    ReuseInfo ReusedOperands(MI, TRI);
    -    SmallVector VirtUseOps;
    -    for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    -      MachineOperand &MO = MI.getOperand(i);
    -      if (!MO.isReg() || MO.getReg() == 0)
    -        continue;   // Ignore non-register operands.
    -      
    -      unsigned VirtReg = MO.getReg();
    -      if (TargetRegisterInfo::isPhysicalRegister(VirtReg)) {
    -        // Ignore physregs for spilling, but remember that it is used by this
    -        // function.
    -        RegInfo->setPhysRegUsed(VirtReg);
    -        continue;
    +        // We want to process implicit virtual register uses first.
    +        if (MO.isImplicit())
    +          // If the virtual register is implicitly defined, emit a implicit_def
    +          // before so scavenger knows it's "defined".
    +          VirtUseOps.insert(VirtUseOps.begin(), i);
    +        else
    +          VirtUseOps.push_back(i);
           }
     
    -      // We want to process implicit virtual register uses first.
    -      if (MO.isImplicit())
    -        // If the virtual register is implicitly defined, emit a implicit_def
    -        // before so scavenger knows it's "defined".
    -        VirtUseOps.insert(VirtUseOps.begin(), i);
    -      else
    -        VirtUseOps.push_back(i);
    -    }
    -
    -    // Process all of the spilled uses and all non spilled reg references.
    -    SmallVector PotentialDeadStoreSlots;
    -    KilledMIRegs.clear();
    -    for (unsigned j = 0, e = VirtUseOps.size(); j != e; ++j) {
    -      unsigned i = VirtUseOps[j];
    -      MachineOperand &MO = MI.getOperand(i);
    -      unsigned VirtReg = MO.getReg();
    -      assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
    -             "Not a virtual register?");
    +      // Process all of the spilled uses and all non spilled reg references.
    +      SmallVector PotentialDeadStoreSlots;
    +      KilledMIRegs.clear();
    +      for (unsigned j = 0, e = VirtUseOps.size(); j != e; ++j) {
    +        unsigned i = VirtUseOps[j];
    +        MachineOperand &MO = MI.getOperand(i);
    +        unsigned VirtReg = MO.getReg();
    +        assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
    +               "Not a virtual register?");
    +
    +        unsigned SubIdx = MO.getSubReg();
    +        if (VRM.isAssignedReg(VirtReg)) {
    +          // This virtual register was assigned a physreg!
    +          unsigned Phys = VRM.getPhys(VirtReg);
    +          RegInfo->setPhysRegUsed(Phys);
    +          if (MO.isDef())
    +            ReusedOperands.markClobbered(Phys);
    +          unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys;
    +          MI.getOperand(i).setReg(RReg);
    +          MI.getOperand(i).setSubReg(0);
    +          if (VRM.isImplicitlyDefined(VirtReg))
    +            BuildMI(MBB, &MI, MI.getDebugLoc(),
    +                    TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg);
    +          continue;
    +        }
    +        
    +        // This virtual register is now known to be a spilled value.
    +        if (!MO.isUse())
    +          continue;  // Handle defs in the loop below (handle use&def here though)
    +
    +        bool AvoidReload = false;
    +        if (LIs->hasInterval(VirtReg)) {
    +          LiveInterval &LI = LIs->getInterval(VirtReg);
    +          if (!LI.liveAt(LIs->getUseIndex(LI.beginNumber())))
    +            // Must be defined by an implicit def. It should not be spilled. Note,
    +            // this is for correctness reason. e.g.
    +            // 8   %reg1024 = IMPLICIT_DEF
    +            // 12  %reg1024 = INSERT_SUBREG %reg1024, %reg1025, 2
    +            // The live range [12, 14) are not part of the r1024 live interval since
    +            // it's defined by an implicit def. It will not conflicts with live
    +            // interval of r1025. Now suppose both registers are spilled, you can
    +            // easily see a situation where both registers are reloaded before
    +            // the INSERT_SUBREG and both target registers that would overlap.
    +            AvoidReload = true;
    +        }
     
    -      unsigned SubIdx = MO.getSubReg();
    -      if (VRM.isAssignedReg(VirtReg)) {
    -        // This virtual register was assigned a physreg!
    -        unsigned Phys = VRM.getPhys(VirtReg);
    -        RegInfo->setPhysRegUsed(Phys);
    -        if (MO.isDef())
    -          ReusedOperands.markClobbered(Phys);
    -        unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys;
    -        MI.getOperand(i).setReg(RReg);
    -        MI.getOperand(i).setSubReg(0);
    -        if (VRM.isImplicitlyDefined(VirtReg))
    -          BuildMI(MBB, &MI, MI.getDebugLoc(),
    -                  TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg);
    -        continue;
    -      }
    -      
    -      // This virtual register is now known to be a spilled value.
    -      if (!MO.isUse())
    -        continue;  // Handle defs in the loop below (handle use&def here though)
    -
    -      bool AvoidReload = false;
    -      if (LIs->hasInterval(VirtReg)) {
    -        LiveInterval &LI = LIs->getInterval(VirtReg);
    -        if (!LI.liveAt(LIs->getUseIndex(LI.beginNumber())))
    -          // Must be defined by an implicit def. It should not be spilled. Note,
    -          // this is for correctness reason. e.g.
    -          // 8   %reg1024 = IMPLICIT_DEF
    -          // 12  %reg1024 = INSERT_SUBREG %reg1024, %reg1025, 2
    -          // The live range [12, 14) are not part of the r1024 live interval since
    -          // it's defined by an implicit def. It will not conflicts with live
    -          // interval of r1025. Now suppose both registers are spilled, you can
    -          // easily see a situation where both registers are reloaded before
    -          // the INSERT_SUBREG and both target registers that would overlap.
    -          AvoidReload = true;
    -      }
    +        bool DoReMat = VRM.isReMaterialized(VirtReg);
    +        int SSorRMId = DoReMat
    +          ? VRM.getReMatId(VirtReg) : VRM.getStackSlot(VirtReg);
    +        int ReuseSlot = SSorRMId;
     
    -      bool DoReMat = VRM.isReMaterialized(VirtReg);
    -      int SSorRMId = DoReMat
    -        ? VRM.getReMatId(VirtReg) : VRM.getStackSlot(VirtReg);
    -      int ReuseSlot = SSorRMId;
    -
    -      // Check to see if this stack slot is available.
    -      unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SSorRMId);
    -
    -      // If this is a sub-register use, make sure the reuse register is in the
    -      // right register class. For example, for x86 not all of the 32-bit
    -      // registers have accessible sub-registers.
    -      // Similarly so for EXTRACT_SUBREG. Consider this:
    -      // EDI = op
    -      // MOV32_mr fi#1, EDI
    -      // ...
    -      //       = EXTRACT_SUBREG fi#1
    -      // fi#1 is available in EDI, but it cannot be reused because it's not in
    -      // the right register file.
    -      if (PhysReg && !AvoidReload &&
    -          (SubIdx || MI.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)) {
    -        const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -        if (!RC->contains(PhysReg))
    -          PhysReg = 0;
    -      }
    +        // Check to see if this stack slot is available.
    +        unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SSorRMId);
     
    -      if (PhysReg && !AvoidReload) {
    -        // This spilled operand might be part of a two-address operand.  If this
    -        // is the case, then changing it will necessarily require changing the 
    -        // def part of the instruction as well.  However, in some cases, we
    -        // aren't allowed to modify the reused register.  If none of these cases
    -        // apply, reuse it.
    -        bool CanReuse = true;
    -        bool isTied = MI.isRegTiedToDefOperand(i);
    -        if (isTied) {
    -          // Okay, we have a two address operand.  We can reuse this physreg as
    -          // long as we are allowed to clobber the value and there isn't an
    -          // earlier def that has already clobbered the physreg.
    -          CanReuse = !ReusedOperands.isClobbered(PhysReg) &&
    -            Spills.canClobberPhysReg(PhysReg);
    +        // If this is a sub-register use, make sure the reuse register is in the
    +        // right register class. For example, for x86 not all of the 32-bit
    +        // registers have accessible sub-registers.
    +        // Similarly so for EXTRACT_SUBREG. Consider this:
    +        // EDI = op
    +        // MOV32_mr fi#1, EDI
    +        // ...
    +        //       = EXTRACT_SUBREG fi#1
    +        // fi#1 is available in EDI, but it cannot be reused because it's not in
    +        // the right register file.
    +        if (PhysReg && !AvoidReload &&
    +            (SubIdx || MI.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)) {
    +          const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    +          if (!RC->contains(PhysReg))
    +            PhysReg = 0;
             }
    -        
    -        if (CanReuse) {
    -          // If this stack slot value is already available, reuse it!
    -          if (ReuseSlot > VirtRegMap::MAX_STACK_SLOT)
    -            DOUT << "Reusing RM#" << ReuseSlot-VirtRegMap::MAX_STACK_SLOT-1;
    -          else
    -            DOUT << "Reusing SS#" << ReuseSlot;
    -          DOUT << " from physreg "
    -               << TRI->getName(PhysReg) << " for vreg"
    -               << VirtReg <<" instead of reloading into physreg "
    -               << TRI->getName(VRM.getPhys(VirtReg)) << "\n";
    -          unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
    -          MI.getOperand(i).setReg(RReg);
    -          MI.getOperand(i).setSubReg(0);
     
    -          // The only technical detail we have is that we don't know that
    -          // PhysReg won't be clobbered by a reloaded stack slot that occurs
    -          // later in the instruction.  In particular, consider 'op V1, V2'.
    -          // If V1 is available in physreg R0, we would choose to reuse it
    -          // here, instead of reloading it into the register the allocator
    -          // indicated (say R1).  However, V2 might have to be reloaded
    -          // later, and it might indicate that it needs to live in R0.  When
    -          // this occurs, we need to have information available that
    -          // indicates it is safe to use R1 for the reload instead of R0.
    -          //
    -          // To further complicate matters, we might conflict with an alias,
    -          // or R0 and R1 might not be compatible with each other.  In this
    -          // case, we actually insert a reload for V1 in R1, ensuring that
    -          // we can get at R0 or its alias.
    -          ReusedOperands.addReuse(i, ReuseSlot, PhysReg,
    -                                  VRM.getPhys(VirtReg), VirtReg);
    -          if (isTied)
    -            // Only mark it clobbered if this is a use&def operand.
    -            ReusedOperands.markClobbered(PhysReg);
    -          ++NumReused;
    +        if (PhysReg && !AvoidReload) {
    +          // This spilled operand might be part of a two-address operand.  If this
    +          // is the case, then changing it will necessarily require changing the 
    +          // def part of the instruction as well.  However, in some cases, we
    +          // aren't allowed to modify the reused register.  If none of these cases
    +          // apply, reuse it.
    +          bool CanReuse = true;
    +          bool isTied = MI.isRegTiedToDefOperand(i);
    +          if (isTied) {
    +            // Okay, we have a two address operand.  We can reuse this physreg as
    +            // long as we are allowed to clobber the value and there isn't an
    +            // earlier def that has already clobbered the physreg.
    +            CanReuse = !ReusedOperands.isClobbered(PhysReg) &&
    +              Spills.canClobberPhysReg(PhysReg);
    +          }
    +          
    +          if (CanReuse) {
    +            // If this stack slot value is already available, reuse it!
    +            if (ReuseSlot > VirtRegMap::MAX_STACK_SLOT)
    +              DOUT << "Reusing RM#" << ReuseSlot-VirtRegMap::MAX_STACK_SLOT-1;
    +            else
    +              DOUT << "Reusing SS#" << ReuseSlot;
    +            DOUT << " from physreg "
    +                 << TRI->getName(PhysReg) << " for vreg"
    +                 << VirtReg <<" instead of reloading into physreg "
    +                 << TRI->getName(VRM.getPhys(VirtReg)) << "\n";
    +            unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
    +            MI.getOperand(i).setReg(RReg);
    +            MI.getOperand(i).setSubReg(0);
     
    -          if (MI.getOperand(i).isKill() &&
    -              ReuseSlot <= VirtRegMap::MAX_STACK_SLOT) {
    +            // The only technical detail we have is that we don't know that
    +            // PhysReg won't be clobbered by a reloaded stack slot that occurs
    +            // later in the instruction.  In particular, consider 'op V1, V2'.
    +            // If V1 is available in physreg R0, we would choose to reuse it
    +            // here, instead of reloading it into the register the allocator
    +            // indicated (say R1).  However, V2 might have to be reloaded
    +            // later, and it might indicate that it needs to live in R0.  When
    +            // this occurs, we need to have information available that
    +            // indicates it is safe to use R1 for the reload instead of R0.
    +            //
    +            // To further complicate matters, we might conflict with an alias,
    +            // or R0 and R1 might not be compatible with each other.  In this
    +            // case, we actually insert a reload for V1 in R1, ensuring that
    +            // we can get at R0 or its alias.
    +            ReusedOperands.addReuse(i, ReuseSlot, PhysReg,
    +                                    VRM.getPhys(VirtReg), VirtReg);
    +            if (isTied)
    +              // Only mark it clobbered if this is a use&def operand.
    +              ReusedOperands.markClobbered(PhysReg);
    +            ++NumReused;
    +
    +            if (MI.getOperand(i).isKill() &&
    +                ReuseSlot <= VirtRegMap::MAX_STACK_SLOT) {
    +
    +              // The store of this spilled value is potentially dead, but we
    +              // won't know for certain until we've confirmed that the re-use
    +              // above is valid, which means waiting until the other operands
    +              // are processed. For now we just track the spill slot, we'll
    +              // remove it after the other operands are processed if valid.
     
    -            // The store of this spilled value is potentially dead, but we
    -            // won't know for certain until we've confirmed that the re-use
    -            // above is valid, which means waiting until the other operands
    -            // are processed. For now we just track the spill slot, we'll
    -            // remove it after the other operands are processed if valid.
    +              PotentialDeadStoreSlots.push_back(ReuseSlot);
    +            }
     
    -            PotentialDeadStoreSlots.push_back(ReuseSlot);
    -          }
    +            // Mark is isKill if it's there no other uses of the same virtual
    +            // register and it's not a two-address operand. IsKill will be
    +            // unset if reg is reused.
    +            if (!isTied && KilledMIRegs.count(VirtReg) == 0) {
    +              MI.getOperand(i).setIsKill();
    +              KilledMIRegs.insert(VirtReg);
    +            }
     
    -          // Mark is isKill if it's there no other uses of the same virtual
    -          // register and it's not a two-address operand. IsKill will be
    -          // unset if reg is reused.
    -          if (!isTied && KilledMIRegs.count(VirtReg) == 0) {
    -            MI.getOperand(i).setIsKill();
    -            KilledMIRegs.insert(VirtReg);
    +            continue;
    +          }  // CanReuse
    +          
    +          // Otherwise we have a situation where we have a two-address instruction
    +          // whose mod/ref operand needs to be reloaded.  This reload is already
    +          // available in some register "PhysReg", but if we used PhysReg as the
    +          // operand to our 2-addr instruction, the instruction would modify
    +          // PhysReg.  This isn't cool if something later uses PhysReg and expects
    +          // to get its initial value.
    +          //
    +          // To avoid this problem, and to avoid doing a load right after a store,
    +          // we emit a copy from PhysReg into the designated register for this
    +          // operand.
    +          unsigned DesignatedReg = VRM.getPhys(VirtReg);
    +          assert(DesignatedReg && "Must map virtreg to physreg!");
    +
    +          // Note that, if we reused a register for a previous operand, the
    +          // register we want to reload into might not actually be
    +          // available.  If this occurs, use the register indicated by the
    +          // reuser.
    +          if (ReusedOperands.hasReuses())
    +            DesignatedReg = ReusedOperands.GetRegForReload(DesignatedReg, &MI, 
    +                                 Spills, MaybeDeadStores, RegKills, KillOps, VRM);
    +          
    +          // If the mapped designated register is actually the physreg we have
    +          // incoming, we don't need to inserted a dead copy.
    +          if (DesignatedReg == PhysReg) {
    +            // If this stack slot value is already available, reuse it!
    +            if (ReuseSlot > VirtRegMap::MAX_STACK_SLOT)
    +              DOUT << "Reusing RM#" << ReuseSlot-VirtRegMap::MAX_STACK_SLOT-1;
    +            else
    +              DOUT << "Reusing SS#" << ReuseSlot;
    +            DOUT << " from physreg " << TRI->getName(PhysReg)
    +                 << " for vreg" << VirtReg
    +                 << " instead of reloading into same physreg.\n";
    +            unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
    +            MI.getOperand(i).setReg(RReg);
    +            MI.getOperand(i).setSubReg(0);
    +            ReusedOperands.markClobbered(RReg);
    +            ++NumReused;
    +            continue;
               }
    +          
    +          const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    +          RegInfo->setPhysRegUsed(DesignatedReg);
    +          ReusedOperands.markClobbered(DesignatedReg);
    +          TII->copyRegToReg(MBB, &MI, DesignatedReg, PhysReg, RC, RC);
    +
    +          MachineInstr *CopyMI = prior(MII);
    +          UpdateKills(*CopyMI, RegKills, KillOps, TRI);
     
    +          // This invalidates DesignatedReg.
    +          Spills.ClobberPhysReg(DesignatedReg);
    +          
    +          Spills.addAvailable(ReuseSlot, DesignatedReg);
    +          unsigned RReg =
    +            SubIdx ? TRI->getSubReg(DesignatedReg, SubIdx) : DesignatedReg;
    +          MI.getOperand(i).setReg(RReg);
    +          MI.getOperand(i).setSubReg(0);
    +          DOUT << '\t' << *prior(MII);
    +          ++NumReused;
               continue;
    -        }  // CanReuse
    +        } // if (PhysReg)
             
    -        // Otherwise we have a situation where we have a two-address instruction
    -        // whose mod/ref operand needs to be reloaded.  This reload is already
    -        // available in some register "PhysReg", but if we used PhysReg as the
    -        // operand to our 2-addr instruction, the instruction would modify
    -        // PhysReg.  This isn't cool if something later uses PhysReg and expects
    -        // to get its initial value.
    -        //
    -        // To avoid this problem, and to avoid doing a load right after a store,
    -        // we emit a copy from PhysReg into the designated register for this
    -        // operand.
    -        unsigned DesignatedReg = VRM.getPhys(VirtReg);
    -        assert(DesignatedReg && "Must map virtreg to physreg!");
    +        // Otherwise, reload it and remember that we have it.
    +        PhysReg = VRM.getPhys(VirtReg);
    +        assert(PhysReg && "Must map virtreg to physreg!");
     
             // Note that, if we reused a register for a previous operand, the
             // register we want to reload into might not actually be
             // available.  If this occurs, use the register indicated by the
             // reuser.
             if (ReusedOperands.hasReuses())
    -          DesignatedReg = ReusedOperands.GetRegForReload(DesignatedReg, &MI, 
    -                               Spills, MaybeDeadStores, RegKills, KillOps, VRM);
    -        
    -        // If the mapped designated register is actually the physreg we have
    -        // incoming, we don't need to inserted a dead copy.
    -        if (DesignatedReg == PhysReg) {
    -          // If this stack slot value is already available, reuse it!
    -          if (ReuseSlot > VirtRegMap::MAX_STACK_SLOT)
    -            DOUT << "Reusing RM#" << ReuseSlot-VirtRegMap::MAX_STACK_SLOT-1;
    -          else
    -            DOUT << "Reusing SS#" << ReuseSlot;
    -          DOUT << " from physreg " << TRI->getName(PhysReg)
    -               << " for vreg" << VirtReg
    -               << " instead of reloading into same physreg.\n";
    -          unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
    -          MI.getOperand(i).setReg(RReg);
    -          MI.getOperand(i).setSubReg(0);
    -          ReusedOperands.markClobbered(RReg);
    -          ++NumReused;
    -          continue;
    -        }
    +          PhysReg = ReusedOperands.GetRegForReload(PhysReg, &MI, 
    +                                 Spills, MaybeDeadStores, RegKills, KillOps, VRM);
             
    -        const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -        RegInfo->setPhysRegUsed(DesignatedReg);
    -        ReusedOperands.markClobbered(DesignatedReg);
    -        TII->copyRegToReg(MBB, &MI, DesignatedReg, PhysReg, RC, RC);
    +        RegInfo->setPhysRegUsed(PhysReg);
    +        ReusedOperands.markClobbered(PhysReg);
    +        if (AvoidReload)
    +          ++NumAvoided;
    +        else {
    +          if (DoReMat) {
    +            ReMaterialize(MBB, MII, PhysReg, VirtReg, TII, TRI, VRM);
    +          } else {
    +            const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    +            TII->loadRegFromStackSlot(MBB, &MI, PhysReg, SSorRMId, RC);
    +            MachineInstr *LoadMI = prior(MII);
    +            VRM.addSpillSlotUse(SSorRMId, LoadMI);
    +            ++NumLoads;
    +          }
    +          // This invalidates PhysReg.
    +          Spills.ClobberPhysReg(PhysReg);
     
    -        MachineInstr *CopyMI = prior(MII);
    -        UpdateKills(*CopyMI, RegKills, KillOps, TRI);
    +          // Any stores to this stack slot are not dead anymore.
    +          if (!DoReMat)
    +            MaybeDeadStores[SSorRMId] = NULL;
    +          Spills.addAvailable(SSorRMId, PhysReg);
    +          // Assumes this is the last use. IsKill will be unset if reg is reused
    +          // unless it's a two-address operand.
    +          if (!MI.isRegTiedToDefOperand(i) &&
    +              KilledMIRegs.count(VirtReg) == 0) {
    +            MI.getOperand(i).setIsKill();
    +            KilledMIRegs.insert(VirtReg);
    +          }
     
    -        // This invalidates DesignatedReg.
    -        Spills.ClobberPhysReg(DesignatedReg);
    -        
    -        Spills.addAvailable(ReuseSlot, DesignatedReg);
    -        unsigned RReg =
    -          SubIdx ? TRI->getSubReg(DesignatedReg, SubIdx) : DesignatedReg;
    +          UpdateKills(*prior(MII), RegKills, KillOps, TRI);
    +          DOUT << '\t' << *prior(MII);
    +        }
    +        unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
             MI.getOperand(i).setReg(RReg);
             MI.getOperand(i).setSubReg(0);
    -        DOUT << '\t' << *prior(MII);
    -        ++NumReused;
    -        continue;
    -      } // if (PhysReg)
    -      
    -      // Otherwise, reload it and remember that we have it.
    -      PhysReg = VRM.getPhys(VirtReg);
    -      assert(PhysReg && "Must map virtreg to physreg!");
    -
    -      // Note that, if we reused a register for a previous operand, the
    -      // register we want to reload into might not actually be
    -      // available.  If this occurs, use the register indicated by the
    -      // reuser.
    -      if (ReusedOperands.hasReuses())
    -        PhysReg = ReusedOperands.GetRegForReload(PhysReg, &MI, 
    -                               Spills, MaybeDeadStores, RegKills, KillOps, VRM);
    -      
    -      RegInfo->setPhysRegUsed(PhysReg);
    -      ReusedOperands.markClobbered(PhysReg);
    -      if (AvoidReload)
    -        ++NumAvoided;
    -      else {
    -        if (DoReMat) {
    -          ReMaterialize(MBB, MII, PhysReg, VirtReg, TII, TRI, VRM);
    -        } else {
    -          const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
    -          TII->loadRegFromStackSlot(MBB, &MI, PhysReg, SSorRMId, RC);
    -          MachineInstr *LoadMI = prior(MII);
    -          VRM.addSpillSlotUse(SSorRMId, LoadMI);
    -          ++NumLoads;
    -        }
    -        // This invalidates PhysReg.
    -        Spills.ClobberPhysReg(PhysReg);
    +      }
     
    -        // Any stores to this stack slot are not dead anymore.
    -        if (!DoReMat)
    -          MaybeDeadStores[SSorRMId] = NULL;
    -        Spills.addAvailable(SSorRMId, PhysReg);
    -        // Assumes this is the last use. IsKill will be unset if reg is reused
    -        // unless it's a two-address operand.
    -        if (!MI.isRegTiedToDefOperand(i) &&
    -            KilledMIRegs.count(VirtReg) == 0) {
    -          MI.getOperand(i).setIsKill();
    -          KilledMIRegs.insert(VirtReg);
    +      // Ok - now we can remove stores that have been confirmed dead.
    +      for (unsigned j = 0, e = PotentialDeadStoreSlots.size(); j != e; ++j) {
    +        // This was the last use and the spilled value is still available
    +        // for reuse. That means the spill was unnecessary!
    +        int PDSSlot = PotentialDeadStoreSlots[j];
    +        MachineInstr* DeadStore = MaybeDeadStores[PDSSlot];
    +        if (DeadStore) {
    +          DOUT << "Removed dead store:\t" << *DeadStore;
    +          InvalidateKills(*DeadStore, RegKills, KillOps);
    +          VRM.RemoveMachineInstrFromMaps(DeadStore);
    +          MBB.erase(DeadStore);
    +          MaybeDeadStores[PDSSlot] = NULL;
    +          ++NumDSE;
             }
    -
    -        UpdateKills(*prior(MII), RegKills, KillOps, TRI);
    -        DOUT << '\t' << *prior(MII);
    -      }
    -      unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
    -      MI.getOperand(i).setReg(RReg);
    -      MI.getOperand(i).setSubReg(0);
    -    }
    -
    -    // Ok - now we can remove stores that have been confirmed dead.
    -    for (unsigned j = 0, e = PotentialDeadStoreSlots.size(); j != e; ++j) {
    -      // This was the last use and the spilled value is still available
    -      // for reuse. That means the spill was unnecessary!
    -      int PDSSlot = PotentialDeadStoreSlots[j];
    -      MachineInstr* DeadStore = MaybeDeadStores[PDSSlot];
    -      if (DeadStore) {
    -        DOUT << "Removed dead store:\t" << *DeadStore;
    -        InvalidateKills(*DeadStore, RegKills, KillOps);
    -        VRM.RemoveMachineInstrFromMaps(DeadStore);
    -        MBB.erase(DeadStore);
    -        MaybeDeadStores[PDSSlot] = NULL;
    -        ++NumDSE;
           }
    -    }
    -
     
    -    DOUT << '\t' << MI;
     
    +      DOUT << '\t' << MI;
     
    -    // If we have folded references to memory operands, make sure we clear all
    -    // physical registers that may contain the value of the spilled virtual
    -    // register
    -    SmallSet FoldedSS;
    -    for (tie(I, End) = VRM.getFoldedVirts(&MI); I != End; ) {
    -      unsigned VirtReg = I->second.first;
    -      VirtRegMap::ModRef MR = I->second.second;
    -      DOUT << "Folded vreg: " << VirtReg << "  MR: " << MR;
     
    -      // MI2VirtMap be can updated which invalidate the iterator.
    -      // Increment the iterator first.
    -      ++I;
    -      int SS = VRM.getStackSlot(VirtReg);
    -      if (SS == VirtRegMap::NO_STACK_SLOT)
    -        continue;
    -      FoldedSS.insert(SS);
    -      DOUT << " - StackSlot: " << SS << "\n";
    -      
    -      // If this folded instruction is just a use, check to see if it's a
    -      // straight load from the virt reg slot.
    -      if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) {
    -        int FrameIdx;
    -        unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx);
    -        if (DestReg && FrameIdx == SS) {
    -          // If this spill slot is available, turn it into a copy (or nothing)
    -          // instead of leaving it as a load!
    -          if (unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SS)) {
    -            DOUT << "Promoted Load To Copy: " << MI;
    -            if (DestReg != InReg) {
    -              const TargetRegisterClass *RC = RegInfo->getRegClass(VirtReg);
    -              TII->copyRegToReg(MBB, &MI, DestReg, InReg, RC, RC);
    -              MachineOperand *DefMO = MI.findRegisterDefOperand(DestReg);
    -              unsigned SubIdx = DefMO->getSubReg();
    -              // Revisit the copy so we make sure to notice the effects of the
    -              // operation on the destreg (either needing to RA it if it's 
    -              // virtual or needing to clobber any values if it's physical).
    -              NextMII = &MI;
    -              --NextMII;  // backtrack to the copy.
    -              // Propagate the sub-register index over.
    -              if (SubIdx) {
    -                DefMO = NextMII->findRegisterDefOperand(DestReg);
    -                DefMO->setSubReg(SubIdx);
    +      // If we have folded references to memory operands, make sure we clear all
    +      // physical registers that may contain the value of the spilled virtual
    +      // register
    +      SmallSet FoldedSS;
    +      for (tie(I, End) = VRM.getFoldedVirts(&MI); I != End; ) {
    +        unsigned VirtReg = I->second.first;
    +        VirtRegMap::ModRef MR = I->second.second;
    +        DOUT << "Folded vreg: " << VirtReg << "  MR: " << MR;
    +
    +        // MI2VirtMap be can updated which invalidate the iterator.
    +        // Increment the iterator first.
    +        ++I;
    +        int SS = VRM.getStackSlot(VirtReg);
    +        if (SS == VirtRegMap::NO_STACK_SLOT)
    +          continue;
    +        FoldedSS.insert(SS);
    +        DOUT << " - StackSlot: " << SS << "\n";
    +        
    +        // If this folded instruction is just a use, check to see if it's a
    +        // straight load from the virt reg slot.
    +        if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) {
    +          int FrameIdx;
    +          unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx);
    +          if (DestReg && FrameIdx == SS) {
    +            // If this spill slot is available, turn it into a copy (or nothing)
    +            // instead of leaving it as a load!
    +            if (unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SS)) {
    +              DOUT << "Promoted Load To Copy: " << MI;
    +              if (DestReg != InReg) {
    +                const TargetRegisterClass *RC = RegInfo->getRegClass(VirtReg);
    +                TII->copyRegToReg(MBB, &MI, DestReg, InReg, RC, RC);
    +                MachineOperand *DefMO = MI.findRegisterDefOperand(DestReg);
    +                unsigned SubIdx = DefMO->getSubReg();
    +                // Revisit the copy so we make sure to notice the effects of the
    +                // operation on the destreg (either needing to RA it if it's 
    +                // virtual or needing to clobber any values if it's physical).
    +                NextMII = &MI;
    +                --NextMII;  // backtrack to the copy.
    +                // Propagate the sub-register index over.
    +                if (SubIdx) {
    +                  DefMO = NextMII->findRegisterDefOperand(DestReg);
    +                  DefMO->setSubReg(SubIdx);
    +                }
    +
    +                // Mark is killed.
    +                MachineOperand *KillOpnd = NextMII->findRegisterUseOperand(InReg);
    +                KillOpnd->setIsKill();
    +
    +                BackTracked = true;
    +              } else {
    +                DOUT << "Removing now-noop copy: " << MI;
    +                // Unset last kill since it's being reused.
    +                InvalidateKill(InReg, RegKills, KillOps);
    +                Spills.disallowClobberPhysReg(InReg);
                   }
     
    -              // Mark is killed.
    -              MachineOperand *KillOpnd = NextMII->findRegisterUseOperand(InReg);
    -              KillOpnd->setIsKill();
    -
    -              BackTracked = true;
    -            } else {
    -              DOUT << "Removing now-noop copy: " << MI;
    -              // Unset last kill since it's being reused.
    -              InvalidateKill(InReg, RegKills, KillOps);
    -              Spills.disallowClobberPhysReg(InReg);
    +              InvalidateKills(MI, RegKills, KillOps);
    +              VRM.RemoveMachineInstrFromMaps(&MI);
    +              MBB.erase(&MI);
    +              Erased = true;
    +              goto ProcessNextInst;
                 }
    -
    -            InvalidateKills(MI, RegKills, KillOps);
    -            VRM.RemoveMachineInstrFromMaps(&MI);
    -            MBB.erase(&MI);
    -            Erased = true;
    -            goto ProcessNextInst;
    -          }
    -        } else {
    -          unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS);
    -          SmallVector NewMIs;
    -          if (PhysReg &&
    -              TII->unfoldMemoryOperand(MF, &MI, PhysReg, false, false, NewMIs)) {
    -            MBB.insert(MII, NewMIs[0]);
    -            InvalidateKills(MI, RegKills, KillOps);
    -            VRM.RemoveMachineInstrFromMaps(&MI);
    -            MBB.erase(&MI);
    -            Erased = true;
    -            --NextMII;  // backtrack to the unfolded instruction.
    -            BackTracked = true;
    -            goto ProcessNextInst;
    -          }
    -        }
    -      }
    -
    -      // If this reference is not a use, any previous store is now dead.
    -      // Otherwise, the store to this stack slot is not dead anymore.
    -      MachineInstr* DeadStore = MaybeDeadStores[SS];
    -      if (DeadStore) {
    -        bool isDead = !(MR & VirtRegMap::isRef);
    -        MachineInstr *NewStore = NULL;
    -        if (MR & VirtRegMap::isModRef) {
    -          unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS);
    -          SmallVector NewMIs;
    -          // We can reuse this physreg as long as we are allowed to clobber
    -          // the value and there isn't an earlier def that has already clobbered
    -          // the physreg.
    -          if (PhysReg &&
    -              !ReusedOperands.isClobbered(PhysReg) &&
    -              Spills.canClobberPhysReg(PhysReg) &&
    -              !TII->isStoreToStackSlot(&MI, SS)) { // Not profitable!
    -            MachineOperand *KillOpnd =
    -              DeadStore->findRegisterUseOperand(PhysReg, true);
    -            // Note, if the store is storing a sub-register, it's possible the
    -            // super-register is needed below.
    -            if (KillOpnd && !KillOpnd->getSubReg() &&
    -                TII->unfoldMemoryOperand(MF, &MI, PhysReg, false, true,NewMIs)){
    +          } else {
    +            unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS);
    +            SmallVector NewMIs;
    +            if (PhysReg &&
    +                TII->unfoldMemoryOperand(MF, &MI, PhysReg, false, false, NewMIs)) {
                   MBB.insert(MII, NewMIs[0]);
    -              NewStore = NewMIs[1];
    -              MBB.insert(MII, NewStore);
    -              VRM.addSpillSlotUse(SS, NewStore);
                   InvalidateKills(MI, RegKills, KillOps);
                   VRM.RemoveMachineInstrFromMaps(&MI);
                   MBB.erase(&MI);
                   Erased = true;
    -              --NextMII;
                   --NextMII;  // backtrack to the unfolded instruction.
                   BackTracked = true;
    -              isDead = true;
    -              ++NumSUnfold;
    +              goto ProcessNextInst;
                 }
               }
             }
     
    -        if (isDead) {  // Previous store is dead.
    -          // If we get here, the store is dead, nuke it now.
    -          DOUT << "Removed dead store:\t" << *DeadStore;
    -          InvalidateKills(*DeadStore, RegKills, KillOps);
    -          VRM.RemoveMachineInstrFromMaps(DeadStore);
    -          MBB.erase(DeadStore);
    -          if (!NewStore)
    -            ++NumDSE;
    -        }
    -
    -        MaybeDeadStores[SS] = NULL;
    -        if (NewStore) {
    -          // Treat this store as a spill merged into a copy. That makes the
    -          // stack slot value available.
    -          VRM.virtFolded(VirtReg, NewStore, VirtRegMap::isMod);
    -          goto ProcessNextInst;
    -        }
    -      }
    -
    -      // If the spill slot value is available, and this is a new definition of
    -      // the value, the value is not available anymore.
    -      if (MR & VirtRegMap::isMod) {
    -        // Notice that the value in this stack slot has been modified.
    -        Spills.ModifyStackSlotOrReMat(SS);
    -        
    -        // If this is *just* a mod of the value, check to see if this is just a
    -        // store to the spill slot (i.e. the spill got merged into the copy). If
    -        // so, realize that the vreg is available now, and add the store to the
    -        // MaybeDeadStore info.
    -        int StackSlot;
    -        if (!(MR & VirtRegMap::isRef)) {
    -          if (unsigned SrcReg = TII->isStoreToStackSlot(&MI, StackSlot)) {
    -            assert(TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
    -                   "Src hasn't been allocated yet?");
    -
    -            if (CommuteToFoldReload(MBB, MII, VirtReg, SrcReg, StackSlot,
    -                                    Spills, RegKills, KillOps, TRI, VRM)) {
    -              NextMII = next(MII);
    -              BackTracked = true;
    -              goto ProcessNextInst;
    +        // If this reference is not a use, any previous store is now dead.
    +        // Otherwise, the store to this stack slot is not dead anymore.
    +        MachineInstr* DeadStore = MaybeDeadStores[SS];
    +        if (DeadStore) {
    +          bool isDead = !(MR & VirtRegMap::isRef);
    +          MachineInstr *NewStore = NULL;
    +          if (MR & VirtRegMap::isModRef) {
    +            unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS);
    +            SmallVector NewMIs;
    +            // We can reuse this physreg as long as we are allowed to clobber
    +            // the value and there isn't an earlier def that has already clobbered
    +            // the physreg.
    +            if (PhysReg &&
    +                !ReusedOperands.isClobbered(PhysReg) &&
    +                Spills.canClobberPhysReg(PhysReg) &&
    +                !TII->isStoreToStackSlot(&MI, SS)) { // Not profitable!
    +              MachineOperand *KillOpnd =
    +                DeadStore->findRegisterUseOperand(PhysReg, true);
    +              // Note, if the store is storing a sub-register, it's possible the
    +              // super-register is needed below.
    +              if (KillOpnd && !KillOpnd->getSubReg() &&
    +                  TII->unfoldMemoryOperand(MF, &MI, PhysReg, false, true,NewMIs)){
    +                MBB.insert(MII, NewMIs[0]);
    +                NewStore = NewMIs[1];
    +                MBB.insert(MII, NewStore);
    +                VRM.addSpillSlotUse(SS, NewStore);
    +                InvalidateKills(MI, RegKills, KillOps);
    +                VRM.RemoveMachineInstrFromMaps(&MI);
    +                MBB.erase(&MI);
    +                Erased = true;
    +                --NextMII;
    +                --NextMII;  // backtrack to the unfolded instruction.
    +                BackTracked = true;
    +                isDead = true;
    +                ++NumSUnfold;
    +              }
                 }
    -
    -            // Okay, this is certainly a store of SrcReg to [StackSlot].  Mark
    -            // this as a potentially dead store in case there is a subsequent
    -            // store into the stack slot without a read from it.
    -            MaybeDeadStores[StackSlot] = &MI;
    -
    -            // If the stack slot value was previously available in some other
    -            // register, change it now.  Otherwise, make the register
    -            // available in PhysReg.
    -            Spills.addAvailable(StackSlot, SrcReg, MI.killsRegister(SrcReg));
               }
    -        }
    -      }
    -    }
     
    -    // Process all of the spilled defs.
    -    for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    -      MachineOperand &MO = MI.getOperand(i);
    -      if (!(MO.isReg() && MO.getReg() && MO.isDef()))
    -        continue;
    +          if (isDead) {  // Previous store is dead.
    +            // If we get here, the store is dead, nuke it now.
    +            DOUT << "Removed dead store:\t" << *DeadStore;
    +            InvalidateKills(*DeadStore, RegKills, KillOps);
    +            VRM.RemoveMachineInstrFromMaps(DeadStore);
    +            MBB.erase(DeadStore);
    +            if (!NewStore)
    +              ++NumDSE;
    +          }
     
    -      unsigned VirtReg = MO.getReg();
    -      if (!TargetRegisterInfo::isVirtualRegister(VirtReg)) {
    -        // Check to see if this is a noop copy.  If so, eliminate the
    -        // instruction before considering the dest reg to be changed.
    -        unsigned Src, Dst, SrcSR, DstSR;
    -        if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) {
    -          ++NumDCE;
    -          DOUT << "Removing now-noop copy: " << MI;
    -          SmallVector KillRegs;
    -          InvalidateKills(MI, RegKills, KillOps, &KillRegs);
    -          if (MO.isDead() && !KillRegs.empty()) {
    -            // Source register or an implicit super/sub-register use is killed.
    -            assert(KillRegs[0] == Dst ||
    -                   TRI->isSubRegister(KillRegs[0], Dst) ||
    -                   TRI->isSuperRegister(KillRegs[0], Dst));
    -            // Last def is now dead.
    -            TransferDeadness(&MBB, Dist, Src, RegKills, KillOps);
    +          MaybeDeadStores[SS] = NULL;
    +          if (NewStore) {
    +            // Treat this store as a spill merged into a copy. That makes the
    +            // stack slot value available.
    +            VRM.virtFolded(VirtReg, NewStore, VirtRegMap::isMod);
    +            goto ProcessNextInst;
               }
    -          VRM.RemoveMachineInstrFromMaps(&MI);
    -          MBB.erase(&MI);
    -          Erased = true;
    -          Spills.disallowClobberPhysReg(VirtReg);
    -          goto ProcessNextInst;
             }
    +
    +        // If the spill slot value is available, and this is a new definition of
    +        // the value, the value is not available anymore.
    +        if (MR & VirtRegMap::isMod) {
    +          // Notice that the value in this stack slot has been modified.
    +          Spills.ModifyStackSlotOrReMat(SS);
               
    -        // If it's not a no-op copy, it clobbers the value in the destreg.
    -        Spills.ClobberPhysReg(VirtReg);
    -        ReusedOperands.markClobbered(VirtReg);
    - 
    -        // Check to see if this instruction is a load from a stack slot into
    -        // a register.  If so, this provides the stack slot value in the reg.
    -        int FrameIdx;
    -        if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
    -          assert(DestReg == VirtReg && "Unknown load situation!");
    -
    -          // If it is a folded reference, then it's not safe to clobber.
    -          bool Folded = FoldedSS.count(FrameIdx);
    -          // Otherwise, if it wasn't available, remember that it is now!
    -          Spills.addAvailable(FrameIdx, DestReg, !Folded);
    -          goto ProcessNextInst;
    -        }
    -            
    -        continue;
    -      }
    +          // If this is *just* a mod of the value, check to see if this is just a
    +          // store to the spill slot (i.e. the spill got merged into the copy). If
    +          // so, realize that the vreg is available now, and add the store to the
    +          // MaybeDeadStore info.
    +          int StackSlot;
    +          if (!(MR & VirtRegMap::isRef)) {
    +            if (unsigned SrcReg = TII->isStoreToStackSlot(&MI, StackSlot)) {
    +              assert(TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
    +                     "Src hasn't been allocated yet?");
    +
    +              if (CommuteToFoldReload(MBB, MII, VirtReg, SrcReg, StackSlot,
    +                                      Spills, RegKills, KillOps, TRI, VRM)) {
    +                NextMII = next(MII);
    +                BackTracked = true;
    +                goto ProcessNextInst;
    +              }
     
    -      unsigned SubIdx = MO.getSubReg();
    -      bool DoReMat = VRM.isReMaterialized(VirtReg);
    -      if (DoReMat)
    -        ReMatDefs.insert(&MI);
    -
    -      // The only vregs left are stack slot definitions.
    -      int StackSlot = VRM.getStackSlot(VirtReg);
    -      const TargetRegisterClass *RC = RegInfo->getRegClass(VirtReg);
    -
    -      // If this def is part of a two-address operand, make sure to execute
    -      // the store from the correct physical register.
    -      unsigned PhysReg;
    -      unsigned TiedOp;
    -      if (MI.isRegTiedToUseOperand(i, &TiedOp)) {
    -        PhysReg = MI.getOperand(TiedOp).getReg();
    -        if (SubIdx) {
    -          unsigned SuperReg = findSuperReg(RC, PhysReg, SubIdx, TRI);
    -          assert(SuperReg && TRI->getSubReg(SuperReg, SubIdx) == PhysReg &&
    -                 "Can't find corresponding super-register!");
    -          PhysReg = SuperReg;
    -        }
    -      } else {
    -        PhysReg = VRM.getPhys(VirtReg);
    -        if (ReusedOperands.isClobbered(PhysReg)) {
    -          // Another def has taken the assigned physreg. It must have been a
    -          // use&def which got it due to reuse. Undo the reuse!
    -          PhysReg = ReusedOperands.GetRegForReload(PhysReg, &MI, 
    -                               Spills, MaybeDeadStores, RegKills, KillOps, VRM);
    +              // Okay, this is certainly a store of SrcReg to [StackSlot].  Mark
    +              // this as a potentially dead store in case there is a subsequent
    +              // store into the stack slot without a read from it.
    +              MaybeDeadStores[StackSlot] = &MI;
    +
    +              // If the stack slot value was previously available in some other
    +              // register, change it now.  Otherwise, make the register
    +              // available in PhysReg.
    +              Spills.addAvailable(StackSlot, SrcReg, MI.killsRegister(SrcReg));
    +            }
    +          }
             }
           }
     
    -      assert(PhysReg && "VR not assigned a physical register?");
    -      RegInfo->setPhysRegUsed(PhysReg);
    -      unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
    -      ReusedOperands.markClobbered(RReg);
    -      MI.getOperand(i).setReg(RReg);
    -      MI.getOperand(i).setSubReg(0);
    -
    -      if (!MO.isDead()) {
    -        MachineInstr *&LastStore = MaybeDeadStores[StackSlot];
    -        SpillRegToStackSlot(MBB, MII, -1, PhysReg, StackSlot, RC, true,
    -                          LastStore, Spills, ReMatDefs, RegKills, KillOps, VRM);
    -        NextMII = next(MII);
    +      // Process all of the spilled defs.
    +      for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    +        MachineOperand &MO = MI.getOperand(i);
    +        if (!(MO.isReg() && MO.getReg() && MO.isDef()))
    +          continue;
     
    -        // Check to see if this is a noop copy.  If so, eliminate the
    -        // instruction before considering the dest reg to be changed.
    -        {
    +        unsigned VirtReg = MO.getReg();
    +        if (!TargetRegisterInfo::isVirtualRegister(VirtReg)) {
    +          // Check to see if this is a noop copy.  If so, eliminate the
    +          // instruction before considering the dest reg to be changed.
               unsigned Src, Dst, SrcSR, DstSR;
               if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) {
                 ++NumDCE;
                 DOUT << "Removing now-noop copy: " << MI;
    -            InvalidateKills(MI, RegKills, KillOps);
    +            SmallVector KillRegs;
    +            InvalidateKills(MI, RegKills, KillOps, &KillRegs);
    +            if (MO.isDead() && !KillRegs.empty()) {
    +              // Source register or an implicit super/sub-register use is killed.
    +              assert(KillRegs[0] == Dst ||
    +                     TRI->isSubRegister(KillRegs[0], Dst) ||
    +                     TRI->isSuperRegister(KillRegs[0], Dst));
    +              // Last def is now dead.
    +              TransferDeadness(&MBB, Dist, Src, RegKills, KillOps);
    +            }
                 VRM.RemoveMachineInstrFromMaps(&MI);
                 MBB.erase(&MI);
                 Erased = true;
    -            UpdateKills(*LastStore, RegKills, KillOps, TRI);
    +            Spills.disallowClobberPhysReg(VirtReg);
    +            goto ProcessNextInst;
    +          }
    +            
    +          // If it's not a no-op copy, it clobbers the value in the destreg.
    +          Spills.ClobberPhysReg(VirtReg);
    +          ReusedOperands.markClobbered(VirtReg);
    +   
    +          // Check to see if this instruction is a load from a stack slot into
    +          // a register.  If so, this provides the stack slot value in the reg.
    +          int FrameIdx;
    +          if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
    +            assert(DestReg == VirtReg && "Unknown load situation!");
    +
    +            // If it is a folded reference, then it's not safe to clobber.
    +            bool Folded = FoldedSS.count(FrameIdx);
    +            // Otherwise, if it wasn't available, remember that it is now!
    +            Spills.addAvailable(FrameIdx, DestReg, !Folded);
                 goto ProcessNextInst;
               }
    +              
    +          continue;
             }
    -      }    
    -    }
    -  ProcessNextInst:
    -    DistanceMap.insert(std::make_pair(&MI, Dist++));
    -    if (!Erased && !BackTracked) {
    -      for (MachineBasicBlock::iterator II = &MI; II != NextMII; ++II)
    -        UpdateKills(*II, RegKills, KillOps, TRI);
    +
    +        unsigned SubIdx = MO.getSubReg();
    +        bool DoReMat = VRM.isReMaterialized(VirtReg);
    +        if (DoReMat)
    +          ReMatDefs.insert(&MI);
    +
    +        // The only vregs left are stack slot definitions.
    +        int StackSlot = VRM.getStackSlot(VirtReg);
    +        const TargetRegisterClass *RC = RegInfo->getRegClass(VirtReg);
    +
    +        // If this def is part of a two-address operand, make sure to execute
    +        // the store from the correct physical register.
    +        unsigned PhysReg;
    +        unsigned TiedOp;
    +        if (MI.isRegTiedToUseOperand(i, &TiedOp)) {
    +          PhysReg = MI.getOperand(TiedOp).getReg();
    +          if (SubIdx) {
    +            unsigned SuperReg = findSuperReg(RC, PhysReg, SubIdx, TRI);
    +            assert(SuperReg && TRI->getSubReg(SuperReg, SubIdx) == PhysReg &&
    +                   "Can't find corresponding super-register!");
    +            PhysReg = SuperReg;
    +          }
    +        } else {
    +          PhysReg = VRM.getPhys(VirtReg);
    +          if (ReusedOperands.isClobbered(PhysReg)) {
    +            // Another def has taken the assigned physreg. It must have been a
    +            // use&def which got it due to reuse. Undo the reuse!
    +            PhysReg = ReusedOperands.GetRegForReload(PhysReg, &MI, 
    +                                 Spills, MaybeDeadStores, RegKills, KillOps, VRM);
    +          }
    +        }
    +
    +        assert(PhysReg && "VR not assigned a physical register?");
    +        RegInfo->setPhysRegUsed(PhysReg);
    +        unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
    +        ReusedOperands.markClobbered(RReg);
    +        MI.getOperand(i).setReg(RReg);
    +        MI.getOperand(i).setSubReg(0);
    +
    +        if (!MO.isDead()) {
    +          MachineInstr *&LastStore = MaybeDeadStores[StackSlot];
    +          SpillRegToStackSlot(MBB, MII, -1, PhysReg, StackSlot, RC, true,
    +                            LastStore, Spills, ReMatDefs, RegKills, KillOps, VRM);
    +          NextMII = next(MII);
    +
    +          // Check to see if this is a noop copy.  If so, eliminate the
    +          // instruction before considering the dest reg to be changed.
    +          {
    +            unsigned Src, Dst, SrcSR, DstSR;
    +            if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) {
    +              ++NumDCE;
    +              DOUT << "Removing now-noop copy: " << MI;
    +              InvalidateKills(MI, RegKills, KillOps);
    +              VRM.RemoveMachineInstrFromMaps(&MI);
    +              MBB.erase(&MI);
    +              Erased = true;
    +              UpdateKills(*LastStore, RegKills, KillOps, TRI);
    +              goto ProcessNextInst;
    +            }
    +          }
    +        }    
    +      }
    +    ProcessNextInst:
    +      DistanceMap.insert(std::make_pair(&MI, Dist++));
    +      if (!Erased && !BackTracked) {
    +        for (MachineBasicBlock::iterator II = &MI; II != NextMII; ++II)
    +          UpdateKills(*II, RegKills, KillOps, TRI);
    +      }
    +      MII = NextMII;
         }
    -    MII = NextMII;
    +
       }
     
    -}
    +};
     
    -llvm::Spiller* llvm::createSpiller() {
    -  switch (SpillerOpt) {
    +llvm::VirtRegRewriter* llvm::createVirtRegRewriter() {
    +  switch (RewriterOpt) {
       default: assert(0 && "Unreachable!");
       case local:
    -    return new LocalSpiller();
    +    return new LocalRewriter();
       case simple:
    -    return new SimpleSpiller();
    +    return new SimpleRewriter();
       }
     }
    
    Copied: llvm/trunk/lib/CodeGen/VirtRegRewriter.h (from r71041, llvm/trunk/lib/CodeGen/Spiller.h)
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegRewriter.h?p2=llvm/trunk/lib/CodeGen/VirtRegRewriter.h&p1=llvm/trunk/lib/CodeGen/Spiller.h&r1=71041&r2=71057&rev=71057&view=diff
    
    ==============================================================================
    --- llvm/trunk/lib/CodeGen/Spiller.h (original)
    +++ llvm/trunk/lib/CodeGen/VirtRegRewriter.h Tue May  5 21:36:21 2009
    @@ -1,4 +1,4 @@
    -//===-- llvm/CodeGen/Spiller.h - Spiller -*- C++ -*------------------------===//
    +//===-- llvm/CodeGen/VirtRegRewriter.h - VirtRegRewriter -*- C++ -*--------===//
     //
     //                     The LLVM Compiler Infrastructure
     //
    @@ -7,8 +7,8 @@
     //
     //===----------------------------------------------------------------------===//
     
    -#ifndef LLVM_CODEGEN_SPILLER_H
    -#define LLVM_CODEGEN_SPILLER_H
    +#ifndef LLVM_CODEGEN_VIRTREGREWRITER_H
    +#define LLVM_CODEGEN_VIRTREGREWRITER_H
     
     #include "llvm/Target/TargetRegisterInfo.h"
     #include "llvm/ADT/BitVector.h"
    @@ -32,309 +32,25 @@
     #include "VirtRegMap.h"
     #include 
     
    +// TODO:
    +//       - Finish renaming Spiller -> Rewriter
    +//         - SimpleSpiller
    +//         - LocalSpiller
    +
     namespace llvm {
       
    -  /// Spiller interface: Implementations of this interface assign spilled
    -  /// virtual registers to stack slots, rewriting the code.
    -  struct Spiller {
    -    virtual ~Spiller();
    +  /// VirtRegRewriter interface: Implementations of this interface assign
    +  /// spilled virtual registers to stack slots, rewriting the code.
    +  struct VirtRegRewriter {
    +    virtual ~VirtRegRewriter();
         virtual bool runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM,
                                           LiveIntervals* LIs) = 0;
       };
     
    -  /// createSpiller - Create an return a spiller object, as specified on the
    -  /// command line.
    -  Spiller* createSpiller();
    -  
    -  // ************************************************************************ //
    -  
    -  // Simple Spiller Implementation
    -  struct VISIBILITY_HIDDEN SimpleSpiller : public Spiller {
    -    bool runOnMachineFunction(MachineFunction& mf, VirtRegMap &VRM,
    -                              LiveIntervals* LIs);
    -  };
    -  
    -  // ************************************************************************ //
    -  
    -  /// AvailableSpills - As the local spiller is scanning and rewriting an MBB
    -  /// from top down, keep track of which spills slots or remat are available in
    -  /// each register.
    -  ///
    -  /// Note that not all physregs are created equal here.  In particular, some
    -  /// physregs are reloads that we are allowed to clobber or ignore at any time.
    -  /// Other physregs are values that the register allocated program is using
    -  /// that we cannot CHANGE, but we can read if we like.  We keep track of this
    -  /// on a per-stack-slot / remat id basis as the low bit in the value of the
    -  /// SpillSlotsAvailable entries.  The predicate 'canClobberPhysReg()' checks
    -  /// this bit and addAvailable sets it if.
    -  class VISIBILITY_HIDDEN AvailableSpills {
    -    const TargetRegisterInfo *TRI;
    -    const TargetInstrInfo *TII;
    -
    -    // SpillSlotsOrReMatsAvailable - This map keeps track of all of the spilled
    -    // or remat'ed virtual register values that are still available, due to
    -    // being loaded or stored to, but not invalidated yet.
    -    std::map SpillSlotsOrReMatsAvailable;
    -
    -    // PhysRegsAvailable - This is the inverse of SpillSlotsOrReMatsAvailable,
    -    // indicating which stack slot values are currently held by a physreg.  This
    -    // is used to invalidate entries in SpillSlotsOrReMatsAvailable when a
    -    // physreg is modified.
    -    std::multimap PhysRegsAvailable;
    -
    -    void disallowClobberPhysRegOnly(unsigned PhysReg);
    -
    -    void ClobberPhysRegOnly(unsigned PhysReg);
    -  public:
    -    AvailableSpills(const TargetRegisterInfo *tri, const TargetInstrInfo *tii)
    -      : TRI(tri), TII(tii) {
    -    }
    -
    -    /// clear - Reset the state.
    -    void clear() {
    -      SpillSlotsOrReMatsAvailable.clear();
    -      PhysRegsAvailable.clear();
    -    }
    -
    -    const TargetRegisterInfo *getRegInfo() const { return TRI; }
    -
    -    /// getSpillSlotOrReMatPhysReg - If the specified stack slot or remat is
    -    /// available in a physical register, return that PhysReg, otherwise
    -    /// return 0.
    -    unsigned getSpillSlotOrReMatPhysReg(int Slot) const {
    -      std::map::const_iterator I =
    -        SpillSlotsOrReMatsAvailable.find(Slot);
    -      if (I != SpillSlotsOrReMatsAvailable.end()) {
    -        return I->second >> 1;  // Remove the CanClobber bit.
    -      }
    -      return 0;
    -    }
    -
    -    /// addAvailable - Mark that the specified stack slot / remat is available
    -    /// in the specified physreg.  If CanClobber is true, the physreg can be
    -    /// modified at any time without changing the semantics of the program.
    -    void addAvailable(int SlotOrReMat, unsigned Reg, bool CanClobber = true) {
    -      // If this stack slot is thought to be available in some other physreg, 
    -      // remove its record.
    -      ModifyStackSlotOrReMat(SlotOrReMat);
    -
    -      PhysRegsAvailable.insert(std::make_pair(Reg, SlotOrReMat));
    -      SpillSlotsOrReMatsAvailable[SlotOrReMat]= (Reg << 1) |
    -                                                (unsigned)CanClobber;
    -
    -      if (SlotOrReMat > VirtRegMap::MAX_STACK_SLOT)
    -        DOUT << "Remembering RM#" << SlotOrReMat-VirtRegMap::MAX_STACK_SLOT-1;
    -      else
    -        DOUT << "Remembering SS#" << SlotOrReMat;
    -      DOUT << " in physreg " << TRI->getName(Reg) << "\n";
    -    }
    -
    -    /// canClobberPhysRegForSS - Return true if the spiller is allowed to change
    -    /// the value of the specified stackslot register if it desires. The
    -    /// specified stack slot must be available in a physreg for this query to
    -    /// make sense.
    -    bool canClobberPhysRegForSS(int SlotOrReMat) const {
    -      assert(SpillSlotsOrReMatsAvailable.count(SlotOrReMat) &&
    -             "Value not available!");
    -      return SpillSlotsOrReMatsAvailable.find(SlotOrReMat)->second & 1;
    -    }
    -
    -    /// canClobberPhysReg - Return true if the spiller is allowed to clobber the
    -    /// physical register where values for some stack slot(s) might be
    -    /// available.
    -    bool canClobberPhysReg(unsigned PhysReg) const {
    -      std::multimap::const_iterator I =
    -        PhysRegsAvailable.lower_bound(PhysReg);
    -      while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
    -        int SlotOrReMat = I->second;
    -        I++;
    -        if (!canClobberPhysRegForSS(SlotOrReMat))
    -          return false;
    -      }
    -      return true;
    -    }
    -
    -    /// disallowClobberPhysReg - Unset the CanClobber bit of the specified
    -    /// stackslot register. The register is still available but is no longer
    -    /// allowed to be modifed.
    -    void disallowClobberPhysReg(unsigned PhysReg);
    -
    -    /// ClobberPhysReg - This is called when the specified physreg changes
    -    /// value.  We use this to invalidate any info about stuff that lives in
    -    /// it and any of its aliases.
    -    void ClobberPhysReg(unsigned PhysReg);
    -
    -    /// ModifyStackSlotOrReMat - This method is called when the value in a stack
    -    /// slot changes.  This removes information about which register the
    -    /// previous value for this slot lives in (as the previous value is dead
    -    /// now).
    -    void ModifyStackSlotOrReMat(int SlotOrReMat);
    -
    -    /// AddAvailableRegsToLiveIn - Availability information is being kept coming
    -    /// into the specified MBB. Add available physical registers as potential
    -    /// live-in's. If they are reused in the MBB, they will be added to the
    -    /// live-in set to make register scavenger and post-allocation scheduler.
    -    void AddAvailableRegsToLiveIn(MachineBasicBlock &MBB, BitVector &RegKills,
    -                                  std::vector &KillOps);
    -  };
    -  
    -  // ************************************************************************ //
    -  
    -  // ReusedOp - For each reused operand, we keep track of a bit of information,
    -  // in case we need to rollback upon processing a new operand.  See comments
    -  // below.
    -  struct ReusedOp {
    -    // The MachineInstr operand that reused an available value.
    -    unsigned Operand;
    -
    -    // StackSlotOrReMat - The spill slot or remat id of the value being reused.
    -    unsigned StackSlotOrReMat;
    -
    -    // PhysRegReused - The physical register the value was available in.
    -    unsigned PhysRegReused;
    -
    -    // AssignedPhysReg - The physreg that was assigned for use by the reload.
    -    unsigned AssignedPhysReg;
    -    
    -    // VirtReg - The virtual register itself.
    -    unsigned VirtReg;
    -
    -    ReusedOp(unsigned o, unsigned ss, unsigned prr, unsigned apr,
    -             unsigned vreg)
    -      : Operand(o), StackSlotOrReMat(ss), PhysRegReused(prr),
    -        AssignedPhysReg(apr), VirtReg(vreg) {}
    -  };
    -  
    -  /// ReuseInfo - This maintains a collection of ReuseOp's for each operand that
    -  /// is reused instead of reloaded.
    -  class VISIBILITY_HIDDEN ReuseInfo {
    -    MachineInstr &MI;
    -    std::vector Reuses;
    -    BitVector PhysRegsClobbered;
    -  public:
    -    ReuseInfo(MachineInstr &mi, const TargetRegisterInfo *tri) : MI(mi) {
    -      PhysRegsClobbered.resize(tri->getNumRegs());
    -    }
    -    
    -    bool hasReuses() const {
    -      return !Reuses.empty();
    -    }
    -    
    -    /// addReuse - If we choose to reuse a virtual register that is already
    -    /// available instead of reloading it, remember that we did so.
    -    void addReuse(unsigned OpNo, unsigned StackSlotOrReMat,
    -                  unsigned PhysRegReused, unsigned AssignedPhysReg,
    -                  unsigned VirtReg) {
    -      // If the reload is to the assigned register anyway, no undo will be
    -      // required.
    -      if (PhysRegReused == AssignedPhysReg) return;
    -      
    -      // Otherwise, remember this.
    -      Reuses.push_back(ReusedOp(OpNo, StackSlotOrReMat, PhysRegReused, 
    -                                AssignedPhysReg, VirtReg));
    -    }
    -
    -    void markClobbered(unsigned PhysReg) {
    -      PhysRegsClobbered.set(PhysReg);
    -    }
    +  /// createVirtRegRewriter - Create an return a rewriter object, as specified
    +  /// on the command line.
    +  VirtRegRewriter* createVirtRegRewriter();
     
    -    bool isClobbered(unsigned PhysReg) const {
    -      return PhysRegsClobbered.test(PhysReg);
    -    }
    -    
    -    /// GetRegForReload - We are about to emit a reload into PhysReg.  If there
    -    /// is some other operand that is using the specified register, either pick
    -    /// a new register to use, or evict the previous reload and use this reg. 
    -    unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
    -                             AvailableSpills &Spills,
    -                             std::vector &MaybeDeadStores,
    -                             SmallSet &Rejected,
    -                             BitVector &RegKills,
    -                             std::vector &KillOps,
    -                             VirtRegMap &VRM);
    -
    -    /// GetRegForReload - Helper for the above GetRegForReload(). Add a
    -    /// 'Rejected' set to remember which registers have been considered and
    -    /// rejected for the reload. This avoids infinite looping in case like
    -    /// this:
    -    /// t1 := op t2, t3
    -    /// t2 <- assigned r0 for use by the reload but ended up reuse r1
    -    /// t3 <- assigned r1 for use by the reload but ended up reuse r0
    -    /// t1 <- desires r1
    -    ///       sees r1 is taken by t2, tries t2's reload register r0
    -    ///       sees r0 is taken by t3, tries t3's reload register r1
    -    ///       sees r1 is taken by t2, tries t2's reload register r0 ...
    -    unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
    -                             AvailableSpills &Spills,
    -                             std::vector &MaybeDeadStores,
    -                             BitVector &RegKills,
    -                             std::vector &KillOps,
    -                             VirtRegMap &VRM) {
    -      SmallSet Rejected;
    -      return GetRegForReload(PhysReg, MI, Spills, MaybeDeadStores, Rejected,
    -                             RegKills, KillOps, VRM);
    -    }
    -  };
    -  
    -  // ************************************************************************ //
    -  
    -  /// LocalSpiller - This spiller does a simple pass over the machine basic
    -  /// block to attempt to keep spills in registers as much as possible for
    -  /// blocks that have low register pressure (the vreg may be spilled due to
    -  /// register pressure in other blocks).
    -  class VISIBILITY_HIDDEN LocalSpiller : public Spiller {
    -    MachineRegisterInfo *RegInfo;
    -    const TargetRegisterInfo *TRI;
    -    const TargetInstrInfo *TII;
    -    BitVector AllocatableRegs;
    -    DenseMap DistanceMap;
    -  public:
    -    bool runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM,
    -                              LiveIntervals* LI);
    -  private:
    -    void TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
    -                          unsigned Reg, BitVector &RegKills,
    -                          std::vector &KillOps);
    -
    -    bool OptimizeByUnfold(MachineBasicBlock &MBB,
    -                          MachineBasicBlock::iterator &MII,
    -                          std::vector &MaybeDeadStores,
    -                          AvailableSpills &Spills, BitVector &RegKills,
    -                          std::vector &KillOps,
    -                          VirtRegMap &VRM);
    -
    -    bool OptimizeByUnfold2(unsigned VirtReg, int SS,
    -                           MachineBasicBlock &MBB,
    -                           MachineBasicBlock::iterator &MII, 
    -                           std::vector &MaybeDeadStores,
    -                           AvailableSpills &Spills, BitVector &RegKills,
    -                           std::vector &KillOps,
    -                           VirtRegMap &VRM);
    -
    -    bool CommuteToFoldReload(MachineBasicBlock &MBB,
    -                             MachineBasicBlock::iterator &MII,
    -                             unsigned VirtReg, unsigned SrcReg, int SS,
    -                             AvailableSpills &Spills,
    -                             BitVector &RegKills,
    -                             std::vector &KillOps,
    -                             const TargetRegisterInfo *TRI,
    -                             VirtRegMap &VRM);
    -
    -    void SpillRegToStackSlot(MachineBasicBlock &MBB,
    -                             MachineBasicBlock::iterator &MII,
    -                             int Idx, unsigned PhysReg, int StackSlot,
    -                             const TargetRegisterClass *RC,
    -                             bool isAvailable, MachineInstr *&LastStore,
    -                             AvailableSpills &Spills,
    -                             SmallSet &ReMatDefs,
    -                             BitVector &RegKills,
    -                             std::vector &KillOps,
    -                             VirtRegMap &VRM);
    -
    -    void RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
    -                    LiveIntervals *LIs, AvailableSpills &Spills,
    -                    BitVector &RegKills, std::vector &KillOps);
    -  };
     }
     
     #endif
    
    Modified: llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll?rev=71057&r1=71056&r2=71057&view=diff
    
    ==============================================================================
    --- llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll (original)
    +++ llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll Tue May  5 21:36:21 2009
    @@ -1,4 +1,4 @@
    -; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin -stats |& grep spiller | not grep {stores unfolded}
    +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin -stats |& grep virtregrewriter | not grep {stores unfolded}
     ; rdar://6682365
     
     ; Do not clobber a register if another spill slot is available in it and it's marked "do not clobber".
    
    
    
    
    From foldr at codedgers.com  Tue May  5 23:54:23 2009
    From: foldr at codedgers.com (Mikhail Glushenkov)
    Date: Wed, 06 May 2009 04:54:23 -0000
    Subject: [llvm-commits] [llvm] r71068 -
    	/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp
    Message-ID: <200905060454.n464sN3S027282@zion.cs.uiuc.edu>
    
    Author: foldr
    Date: Tue May  5 23:54:23 2009
    New Revision: 71068
    
    URL: http://llvm.org/viewvc/llvm-project?rev=71068&view=rev
    Log:
    A better error message.
    
    Modified:
        llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp
    
    Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=71068&r1=71067&r2=71068&view=diff
    
    ==============================================================================
    --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original)
    +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Tue May  5 23:54:23 2009
    @@ -86,8 +86,8 @@
     // less than or equal to min_arguments, otherwise throw an exception.
     void checkNumberOfArguments (const DagInit* d, unsigned min_arguments) {
       if (!d || d->getNumArgs() < min_arguments)
    -    throw "Property " + d->getOperator()->getAsString()
    -      + " has too few arguments!";
    +    throw d->getOperator()->getAsString()
    +      + ": too few arguments!";
     }
     
     // isDagEmpty - is this DAG marked with an empty marker?
    
    
    
    
    From nicholas at mxc.ca  Wed May  6 01:15:32 2009
    From: nicholas at mxc.ca (Nick Lewycky)
    Date: Tue, 05 May 2009 23:15:32 -0700
    Subject: [llvm-commits] patch: use CallbackVH for metadata
    Message-ID: <4A012B04.9060101@mxc.ca>
    
    This patch switches MDNode to using CallbackVH and adds a special 
    typeless "null" keyword that means "(Value*)0" within a metadata node. 
    Also change MDNode construction to accept Value* even though we don't 
    really permit non-Constant values yet.
    
    Please review!
    
    Nick
    -------------- next part --------------
    A non-text attachment was scrubbed...
    Name: metadata-callbackvh.patch
    Type: text/x-diff
    Size: 17029 bytes
    Desc: not available
    Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090505/b124877d/attachment.bin 
    
    From baldrick at free.fr  Wed May  6 01:49:54 2009
    From: baldrick at free.fr (Duncan Sands)
    Date: Wed, 06 May 2009 06:49:54 -0000
    Subject: [llvm-commits] [llvm] r71071 - in /llvm/trunk: docs/LangRef.html
     include/llvm/Instruction.h lib/Transforms/Scalar/ADCE.cpp
     lib/Transforms/Scalar/GVN.cpp
     lib/Transforms/Scalar/InstructionCombining.cpp
     lib/Transforms/Scalar/LoopDeletion.cpp
     lib/Transforms/Scalar/LoopIndexSplit.cpp
     lib/Transforms/Scalar/LoopUnswitch.cpp
     lib/Transforms/Scalar/TailDuplication.cpp
     lib/Transforms/Scalar/TailRecursionElimination.cpp
     lib/Transforms/Utils/Local.cpp lib/VMCore/Instruction.cpp
     test/Transforms/ADCE/dce_pure_call.ll
    Message-ID: <200905060649.n466nu6s031618@zion.cs.uiuc.edu>
    
    Author: baldrick
    Date: Wed May  6 01:49:50 2009
    New Revision: 71071
    
    URL: http://llvm.org/viewvc/llvm-project?rev=71071&view=rev
    Log:
    Allow readonly functions to unwind exceptions.  Teach
    the optimizers about this.  For example, a readonly
    function with no uses cannot be removed unless it is
    also marked nounwind.
    
    Modified:
        llvm/trunk/docs/LangRef.html
        llvm/trunk/include/llvm/Instruction.h
        llvm/trunk/lib/Transforms/Scalar/ADCE.cpp
        llvm/trunk/lib/Transforms/Scalar/GVN.cpp
        llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
        llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp
        llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp
        llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
        llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp
        llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp
        llvm/trunk/lib/Transforms/Utils/Local.cpp
        llvm/trunk/lib/VMCore/Instruction.cpp
        llvm/trunk/test/Transforms/ADCE/dce_pure_call.ll
    
    Modified: llvm/trunk/docs/LangRef.html
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=71071&r1=71070&r2=71071&view=diff
    
    ==============================================================================
    --- llvm/trunk/docs/LangRef.html (original)
    +++ llvm/trunk/docs/LangRef.html Wed May  6 01:49:50 2009
    @@ -1061,23 +1061,24 @@
     behavior is undefined.
     
     
    readnone
    -
    This attribute indicates that the function computes its result (or the -exception it throws) based strictly on its arguments, without dereferencing any +
    This attribute indicates that the function computes its result (or decides to +unwind an exception) based strictly on its arguments, without dereferencing any pointer arguments or otherwise accessing any mutable state (e.g. memory, control registers, etc) visible to caller functions. It does not write through any pointer arguments (including byval arguments) and -never changes any state visible to callers. readnone functions may not throw -an exception that escapes into the caller.
    +never changes any state visible to callers. This means that it cannot unwind +exceptions by calling the C++ exception throwing methods, but could +use the unwind instruction.
    readonly
    This attribute indicates that the function does not write through any pointer arguments (including byval arguments) or otherwise modify any state (e.g. memory, control registers, etc) visible to caller functions. It may dereference pointer arguments and read state that may -be set in the caller. A readonly function always returns the same value when -called with the same set of arguments and global -state. readonly functions may not throw an exception that escapes into the -caller.
    +be set in the caller. A readonly function always returns the same value (or +unwinds an exception identically) when called with the same set of arguments +and global state. It cannot unwind an exception by calling the C++ +exception throwing methods, but may use the unwind instruction.
    ssp
    This attribute indicates that the function should emit a stack smashing Modified: llvm/trunk/include/llvm/Instruction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instruction.h?rev=71071&r1=71070&r2=71071&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instruction.h (original) +++ llvm/trunk/include/llvm/Instruction.h Wed May 6 01:49:50 2009 @@ -40,14 +40,6 @@ // Out of line virtual method, so the vtable, etc has a home. ~Instruction(); - /// mayWriteToMemory - Return true if this instruction may modify memory. - /// - bool mayWriteToMemory() const; - - /// mayReadFromMemory - Return true if this instruction may read memory. - /// - bool mayReadFromMemory() const; - /// clone() - Create a copy of 'this' instruction that is identical in all /// ways except the following: /// * The instruction has no parent @@ -181,6 +173,24 @@ } static bool isTrapping(unsigned op); + /// mayWriteToMemory - Return true if this instruction may modify memory. + /// + bool mayWriteToMemory() const; + + /// mayReadFromMemory - Return true if this instruction may read memory. + /// + bool mayReadFromMemory() const; + + /// mayThrow - Return true if this instruction may throw an exception. + /// + bool mayThrow() const; + + /// mayHaveSideEffects - Return true if the instruction may have side effects. + /// + bool mayHaveSideEffects() const { + return mayWriteToMemory() || mayThrow(); + } + /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *) { return true; } static inline bool classof(const Value *V) { Modified: llvm/trunk/lib/Transforms/Scalar/ADCE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ADCE.cpp?rev=71071&r1=71070&r2=71071&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ADCE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ADCE.cpp Wed May 6 01:49:50 2009 @@ -57,7 +57,7 @@ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) if (isa(I.getInstructionIterator()) || isa(I.getInstructionIterator()) || - I->mayWriteToMemory()) { + I->mayHaveSideEffects()) { alive.insert(I.getInstructionIterator()); worklist.push_back(I.getInstructionIterator()); } Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=71071&r1=71070&r2=71071&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed May 6 01:49:50 2009 @@ -1479,13 +1479,13 @@ for (BasicBlock::iterator BI = CurrentBlock->begin(), BE = CurrentBlock->end(); BI != BE; ) { Instruction *CurInst = BI++; - + if (isa(CurInst) || isa(CurInst) || isa(CurInst) || (CurInst->getType() == Type::VoidTy) || - CurInst->mayReadFromMemory() || CurInst->mayWriteToMemory() || + CurInst->mayReadFromMemory() || CurInst->mayHaveSideEffects() || isa(CurInst)) continue; - + uint32_t valno = VN.lookup(CurInst); // Look for the predecessors for PRE opportunities. We're Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=71071&r1=71070&r2=71071&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Wed May 6 01:49:50 2009 @@ -12579,7 +12579,7 @@ assert(I->hasOneUse() && "Invariants didn't hold!"); // Cannot move control-flow-involving, volatile loads, vaarg, etc. - if (isa(I) || I->mayWriteToMemory() || isa(I)) + if (isa(I) || I->mayHaveSideEffects() || isa(I)) return false; // Do not sink alloca instructions out of the entry block. Modified: llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp?rev=71071&r1=71070&r2=71071&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Wed May 6 01:49:50 2009 @@ -136,11 +136,8 @@ LI != LE; ++LI) { for (BasicBlock::iterator BI = (*LI)->begin(), BE = (*LI)->end(); BI != BE; ++BI) { - if (BI->mayWriteToMemory()) + if (BI->mayHaveSideEffects()) return false; - else if (LoadInst* L = dyn_cast(BI)) - if (L->isVolatile()) - return false; } } Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=71071&r1=71070&r2=71071&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Wed May 6 01:49:50 2009 @@ -1148,7 +1148,7 @@ || isa(I)) continue; - if (I->mayWriteToMemory()) + if (I->mayHaveSideEffects()) return false; // I is used only inside this block then it is OK. Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=71071&r1=71070&r2=71071&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Wed May 6 01:49:50 2009 @@ -300,7 +300,7 @@ // Okay, everything after this looks good, check to make sure that this block // doesn't include any side effects. for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) - if (I->mayWriteToMemory()) + if (I->mayHaveSideEffects()) return false; return true; @@ -383,7 +383,7 @@ // part of the loop that the code *would* execute. We already checked the // tail, check the header now. for (BasicBlock::iterator I = Header->begin(), E = Header->end(); I != E; ++I) - if (I->mayWriteToMemory()) + if (I->mayHaveSideEffects()) return false; return true; } Modified: llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp?rev=71071&r1=71070&r2=71071&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp Wed May 6 01:49:50 2009 @@ -258,7 +258,7 @@ while (!isa(BBI)) { Instruction *I = BBI++; - bool CanHoist = !I->isTrapping() && !I->mayWriteToMemory(); + bool CanHoist = !I->isTrapping() && !I->mayHaveSideEffects(); if (CanHoist) { for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) if (Instruction *OpI = dyn_cast(I->getOperand(op))) Modified: llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp?rev=71071&r1=71070&r2=71071&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp Wed May 6 01:49:50 2009 @@ -201,7 +201,7 @@ bool TailCallElim::CanMoveAboveCall(Instruction *I, CallInst *CI) { // FIXME: We can move load/store/call/free instructions above the call if the // call does not mod/ref the memory location being processed. - if (I->mayWriteToMemory() || isa(I)) + if (I->mayHaveSideEffects() || isa(I)) return false; // Otherwise, if this is a side-effect free instruction, check to make sure Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=71071&r1=71070&r2=71071&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Wed May 6 01:49:50 2009 @@ -164,17 +164,15 @@ // We don't want debug info removed by anything this general. if (isa(I)) return false; - - if (!I->mayWriteToMemory()) - return true; - // Special case intrinsics that "may write to memory" but can be deleted when - // dead. + if (!I->mayHaveSideEffects()) return true; + + // Special case intrinsics that "may have side effects" but can be deleted + // when dead. if (IntrinsicInst *II = dyn_cast(I)) // Safe to delete llvm.stacksave if dead. if (II->getIntrinsicID() == Intrinsic::stacksave) return true; - return false; } @@ -230,7 +228,7 @@ SmallPtrSet PHIs; PHIs.insert(PN); for (Instruction *J = cast(*PN->use_begin()); - J->hasOneUse() && !J->mayWriteToMemory(); + J->hasOneUse() && !J->mayHaveSideEffects(); J = cast(*J->use_begin())) // If we find a PHI more than once, we're on a cycle that // won't prove fruitful. Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=71071&r1=71070&r2=71071&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Wed May 6 01:49:50 2009 @@ -320,6 +320,14 @@ } } +/// mayThrow - Return true if this instruction may throw an exception. +/// +bool Instruction::mayThrow() const { + if (const CallInst *CI = dyn_cast(this)) + return !CI->doesNotThrow(); + return false; +} + /// isAssociative - Return true if the instruction is associative: /// /// Associative operators satisfy: x op (y op z) === (x op y) op z) Modified: llvm/trunk/test/Transforms/ADCE/dce_pure_call.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ADCE/dce_pure_call.ll?rev=71071&r1=71070&r2=71071&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ADCE/dce_pure_call.ll (original) +++ llvm/trunk/test/Transforms/ADCE/dce_pure_call.ll Wed May 6 01:49:50 2009 @@ -1,8 +1,8 @@ ; RUN: llvm-as < %s | opt -adce | llvm-dis | not grep call -declare i32 @strlen(i8*) readonly +declare i32 @strlen(i8*) readonly nounwind define void @test() { - call i32 @strlen( i8* null ) readonly ; :1 [#uses=0] + call i32 @strlen( i8* null ) ; :1 [#uses=0] ret void } From evan.cheng at apple.com Wed May 6 02:25:19 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 06 May 2009 07:25:19 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r71072 - /llvm-gcc-4.2/trunk/gcc/config/i386/i386.h Message-ID: <200905060725.n467PJAB000313@zion.cs.uiuc.edu> Author: evancheng Date: Wed May 6 02:25:18 2009 New Revision: 71072 URL: http://llvm.org/viewvc/llvm-project?rev=71072&view=rev Log: llvm x86 backend doesn't know -mattr=+sse4a yet. Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.h Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/i386.h?rev=71072&r1=71071&r2=71072&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/i386.h (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/i386.h Wed May 6 02:25:18 2009 @@ -3888,7 +3888,6 @@ if (TARGET_SSSE3) F.AddFeature("ssse3"); \ if (TARGET_SSE4_1) F.AddFeature("sse41"); \ if (TARGET_SSE4_2) F.AddFeature("sse42"); \ - if (TARGET_SSE4A) F.AddFeature("sse4a"); \ if (TARGET_3DNOW) F.AddFeature("3dnow"); \ if (TARGET_3DNOW_A) F.AddFeature("3dnowa"); \ } From sanjiv.gupta at microchip.com Wed May 6 03:02:03 2009 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Wed, 06 May 2009 08:02:03 -0000 Subject: [llvm-commits] [llvm] r71073 - in /llvm/trunk/lib/Target/PIC16: PIC16.h PIC16AsmPrinter.cpp PIC16AsmPrinter.h PIC16ISelLowering.cpp PIC16InstrInfo.cpp PIC16InstrInfo.h PIC16InstrInfo.td PIC16MemSelOpt.cpp PIC16TargetAsmInfo.cpp PIC16TargetAsmInfo.h PIC16TargetMachine.cpp PIC16TargetMachine.h Message-ID: <200905060802.n468237O012196@zion.cs.uiuc.edu> Author: sgupta Date: Wed May 6 03:02:01 2009 New Revision: 71073 URL: http://llvm.org/viewvc/llvm-project?rev=71073&view=rev Log: Emit banksel and movlp instructions. Split large global data (both initialized and un-initialized) into multiple sections of <= 80 bytes. Provide routines to manage PIC16 ABI naming conventions. Added: llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp Modified: llvm/trunk/lib/Target/PIC16/PIC16.h llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h Modified: llvm/trunk/lib/Target/PIC16/PIC16.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16.h?rev=71073&r1=71072&r2=71073&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16.h Wed May 6 03:02:01 2009 @@ -18,6 +18,7 @@ #include "llvm/Target/TargetMachine.h" #include #include +#include namespace llvm { class PIC16TargetMachine; @@ -39,6 +40,94 @@ UGE }; } + // A Central object to manage all ABI naming conventions. + class PIC16ABINames { + public: + // Map the name of the symbol to its section name. + // Current ABI: + // ------------------------------------------------------ + // Global variables do not have any '.' in their names. + // they are prefixed with @ + // These are maily function names and global variable names. + // ------------------------------------------------------- + // Functions and auto variables. + // Names are mangled as .. + // Where prefix is a special char '@' and id is any one of + // the following + // .auto. - an automatic var of a function. + // .temp. - temproray data of a function. + // .ret. - return value label for a function. + // .frame. - Frame label for a function where retval, args + // and temps are stored. + // .args. - Label used to pass arguments to a direct call. + // Example - Function name: @foo + // Its frame: @foo.frame. + // Its retval: @foo.ret. + // Its local vars: @foo.auto.a + // Its temp data: @foo.temp. + // Its arg passing: @foo.args. + //---------------------------------------------- + // Libcall - compiler generated libcall names must have a .lib. + // This id will be used to emit extern decls for libcalls. + // Example - libcall name: @sra_i8.lib. + // To pass args: @sra_i8.args. + // To return val: @sra_i8.ret. + //---------------------------------------------- + + enum IDs { + PREFIX_SYMBOL, + + FUNC_AUTOS, + FUNC_FRAME, + FUNC_RET, + FUNC_ARGS, + FUNC_TEMPS, + + LIBCALL, + + FRAME_SECTION, + AUTOS_SECTION + }; + + }; + + inline static const char *getIDName(PIC16ABINames::IDs id) { + switch (id) { + default: assert(0 && "Unknown id"); + case PIC16ABINames::PREFIX_SYMBOL: return "@"; + case PIC16ABINames::FUNC_AUTOS: return ".auto."; + case PIC16ABINames::FUNC_FRAME: return ".frame."; + case PIC16ABINames::FUNC_TEMPS: return ".temp."; + case PIC16ABINames::FUNC_ARGS: return ".args."; + case PIC16ABINames::FUNC_RET: return ".ret."; + case PIC16ABINames::FRAME_SECTION: return "fpdata"; + case PIC16ABINames::AUTOS_SECTION: return "fadata"; + } + } + + inline static PIC16ABINames::IDs getID(const std::string &Sym) { + if (Sym.find(getIDName(PIC16ABINames::FUNC_TEMPS))) + return PIC16ABINames::FUNC_TEMPS; + + if (Sym.find(getIDName(PIC16ABINames::FUNC_FRAME))) + return PIC16ABINames::FUNC_FRAME; + + if (Sym.find(getIDName(PIC16ABINames::FUNC_RET))) + return PIC16ABINames::FUNC_RET; + + if (Sym.find(getIDName(PIC16ABINames::FUNC_ARGS))) + return PIC16ABINames::FUNC_ARGS; + + if (Sym.find(getIDName(PIC16ABINames::FUNC_AUTOS))) + return PIC16ABINames::FUNC_AUTOS; + + if (Sym.find(getIDName(PIC16ABINames::LIBCALL))) + return PIC16ABINames::LIBCALL; + + // It does not have any ID. So its a global. + assert (0 && "Could not determine ID symbol type"); + } + inline static const char *PIC16CondCodeToString(PIC16CC::CondCodes CC) { switch (CC) { @@ -73,11 +162,15 @@ } + FunctionPass *createPIC16ISelDag(PIC16TargetMachine &TM); FunctionPass *createPIC16CodePrinterPass(raw_ostream &OS, PIC16TargetMachine &TM, CodeGenOpt::Level OptLevel, bool Verbose); + // Banksel optimzer pass. + FunctionPass *createPIC16MemSelOptimizerPass(); + std::string getSectionNameForSym(const std::string &Sym); } // end namespace llvm; // Defines symbolic names for PIC16 registers. This defines a mapping from Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp?rev=71073&r1=71072&r2=71073&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp Wed May 6 03:02:01 2009 @@ -45,51 +45,6 @@ } bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) { - std::string NewBank = ""; - unsigned Operands = MI->getNumOperands(); - if (Operands > 1) { - // If we have a Global address or external symbol then we need to print - // banksel for it. - unsigned BankSelVar = 0; - MachineOperand Op = MI->getOperand(BankSelVar); - while (BankSelVar < Operands-1) { - Op = MI->getOperand(BankSelVar); - if ((Op.getType() == MachineOperand::MO_GlobalAddress) || - (Op.getType() == MachineOperand::MO_ExternalSymbol)) - break; - BankSelVar++; - } - if (BankSelVar < Operands-1) { - unsigned OpType = Op.getType(); - if (OpType == MachineOperand::MO_GlobalAddress ) - NewBank = Op.getGlobal()->getSection(); - else { - // External Symbol is generated for temp data and arguments. They are - // in fpdata..# section. - std::string ESName = Op.getSymbolName(); - int index = ESName.find_first_of("."); - std::string FnName = ESName.substr(0,index); - NewBank = "fpdata." + FnName +".#"; - } - // Operand after global address or external symbol should be banksel. - // Value 1 for this operand means we need to generate banksel else do not - // generate banksel. - const MachineOperand &BS = MI->getOperand(BankSelVar+1); - // If Section names are same then the variables are in same section. - // This is not true for external variables as section names for global - // variables in all files are same at this time. For eg. initialized - // data in put in idata.# section in all files. - if ((BS.getType() == MachineOperand::MO_Immediate - && (int)BS.getImm() == 1) - && ((Op.isGlobal() && Op.getGlobal()->hasExternalLinkage()) || - (NewBank.compare(CurBank) != 0))) { - O << "\tbanksel "; - printOperand(MI, BankSelVar); - O << "\n"; - CurBank = NewBank; - } - } - } printInstruction(MI); return true; } @@ -118,8 +73,8 @@ SwitchToSection (fCodeSection); // Emit the frame address of the function at the beginning of code. - O << " retlw low(" << FunctionLabelBegin<< CurrentFnName << ".frame)\n"; - O << " retlw high(" << FunctionLabelBegin<< CurrentFnName << ".frame)\n"; + O << " retlw low(" << FunctionLabelBegin<< CurrentFnName << ".frame.)\n"; + O << " retlw high(" << FunctionLabelBegin<< CurrentFnName << ".frame.)\n"; O << CurrentFnName << ":\n"; @@ -131,7 +86,6 @@ printBasicBlockLabel(I, true); O << '\n'; } - CurBank = ""; // For emitting line directives, we need to keep track of the current // source line. When it changes then only emit the line directive. @@ -225,8 +179,7 @@ DW->BeginModule(&M, MMI, O, this, TAI); EmitExternsAndGlobals (M); - EmitInitData (M); - EmitUnInitData(M); + EmitGlobalData(M); EmitRomData(M); return Result; } @@ -245,13 +198,13 @@ if (I->isDeclaration()) { O << "\textern " <hasExternalLinkage()) { O << "\tglobal " << Name << "\n"; - O << "\tglobal " << FunctionLabelBegin << Name << ".retval\n"; - O << "\tglobal " << FunctionLabelBegin<< Name << ".args\n"; + O << "\tglobal " << FunctionLabelBegin << Name << ".ret.\n"; + O << "\tglobal " << FunctionLabelBegin<< Name << ".args.\n"; } } @@ -274,35 +227,6 @@ } } -void PIC16AsmPrinter::EmitInitData (Module &M) { - SwitchToSection(TAI->getDataSection()); - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - if (!I->hasInitializer()) // External global require no code. - continue; - - Constant *C = I->getInitializer(); - const PointerType *PtrTy = I->getType(); - int AddrSpace = PtrTy->getAddressSpace(); - - if ((!C->isNullValue()) && (AddrSpace == PIC16ISD::RAM_SPACE)) { - - if (EmitSpecialLLVMGlobal(I)) - continue; - - // Any variables reaching here with "." in its name is a local scope - // variable and should not be printed in global data section. - std::string Name = Mang->getValueName(I); - if (isLocalName(Name)) - continue; - - I->setSection(TAI->getDataSection()->getName()); - O << Name; - EmitGlobalConstant(C, AddrSpace); - } - } -} - void PIC16AsmPrinter::EmitRomData (Module &M) { SwitchToSection(TAI->getReadOnlySection()); @@ -335,39 +259,6 @@ IsRomData = false; } -void PIC16AsmPrinter::EmitUnInitData (Module &M) -{ - SwitchToSection(TAI->getBSSSection_()); - const TargetData *TD = TM.getTargetData(); - - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - if (!I->hasInitializer()) // External global require no code. - continue; - - Constant *C = I->getInitializer(); - if (C->isNullValue()) { - - if (EmitSpecialLLVMGlobal(I)) - continue; - - // Any variables reaching here with "." in its name is a local scope - // variable and should not be printed in global data section. - std::string name = Mang->getValueName(I); - if (name.find(".") != std::string::npos) - continue; - - I->setSection(TAI->getBSSSection_()->getName()); - - const Type *Ty = C->getType(); - unsigned Size = TD->getTypePaddedSize(Ty); - - O << name << " " <<"RES"<< " " << Size ; - O << "\n"; - } - } -} - bool PIC16AsmPrinter::doFinalization(Module &M) { O << "\t" << "END\n"; bool Result = AsmPrinter::doFinalization(M); @@ -390,7 +281,7 @@ // Emit function frame label - O << FunctionLabelBegin << CurrentFnName << ".frame:\n"; + O << FunctionLabelBegin << CurrentFnName << ".frame.:\n"; const Type *RetType = F->getReturnType(); unsigned RetSize = 0; @@ -399,10 +290,10 @@ //Emit function return value space if(RetSize > 0) - O << FunctionLabelBegin << CurrentFnName << ".retval RES " << RetSize + O << FunctionLabelBegin << CurrentFnName << ".ret. RES " << RetSize << "\n"; else - O << FunctionLabelBegin << CurrentFnName << ".retval:\n"; + O << FunctionLabelBegin << CurrentFnName << ".ret.:\n"; // Emit variable to hold the space for function arguments unsigned ArgSize = 0; @@ -411,13 +302,13 @@ const Type *Ty = argi->getType(); ArgSize += TD->getTypePaddedSize(Ty); } - O << FunctionLabelBegin << CurrentFnName << ".args RES " << ArgSize + O << FunctionLabelBegin << CurrentFnName << ".args. RES " << ArgSize << "\n"; // Emit temporary space int TempSize = PTLI->GetTmpSize(); if (TempSize > 0 ) - O << FunctionLabelBegin << CurrentFnName << ".tmp RES " << TempSize + O << FunctionLabelBegin << CurrentFnName << ".temp. RES " << TempSize <<"\n"; // Emit the section name for local variables. @@ -454,5 +345,40 @@ // Emit memory reserve directive. O << FunctionLabelBegin << VarName << " RES " << Size << "\n"; } +} + +void PIC16AsmPrinter::EmitGlobalData (Module &M) +{ + const PIC16TargetAsmInfo *PTAI = static_cast(TAI); + const_cast(PTAI)->SetSectionForGVs(M); + const TargetData *TD = TM.getTargetData(); + std::vector IDATASections = PTAI->getIDATASections(); + for (unsigned i = 0; i < IDATASections.size(); i++) { + SwitchToSection(IDATASections[i]->S_); + std::vector Items = IDATASections[i]->Items; + for (unsigned j = 0; j < Items.size(); j++) { + std::string Name = Mang->getValueName(Items[j]); + Constant *C = Items[j]->getInitializer(); + int AddrSpace = Items[j]->getType()->getAddressSpace(); + O << Name; + EmitGlobalConstant(C, AddrSpace); + } + } + + std::vector BSSSections = PTAI->getBSSSections(); + for (unsigned i = 0; i < BSSSections.size(); i++) { + SwitchToSection(BSSSections[i]->S_); + std::vector Items = BSSSections[i]->Items; + for (unsigned j = 0; j < Items.size(); j++) { + std::string Name = Mang->getValueName(Items[j]); + Constant *C = Items[j]->getInitializer(); + const Type *Ty = C->getType(); + unsigned Size = TD->getTypePaddedSize(Ty); + + O << Name << " " <<"RES"<< " " << Size ; + O << "\n"; + } + } } + Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h?rev=71073&r1=71072&r2=71073&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h Wed May 6 03:02:01 2009 @@ -28,7 +28,6 @@ const TargetAsmInfo *T, CodeGenOpt::Level OL, bool V) : AsmPrinter(O, TM, T, OL, V) { - CurBank = ""; FunctionLabelBegin = '@'; IsRomData = false; PTLI = TM.getTargetLowering(); @@ -44,8 +43,7 @@ bool printInstruction(const MachineInstr *MI); // definition autogenerated. bool printMachineInstruction(const MachineInstr *MI); void EmitExternsAndGlobals (Module &M); - void EmitInitData (Module &M); - void EmitUnInitData (Module &M); + void EmitGlobalData (Module &M); void EmitRomData (Module &M); void emitFunctionData(MachineFunction &MF); @@ -55,7 +53,6 @@ private: PIC16TargetLowering *PTLI; - std::string CurBank; bool IsRomData; char FunctionLabelBegin; }; Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=71073&r1=71072&r2=71073&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Wed May 6 03:02:01 2009 @@ -531,7 +531,7 @@ unsigned FIndex = FR->getIndex(); char *tmpName = new char [strlen(Name.c_str()) + 8]; if (FIndex < ReservedFrameCount) { - sprintf(tmpName, "%s.frame", Name.c_str()); + sprintf(tmpName, "%s.frame.", Name.c_str()); ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); Offset = 0; for (unsigned i=0; igetObjectSize(FIndex)); } @@ -850,7 +850,7 @@ // Put the value on stack. // Get a stack slot index and convert to es. int FI = MF.getFrameInfo()->CreateStackObject(1, 1); - sprintf(tmpName, "%s.tmp", FuncName.c_str()); + sprintf(tmpName, "%s.temp.", FuncName.c_str()); SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); // Store the value to ES. @@ -1065,7 +1065,7 @@ std::string FuncName = F->getName(); char *tmpName = new char [strlen(FuncName.c_str()) + 8]; - sprintf(tmpName, "%s.frame", FuncName.c_str()); + sprintf(tmpName, "%s.frame.", FuncName.c_str()); SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Other); SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); SDValue BS = DAG.getConstant(1, MVT::i8); @@ -1250,12 +1250,12 @@ // Label for argument passing char *argFrame = new char [strlen(Name.c_str()) + 8]; - sprintf(argFrame, "%s.args", Name.c_str()); + sprintf(argFrame, "%s.args.", Name.c_str()); ArgLabel = DAG.getTargetExternalSymbol(argFrame, MVT::i8); // Label for reading return value char *retName = new char [strlen(Name.c_str()) + 8]; - sprintf(retName, "%s.retval", Name.c_str()); + sprintf(retName, "%s.ret.", Name.c_str()); RetLabel = DAG.getTargetExternalSymbol(retName, MVT::i8); } else { // if indirect call @@ -1451,8 +1451,8 @@ InitReservedFrameCount(F); // Create the .args external symbol. - char *tmpName = new char [strlen(FuncName.c_str()) + 6]; - sprintf(tmpName, "%s.args", FuncName.c_str()); + char *tmpName = new char [strlen(FuncName.c_str()) + 8]; + sprintf(tmpName, "%s.args.", FuncName.c_str()); SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); // Load arg values from the label + offset. Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp?rev=71073&r1=71072&r2=71073&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp Wed May 6 03:02:01 2009 @@ -76,8 +76,8 @@ const Function *Func = MBB.getParent()->getFunction(); const std::string FuncName = Func->getName(); - char *tmpName = new char [strlen(FuncName.c_str()) + 6]; - sprintf(tmpName, "%s.tmp", FuncName.c_str()); + char *tmpName = new char [strlen(FuncName.c_str()) + 10]; + sprintf(tmpName, "%s.temp.", FuncName.c_str()); // On the order of operands here: think "movwf SrcReg, tmp_slot, offset". if (RC == PIC16::GPRRegisterClass) { @@ -119,8 +119,8 @@ const Function *Func = MBB.getParent()->getFunction(); const std::string FuncName = Func->getName(); - char *tmpName = new char [strlen(FuncName.c_str()) + 6]; - sprintf(tmpName, "%s.tmp", FuncName.c_str()); + char *tmpName = new char [strlen(FuncName.c_str()) + 10]; + sprintf(tmpName, "%s.temp.", FuncName.c_str()); // On the order of operands here: think "movf FrameIndex, W". if (RC == PIC16::GPRRegisterClass) { Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h?rev=71073&r1=71072&r2=71073&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h Wed May 6 03:02:01 2009 @@ -64,6 +64,23 @@ unsigned &SrcReg, unsigned &DstReg, unsigned &SrcSubIdx, unsigned &DstSubIdx) const; + static inline bool hasNoMemOperand (const MachineInstr &MI) { + + if (MI.getNumOperands() == 0) return true; + + switch (MI.getOpcode()) { + default: return false; // Beware + case PIC16::movlw_lo_1: + case PIC16::movlw_hi_1: + case PIC16::movlw_lo_2: + case PIC16::movlw_hi_2: + return true; + } + } + + + + }; } // namespace llvm Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td?rev=71073&r1=71072&r2=71073&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td Wed May 6 03:02:01 2009 @@ -470,13 +470,18 @@ // Banksel. -let isReMaterializable = 1 in { def banksel : - Pseudo<(outs BSR:$dst), + Pseudo<(outs), (ins i8mem:$ptr), "banksel $ptr", - [(set BSR:$dst, (Banksel tglobaladdr:$ptr))]>; -} + []>; + +def pagesel : + Pseudo<(outs), + (ins i8mem:$ptr), + "movlp $ptr", + []>; + // Return insn. def Return : Added: llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp?rev=71073&view=auto ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp (added) +++ llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp Wed May 6 03:02:01 2009 @@ -0,0 +1,163 @@ +//===-- PIC16MemSelOpt.cpp - PIC16 banksel optimizer --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the pass which optimizes the emitting of banksel +// instructions before accessing data memory. This currently works within +// a basic block only and keep tracks of the last accessed memory bank. +// If memory access continues to be in the same bank it just makes banksel +// immediate, which is a part of the insn accessing the data memory, from 1 +// to zero. The asm printer emits a banksel only if that immediate is 1. +// +// FIXME: this is not implemented yet. The banksel pass only works on local +// basic blocks. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "pic16-codegen" +#include "PIC16.h" +#include "PIC16InstrInfo.h" +#include "PIC16TargetAsmInfo.h" +#include "PIC16TargetMachine.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/GlobalValue.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Support/Compiler.h" + +using namespace llvm; + +namespace { + struct VISIBILITY_HIDDEN MemSelOpt : public MachineFunctionPass { + static char ID; + MemSelOpt() : MachineFunctionPass(&ID) {} + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addPreservedID(MachineLoopInfoID); + AU.addPreservedID(MachineDominatorsID); + MachineFunctionPass::getAnalysisUsage(AU); + } + + virtual bool runOnMachineFunction(MachineFunction &MF); + + virtual const char *getPassName() const { + return "PIC16 Memsel Optimizer"; + } + + bool processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB); + bool processInstruction(MachineInstr *MI); + + private: + const TargetInstrInfo *TII; // Machine instruction info. + MachineBasicBlock *MBB; // Current basic block + std::string CurBank; + + }; + char MemSelOpt::ID = 0; +} + +FunctionPass *llvm::createPIC16MemSelOptimizerPass() { + return new MemSelOpt(); +} + + +/// runOnMachineFunction - Loop over all of the basic blocks, transforming FP +/// register references into FP stack references. +/// +bool MemSelOpt::runOnMachineFunction(MachineFunction &MF) { + TII = MF.getTarget().getInstrInfo(); + bool Changed = false; + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + Changed |= processBasicBlock(MF, *I); + } + + return Changed; +} + +/// processBasicBlock - Loop over all of the instructions in the basic block, +/// transforming FP instructions into their stack form. +/// +bool MemSelOpt::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) { + bool Changed = false; + MBB = &BB; + + // Let us assume that when entering a basic block now bank is selected. + // Ideally we should look at the predecessors for this information. + CurBank=""; + + for (MachineBasicBlock::iterator I = BB.begin(); I != BB.end(); ++I) { + Changed |= processInstruction(I); + } + return Changed; +} + +bool MemSelOpt::processInstruction(MachineInstr *MI) { + bool Changed = false; + + unsigned NumOperands = MI->getNumOperands(); + // If this insn has only one operand, probably it is not going to + // access any data memory. + if (PIC16InstrInfo::hasNoMemOperand(*MI)) return Changed; + + // Scan for the memory address operand. + // FIXME: Should we use standard interfaces like memoperands_iterator, + // hasMemOperand() etc ? + int MemOpPos = -1; + for (unsigned i = 0; i < NumOperands; i++) { + MachineOperand Op = MI->getOperand(i); + if (Op.getType() == MachineOperand::MO_GlobalAddress || + Op.getType() == MachineOperand::MO_ExternalSymbol) { + // We found one mem operand. Next one should be BS. + MemOpPos = i; + break; + } + } + + // If we did not find an insn accessing memory. Continue. + if (MemOpPos == -1) return Changed; + + // Get the MemOp. + MachineOperand &Op = MI->getOperand(MemOpPos); + + // If this is a pagesel material, handle it first. + if (MI->getOpcode() == PIC16::CALL) { + DebugLoc dl = MI->getDebugLoc(); + BuildMI(*MBB, MI, dl, TII->get(PIC16::pagesel)). + addOperand(Op); + return true; + } + + // Get the section name(NewBank) for MemOp. + std::string NewBank = CurBank; + if (Op.getType() == MachineOperand::MO_GlobalAddress && + Op.getGlobal()->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) { + NewBank = Op.getGlobal()->getSection(); + } else if (Op.getType() == MachineOperand::MO_ExternalSymbol) { + // External Symbol is generated for temp data and arguments. They are + // in fpdata..# section. + std::string Sym = Op.getSymbolName(); + NewBank = getSectionNameForSym(Sym); + } + + // If the previous and new section names are same, we don't need to + // emit banksel. + if (NewBank.compare(CurBank) != 0 ) { + DebugLoc dl = MI->getDebugLoc(); + BuildMI(*MBB, MI, dl, TII->get(PIC16::banksel)). + addOperand(Op); + Changed = true; + CurBank = NewBank; + } + + return Changed; +} + Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp?rev=71073&r1=71072&r2=71073&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp Wed May 6 03:02:01 2009 @@ -14,6 +14,8 @@ #include "PIC16TargetAsmInfo.h" #include "PIC16TargetMachine.h" #include "llvm/GlobalValue.h" +#include "llvm/GlobalVariable.h" +#include "llvm/DerivedTypes.h" using namespace llvm; @@ -61,3 +63,204 @@ return NULL; } +const Section * +PIC16TargetAsmInfo::getBSSSectionForGlobal(const GlobalVariable *GV) const { + assert (GV->hasInitializer() && "This global doesn't need space"); + Constant *C = GV->getInitializer(); + assert (C->isNullValue() && "Unitialized globals has non-zero initializer"); + + // Find how much space this global needs. + const TargetData *TD = TM.getTargetData(); + const Type *Ty = C->getType(); + unsigned ValSize = TD->getTypePaddedSize(Ty); + + // Go through all BSS Sections and assign this variable + // to the first available section having enough space. + PIC16Section *FoundBSS = NULL; + for (unsigned i = 0; i < BSSSections.size(); i++) { + if (DataBankSize - BSSSections[i]->Size >= ValSize) { + FoundBSS = BSSSections[i]; + break; + } + } + + // No BSS section spacious enough was found. Crate a new one. + if (! FoundBSS) { + char *name = new char[32]; + sprintf (name, "udata.%d.# UDATA", BSSSections.size()); + const Section *NewSection = getNamedSection (name); + + FoundBSS = new PIC16Section(NewSection); + + // Add this newly created BSS section to the list of BSSSections. + BSSSections.push_back(FoundBSS); + } + + // Insert the GV into this BSS. + FoundBSS->Items.push_back(GV); + FoundBSS->Size += ValSize; + + // We can't do this here because GV is const . + // const std::string SName = FoundBSS->S_->getName(); + // GV->setSection(SName); + + return FoundBSS->S_; +} + +const Section * +PIC16TargetAsmInfo::getIDATASectionForGlobal(const GlobalVariable *GV) const { + assert (GV->hasInitializer() && "This global doesn't need space"); + Constant *C = GV->getInitializer(); + assert (!C->isNullValue() && "initialized globals has zero initializer"); + assert (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE && + "can split initialized RAM data only"); + + // Find how much space this global needs. + const TargetData *TD = TM.getTargetData(); + const Type *Ty = C->getType(); + unsigned ValSize = TD->getTypePaddedSize(Ty); + + // Go through all IDATA Sections and assign this variable + // to the first available section having enough space. + PIC16Section *FoundIDATA = NULL; + for (unsigned i = 0; i < IDATASections.size(); i++) { + if ( DataBankSize - IDATASections[i]->Size >= ValSize) { + FoundIDATA = IDATASections[i]; + break; + } + } + + // No IDATA section spacious enough was found. Crate a new one. + if (! FoundIDATA) { + char *name = new char[32]; + sprintf (name, "idata.%d.# IDATA", IDATASections.size()); + const Section *NewSection = getNamedSection (name); + + FoundIDATA = new PIC16Section(NewSection); + + // Add this newly created IDATA section to the list of IDATASections. + IDATASections.push_back(FoundIDATA); + } + + // Insert the GV into this IDATA. + FoundIDATA->Items.push_back(GV); + FoundIDATA->Size += ValSize; + + // We can't do this here because GV is const . + // GV->setSection(FoundIDATA->S->getName()); + + return FoundIDATA->S_; +} + +// Override default implementation to put the true globals into +// multiple data sections if required. +const Section* +PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1) const { + // We select the section based on the initializer here, so it really + // has to be a GlobalVariable. + if (!isa(GV1)) + return TargetAsmInfo::SelectSectionForGlobal(GV1); + + const GlobalVariable *GV = dyn_cast(GV1); + // We are only dealing with true globals here. So names with a "." + // are local globals. Also declarations are not entertained. + std::string name = GV->getName(); + if (name.find(".auto.") != std::string::npos + || name.find(".arg.") != std::string::npos || !GV->hasInitializer()) + return TargetAsmInfo::SelectSectionForGlobal(GV); + + const Constant *C = GV->getInitializer(); + // See if this is an uninitialized global. + if (C->isNullValue()) + return getBSSSectionForGlobal(GV); + + // This is initialized data. We only deal with initialized data in RAM. + if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) + return getIDATASectionForGlobal(GV); + + // Else let the default implementation take care of it. + return TargetAsmInfo::SelectSectionForGlobal(GV); +} + +void PIC16TargetAsmInfo::SetSectionForGVs(Module &M) { + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { + if (!I->hasInitializer()) // External global require no code. + continue; + + // Any variables reaching here with "." in its name is a local scope + // variable and should not be printed in global data section. + std::string name = I->getName(); + if (name.find(".auto.") != std::string::npos + || name.find(".arg.") != std::string::npos) + continue; + int AddrSpace = I->getType()->getAddressSpace(); + + if (AddrSpace == PIC16ISD::RAM_SPACE) + I->setSection(SectionForGlobal(I)->getName()); + } +} + + +// Helper routine. +// Func name starts after prefix and followed by a . +static std::string getFuncNameForSym(const std::string &Sym, + PIC16ABINames::IDs PrefixType) { + + const char *prefix = getIDName (PIC16ABINames::PREFIX_SYMBOL); + + // This name may or may not start with prefix; + // Func names start after prfix in that case. + size_t func_name_start = 0; + if (Sym.find(prefix, 0, strlen(prefix)) != std::string::npos) + func_name_start = strlen(prefix); + + // Position of the . after func name. + size_t func_name_end = Sym.find ('.', func_name_start); + + return Sym.substr (func_name_start, func_name_end); +} + +// Helper routine to create a section name given the section prefix +// and func name. +static std::string +getSectionNameForFunc (const std::string &Fname, + const PIC16ABINames::IDs sec_id) { + std::string sec_id_string = getIDName (sec_id); + return sec_id_string + "." + Fname + ".#"; +} + + +// Get the section for the given external symbol names. +// This function is meant for only mangled external symbol names. +std::string +llvm::getSectionNameForSym(const std::string &Sym) { + std::string SectionName; + + PIC16ABINames::IDs id = getID (Sym); + std::string Fname = getFuncNameForSym (Sym, id); + + switch (id) { + default : assert (0 && "Could not determine external symbol type"); + case PIC16ABINames::FUNC_FRAME: + case PIC16ABINames::FUNC_RET: + case PIC16ABINames::FUNC_TEMPS: + case PIC16ABINames::FUNC_ARGS: { + return getSectionNameForFunc (Fname, PIC16ABINames::FRAME_SECTION); + } + case PIC16ABINames::FUNC_AUTOS: { + return getSectionNameForFunc (Fname, PIC16ABINames::AUTOS_SECTION); + } + } +} + +PIC16TargetAsmInfo::~PIC16TargetAsmInfo() { + + for (unsigned i = 0; i < BSSSections.size(); i++) { + delete BSSSections[i]; + } + + for (unsigned i = 0; i < IDATASections.size(); i++) { + delete IDATASections[i]; + } +} Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h?rev=71073&r1=71072&r2=71073&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h Wed May 6 03:02:01 2009 @@ -14,21 +14,54 @@ #ifndef PIC16TARGETASMINFO_H #define PIC16TARGETASMINFO_H +#include "PIC16.h" #include "llvm/Target/TargetAsmInfo.h" - +#include +#include "llvm/Module.h" +#define DataBankSize 80 namespace llvm { // Forward declaration. class PIC16TargetMachine; + class GlobalVariable; + // PIC16 Splits the global data into mulitple udata and idata sections. + // Each udata and idata section needs to contain a list of globals that + // they contain, in order to avoid scanning over all the global values + // again and printing only those that match the current section. + // Keeping values inside the sections make printing a section much easier. + struct PIC16Section { + const Section *S_; // Connection to actual Section. + unsigned Size; // Total size of the objects contained. + std::vector Items; + + PIC16Section (const Section *s) { S_ = s; Size = 0; } + }; + struct PIC16TargetAsmInfo : public TargetAsmInfo { + std::string getSectionNameForSym(const std::string &Sym) const; PIC16TargetAsmInfo(const PIC16TargetMachine &TM); + virtual ~PIC16TargetAsmInfo(); private: + mutable std::vector BSSSections; + mutable std::vector IDATASections; + const char *RomData8bitsDirective; const char *RomData16bitsDirective; const char *RomData32bitsDirective; const char *getRomDirective(unsigned size) const; virtual const char *getASDirective(unsigned size, unsigned AS) const; + const Section *getBSSSectionForGlobal(const GlobalVariable *GV) const; + const Section *getIDATASectionForGlobal(const GlobalVariable *GV) const; + virtual const Section *SelectSectionForGlobal(const GlobalValue *GV) const; + public: + void SetSectionForGVs(Module &M); + std::vector getBSSSections() const { + return BSSSections; + } + std::vector getIDATASections() const { + return IDATASections; + } }; } // namespace llvm Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp?rev=71073&r1=71072&r2=71073&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp Wed May 6 03:02:01 2009 @@ -70,4 +70,10 @@ return false; } +bool PIC16TargetMachine::addPostRegAlloc(PassManagerBase &PM, + CodeGenOpt::Level OptLevel) { + PM.add(createPIC16MemSelOptimizerPass()); + return true; // -print-machineinstr should print after this. +} + Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h?rev=71073&r1=71072&r2=71073&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h Wed May 6 03:02:01 2009 @@ -62,6 +62,7 @@ virtual bool addAssemblyEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, bool Verbose, raw_ostream &Out); + virtual bool addPostRegAlloc(PassManagerBase &PM, CodeGenOpt::Level OptLevel); }; // PIC16TargetMachine. /// CooperTargetMachine From baldrick at free.fr Wed May 6 03:42:06 2009 From: baldrick at free.fr (Duncan Sands) Date: Wed, 06 May 2009 08:42:06 -0000 Subject: [llvm-commits] [llvm] r71077 - in /llvm/trunk: lib/Transforms/IPO/FunctionAttrs.cpp test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll Message-ID: <200905060842.n468g7cX013662@zion.cs.uiuc.edu> Author: baldrick Date: Wed May 6 03:42:00 2009 New Revision: 71077 URL: http://llvm.org/viewvc/llvm-project?rev=71077&view=rev Log: Fix PR3754: don't mark functions that wrap MallocInst with the readnone. Since MallocInst is scheduled for deletion it doesn't seem worth doing anything more subtle, such as having mayWriteToMemory return true for MallocInst. Added: llvm/trunk/test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll Modified: llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp Modified: llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp?rev=71077&r1=71076&r2=71077&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp Wed May 6 03:42:00 2009 @@ -152,6 +152,11 @@ if (I->mayWriteToMemory()) // Writes memory. Just give up. return false; + + if (isa(I)) + // MallocInst claims not to write memory! PR3754. + return false; + // If this instruction may read memory, remember that. ReadsMemory |= I->mayReadFromMemory(); } Added: llvm/trunk/test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll?rev=71077&view=auto ============================================================================== --- llvm/trunk/test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll (added) +++ llvm/trunk/test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll Wed May 6 03:42:00 2009 @@ -0,0 +1,7 @@ +; RUN: llvm-as < %s | opt -functionattrs | llvm-dis | not grep read +; PR3754 + +define i8* @m(i32 %size) { + %tmp = malloc i8, i32 %size ; [#uses=1] + ret i8* %tmp +} From baldrick at free.fr Wed May 6 06:29:55 2009 From: baldrick at free.fr (Duncan Sands) Date: Wed, 06 May 2009 11:29:55 -0000 Subject: [llvm-commits] [llvm] r71078 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200905061129.n46BTvsG020073@zion.cs.uiuc.edu> Author: baldrick Date: Wed May 6 06:29:50 2009 New Revision: 71078 URL: http://llvm.org/viewvc/llvm-project?rev=71078&view=rev Log: Add generic expansion of SUB when ADD and XOR are legal. Based on a patch by Micah Villmow. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=71078&r1=71077&r2=71078&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed May 6 06:29:50 2009 @@ -3268,8 +3268,7 @@ OpToUse = ISD::UMUL_LOHI; } if (OpToUse) { - Result = SDValue(DAG.getNode(OpToUse, dl, VTs, Tmp1, Tmp2).getNode(), - 0); + Result = DAG.getNode(OpToUse, dl, VTs, Tmp1, Tmp2); break; } } @@ -3289,16 +3288,21 @@ } if (Node->getOpcode() == ISD::SDIV && TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) { - Result = SDValue(DAG.getNode(ISD::SDIVREM, dl, - VTs, Tmp1, Tmp2).getNode(), - 0); + Result = DAG.getNode(ISD::SDIVREM, dl, VTs, Tmp1, Tmp2); break; } if (Node->getOpcode() == ISD::UDIV && TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) { - Result = SDValue(DAG.getNode(ISD::UDIVREM, dl, - VTs, Tmp1, Tmp2).getNode(), - 0); + Result = DAG.getNode(ISD::UDIVREM, dl, VTs, Tmp1, Tmp2); + break; + } + if (Node->getOpcode() == ISD::SUB && + TLI.isOperationLegalOrCustom(ISD::ADD, VT) && + TLI.isOperationLegalOrCustom(ISD::XOR, VT)) { + Tmp2 = DAG.getNode(ISD::XOR, dl, VT, Tmp2, + DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT)); + Tmp2 = DAG.getNode(ISD::ADD, dl, VT, Tmp2, DAG.getConstant(1, VT)); + Result = DAG.getNode(ISD::ADD, dl, VT, Tmp1, Tmp2); break; } From baldrick at free.fr Wed May 6 07:21:35 2009 From: baldrick at free.fr (Duncan Sands) Date: Wed, 06 May 2009 12:21:35 -0000 Subject: [llvm-commits] [llvm] r71081 - in /llvm/trunk: bindings/ocaml/llvm/llvm.ml bindings/ocaml/llvm/llvm.mli bindings/ocaml/llvm/llvm_ocaml.c include/llvm-c/Core.h lib/VMCore/Core.cpp test/Bindings/Ocaml/vmcore.ml Message-ID: <200905061221.n46CLcnP021862@zion.cs.uiuc.edu> Author: baldrick Date: Wed May 6 07:21:17 2009 New Revision: 71081 URL: http://llvm.org/viewvc/llvm-project?rev=71081&view=rev Log: OCaml parameter attribute bindings from PR2752. Incomplete, but better than nothing. Modified: llvm/trunk/bindings/ocaml/llvm/llvm.ml llvm/trunk/bindings/ocaml/llvm/llvm.mli llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c llvm/trunk/include/llvm-c/Core.h llvm/trunk/lib/VMCore/Core.cpp llvm/trunk/test/Bindings/Ocaml/vmcore.ml Modified: llvm/trunk/bindings/ocaml/llvm/llvm.ml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm.ml?rev=71081&r1=71080&r2=71081&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm.ml (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm.ml Wed May 6 07:21:17 2009 @@ -64,6 +64,21 @@ let x86_fastcall = 65 end +module Attribute = struct + type t = + | Zext + | Sext + | Noreturn + | Inreg + | Structret + | Nounwind + | Noalias + | Byval + | Nest + | Readnone + | Readonly +end + module Icmp = struct type t = | Eq @@ -418,7 +433,10 @@ let fold_right_functions f m init = fold_right_function_range f (function_end m) (At_start m) init -(* TODO: param attrs *) +external add_function_attr : llvalue -> Attribute.t -> unit + = "llvm_add_function_attr" +external remove_function_attr : llvalue -> Attribute.t -> unit + = "llvm_remove_function_attr" (*--... Operations on params ...............................................--*) external params : llvalue -> llvalue array = "llvm_params" @@ -469,6 +487,13 @@ let fold_right_params f fn init = fold_right_param_range f init (param_end fn) (At_start fn) +external add_param_attr : llvalue -> Attribute.t -> unit + = "llvm_add_param_attr" +external remove_param_attr : llvalue -> Attribute.t -> unit + = "llvm_remove_param_attr" +external set_param_alignment : llvalue -> int -> unit + = "llvm_set_param_alignment" + (*--... Operations on basic blocks .........................................--*) external value_of_block : llbasicblock -> llvalue = "LLVMBasicBlockAsValue" external value_is_block : llvalue -> bool = "llvm_value_is_block" @@ -586,6 +611,10 @@ = "llvm_instruction_call_conv" external set_instruction_call_conv: int -> llvalue -> unit = "llvm_set_instruction_call_conv" +external add_instruction_param_attr : llvalue -> int -> Attribute.t -> unit + = "llvm_add_instruction_param_attr" +external remove_instruction_param_attr : llvalue -> int -> Attribute.t -> unit + = "llvm_remove_instruction_param_attr" (*--... Operations on call instructions (only) .............................--*) external is_tail_call : llvalue -> bool = "llvm_is_tail_call" Modified: llvm/trunk/bindings/ocaml/llvm/llvm.mli URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm.mli?rev=71081&r1=71080&r2=71081&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm.mli (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm.mli Wed May 6 07:21:17 2009 @@ -111,6 +111,21 @@ convention from C. *) end +module Attribute : sig + type t = + | Zext + | Sext + | Noreturn + | Inreg + | Structret + | Nounwind + | Noalias + | Byval + | Nest + | Readnone + | Readonly +end + (** The predicate for an integer comparison ([icmp]) instruction. See the [llvm::ICmpInst::Predicate] enumeration. *) module Icmp : sig @@ -931,6 +946,15 @@ [gc]. See the method [llvm::Function::setGC]. *) external set_gc : string option -> llvalue -> unit = "llvm_set_gc" +(** [add_function_attr f a] adds attribute [a] to the return type of function + [f]. *) +external add_function_attr : llvalue -> Attribute.t -> unit + = "llvm_add_function_attr" + +(** [remove_function_attr f a] removes attribute [a] from the return type of + function [f]. *) +external remove_function_attr : llvalue -> Attribute.t -> unit + = "llvm_remove_function_attr" (** {7 Operations on params} *) @@ -984,6 +1008,16 @@ [b1,...,bN] are the parameters of function [fn]. Tail recursive. *) val fold_right_params : (llvalue -> 'a -> 'a) -> llvalue -> 'a -> 'a +(** [add_param p a] adds attribute [a] to parameter [p]. *) +external add_param_attr : llvalue -> Attribute.t -> unit = "llvm_add_param_attr" + +(** [remove_param_attr p a] removes attribute [a] from parameter [p]. *) +external remove_param_attr : llvalue -> Attribute.t -> unit + = "llvm_remove_param_attr" + +(** [set_param_alignment p a] set the alignment of parameter [p] to [a]. *) +external set_param_alignment : llvalue -> int -> unit + = "llvm_set_param_alignment" (** {7 Operations on basic blocks} *) @@ -1127,6 +1161,18 @@ external set_instruction_call_conv: int -> llvalue -> unit = "llvm_set_instruction_call_conv" +(** [add_instruction_param_attr ci i a] adds attribute [a] to the [i]th + parameter of the call or invoke instruction [ci]. [i]=0 denotes the return + value. *) +external add_instruction_param_attr : llvalue -> int -> Attribute.t -> unit + = "llvm_add_instruction_param_attr" + +(** [remove_instruction_param_attr ci i a] removes attribute [a] from the + [i]th parameter of the call or invoke instruction [ci]. [i]=0 denotes the + return value. *) +external remove_instruction_param_attr : llvalue -> int -> Attribute.t -> unit + = "llvm_remove_instruction_param_attr" + (** {Operations on call instructions (only)} *) (** [is_tail_call ci] is [true] if the call instruction [ci] is flagged as Modified: llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c?rev=71081&r1=71080&r2=71081&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Wed May 6 07:21:17 2009 @@ -665,6 +665,17 @@ return Val_unit; } +/* llvalue -> Attribute.t -> unit */ +CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) { + LLVMAddFunctionAttr(Arg, 1< Attribute.t -> unit */ +CAMLprim value llvm_remove_function_attr(LLVMValueRef Arg, value PA) { + LLVMRemoveFunctionAttr(Arg, 1< Attribute.t -> unit */ +CAMLprim value llvm_add_param_attr(LLVMValueRef Arg, value PA) { + LLVMAddAttribute(Arg, 1< Attribute.t -> unit */ +CAMLprim value llvm_remove_param_attr(LLVMValueRef Arg, value PA) { + LLVMRemoveAttribute(Arg, 1< int -> unit */ +CAMLprim value llvm_set_param_alignment(LLVMValueRef Arg, value align) { + LLVMSetParamAlignment(Arg, Int_val(align)); + return Val_unit; +} + /*--... Operations on basic blocks .........................................--*/ DEFINE_ITERATORS( @@ -733,6 +762,22 @@ return Val_unit; } +/* llvalue -> int -> Attribute.t -> unit */ +CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr, + value index, + value PA) { + LLVMAddInstrAttribute(Instr, Int_val(index), 1< int -> Attribute.t -> unit */ +CAMLprim value llvm_remove_instruction_param_attr(LLVMValueRef Instr, + value index, + value PA) { + LLVMRemoveInstrAttribute(Instr, Int_val(index), 1< bool */ Modified: llvm/trunk/include/llvm-c/Core.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=71081&r1=71080&r2=71081&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/Core.h (original) +++ llvm/trunk/include/llvm-c/Core.h Wed May 6 07:21:17 2009 @@ -504,6 +504,8 @@ void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC); const char *LLVMGetGC(LLVMValueRef Fn); void LLVMSetGC(LLVMValueRef Fn, const char *Name); +void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA); +void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA); /* Operations on parameters */ unsigned LLVMCountParams(LLVMValueRef Fn); Modified: llvm/trunk/lib/VMCore/Core.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=71081&r1=71080&r2=71081&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Core.cpp (original) +++ llvm/trunk/lib/VMCore/Core.cpp Wed May 6 07:21:17 2009 @@ -776,6 +776,20 @@ F->clearGC(); } +void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) { + Function *Func = unwrap(Fn); + const AttrListPtr PAL = Func->getAttributes(); + const AttrListPtr PALnew = PAL.addAttr(0, PA); + Func->setAttributes(PALnew); +} + +void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) { + Function *Func = unwrap(Fn); + const AttrListPtr PAL = Func->getAttributes(); + const AttrListPtr PALnew = PAL.removeAttr(0, PA); + Func->setAttributes(PALnew); +} + /*--.. Operations on parameters ............................................--*/ unsigned LLVMCountParams(LLVMValueRef FnRef) { Modified: llvm/trunk/test/Bindings/Ocaml/vmcore.ml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/Ocaml/vmcore.ml?rev=71081&r1=71080&r2=71081&view=diff ============================================================================== --- llvm/trunk/test/Bindings/Ocaml/vmcore.ml (original) +++ llvm/trunk/test/Bindings/Ocaml/vmcore.ml Wed May 6 07:21:17 2009 @@ -626,7 +626,13 @@ let p2 = param f 1 in set_value_name "One" p1; set_value_name "Two" p2; - + add_param_attr p1 Attribute.Sext; + add_param_attr p2 Attribute.Noalias; + remove_param_attr p2 Attribute.Noalias; + add_function_attr f Attribute.Nounwind; + add_function_attr f Attribute.Noreturn; + remove_function_attr f Attribute.Noreturn; + insist (Before p1 = param_begin f); insist (Before p2 = param_succ p1); insist (At_end f = param_succ p2); @@ -988,6 +994,10 @@ insist (not (is_tail_call ci)); set_tail_call true ci; insist (is_tail_call ci); + add_instruction_param_attr ci 0 Attribute.Nounwind; + add_instruction_param_attr ci 1 Attribute.Sext; + add_instruction_param_attr ci 2 Attribute.Noalias; + remove_instruction_param_attr ci 2 Attribute.Noalias; let inst46 = build_icmp Icmp.Eq p1 p2 "Inst46" atentry in ignore (build_select inst46 p1 p2 "Inst47" atentry); From baldrick at free.fr Wed May 6 08:51:26 2009 From: baldrick at free.fr (Duncan Sands) Date: Wed, 06 May 2009 13:51:26 -0000 Subject: [llvm-commits] [llvm] r71082 - /llvm/trunk/test/Bindings/Ocaml/vmcore.ml Message-ID: <200905061351.n46DpQqH024994@zion.cs.uiuc.edu> Author: baldrick Date: Wed May 6 08:51:18 2009 New Revision: 71082 URL: http://llvm.org/viewvc/llvm-project?rev=71082&view=rev Log: Nounwind is not valid for function return values. Modified: llvm/trunk/test/Bindings/Ocaml/vmcore.ml Modified: llvm/trunk/test/Bindings/Ocaml/vmcore.ml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/Ocaml/vmcore.ml?rev=71082&r1=71081&r2=71082&view=diff ============================================================================== --- llvm/trunk/test/Bindings/Ocaml/vmcore.ml (original) +++ llvm/trunk/test/Bindings/Ocaml/vmcore.ml Wed May 6 08:51:18 2009 @@ -994,7 +994,6 @@ insist (not (is_tail_call ci)); set_tail_call true ci; insist (is_tail_call ci); - add_instruction_param_attr ci 0 Attribute.Nounwind; add_instruction_param_attr ci 1 Attribute.Sext; add_instruction_param_attr ci 2 Attribute.Noalias; remove_instruction_param_attr ci 2 Attribute.Noalias; From ofv at wanadoo.es Wed May 6 09:28:08 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Wed, 06 May 2009 14:28:08 -0000 Subject: [llvm-commits] [llvm] r71083 - /llvm/trunk/include/llvm/Config/config.h.cmake Message-ID: <200905061428.n46ESBaC026332@zion.cs.uiuc.edu> Author: ofv Date: Wed May 6 09:27:59 2009 New Revision: 71083 URL: http://llvm.org/viewvc/llvm-project?rev=71083&view=rev Log: CMake: Added cmakedefine for HAVE_PTHREAD_H. Patch by Robert Schuster! Modified: llvm/trunk/include/llvm/Config/config.h.cmake Modified: llvm/trunk/include/llvm/Config/config.h.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Config/config.h.cmake?rev=71083&r1=71082&r2=71083&view=diff ============================================================================== --- llvm/trunk/include/llvm/Config/config.h.cmake (original) +++ llvm/trunk/include/llvm/Config/config.h.cmake Wed May 6 09:27:59 2009 @@ -276,6 +276,9 @@ /* Define to have the %a format string */ #undef HAVE_PRINTF_A +/* Have pthread.h */ +#cmakedefine HAVE_PTHREAD_H ${HAVE_PTHREAD_H} + /* Have pthread_mutex_lock */ #cmakedefine HAVE_PTHREAD_MUTEX_LOCK ${HAVE_PTHREAD_MUTEX_LOCK} From ofv at wanadoo.es Wed May 6 09:41:05 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Wed, 06 May 2009 14:41:05 -0000 Subject: [llvm-commits] [llvm] r71084 - in /llvm/trunk: cmake/config-ix.cmake include/llvm/Config/config.h.cmake Message-ID: <200905061441.n46Ef9pE026913@zion.cs.uiuc.edu> Author: ofv Date: Wed May 6 09:40:37 2009 New Revision: 71084 URL: http://llvm.org/viewvc/llvm-project?rev=71084&view=rev Log: CMake: Detects libpthread and sets HAVE_LIBPTHREAD. Modified: llvm/trunk/cmake/config-ix.cmake llvm/trunk/include/llvm/Config/config.h.cmake Modified: llvm/trunk/cmake/config-ix.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=71084&r1=71083&r2=71084&view=diff ============================================================================== --- llvm/trunk/cmake/config-ix.cmake (original) +++ llvm/trunk/cmake/config-ix.cmake Wed May 6 09:40:37 2009 @@ -37,6 +37,10 @@ check_include_file(utime.h HAVE_UTIME_H) check_include_file(windows.h HAVE_WINDOWS_H) +# library checks +include(CheckLibraryExists) +check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD) + # function checks include(CheckSymbolExists) check_symbol_exists(getpagesize unistd.h HAVE_GETPAGESIZE) Modified: llvm/trunk/include/llvm/Config/config.h.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Config/config.h.cmake?rev=71084&r1=71083&r2=71084&view=diff ============================================================================== --- llvm/trunk/include/llvm/Config/config.h.cmake (original) +++ llvm/trunk/include/llvm/Config/config.h.cmake Wed May 6 09:40:37 2009 @@ -194,7 +194,7 @@ #cmakedefine HAVE_LIBPSAPI ${HAVE_LIBPSAPI} /* Define to 1 if you have the `pthread' library (-lpthread). */ -#undef HAVE_LIBPTHREAD +#cmakedefine HAVE_LIBPTHREAD ${HAVE_LIBPTHREAD} /* Define to 1 if you have the `udis86' library (-ludis86). */ #undef HAVE_LIBUDIS86 From ofv at wanadoo.es Wed May 6 09:56:58 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Wed, 06 May 2009 14:56:58 -0000 Subject: [llvm-commits] [llvm] r71085 - /llvm/trunk/lib/CodeGen/CMakeLists.txt Message-ID: <200905061456.n46EuwGF027505@zion.cs.uiuc.edu> Author: ofv Date: Wed May 6 09:56:40 2009 New Revision: 71085 URL: http://llvm.org/viewvc/llvm-project?rev=71085&view=rev Log: CMake: Updated lib/CodeGen/CMakeLists.txt. Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=71085&r1=71084&r2=71085&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Wed May 6 09:56:40 2009 @@ -47,7 +47,6 @@ ScheduleDAGPrinter.cpp ShadowStackGC.cpp SimpleRegisterCoalescing.cpp - Spiller.cpp StackProtector.cpp StackSlotColoring.cpp StrongPHIElimination.cpp @@ -55,4 +54,5 @@ TwoAddressInstructionPass.cpp UnreachableBlockElim.cpp VirtRegMap.cpp + VirtRegRewriter.cpp ) From dag at cray.com Wed May 6 11:01:58 2009 From: dag at cray.com (David Greene) Date: Wed, 6 May 2009 11:01:58 -0500 Subject: [llvm-commits] [llvm-testresults] buildbot failure in The LLVM Compiler Infrastructure on full-llvm-OSX In-Reply-To: References: <20090505203815.0C25128050@relay13.apple.com> Message-ID: <200905061101.59051.dag@cray.com> On Tuesday 05 May 2009 15:44, Bill Wendling wrote: > David, > > Your recent check-in r71008 is causing this failure. Please investigate: > > Running /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ > CodeGen/X86/dg.exp ... > FAIL: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ > CodeGen/X86/change-compare-stride-1.ll > Failed with exit(1) at line 2 > while running: grep {cmpq $-478,} change-compare-stride-1.ll.tmp > child process exited abnormally This seems to be a bug in APInt. From LoopStrengthReduce.cpp: Scale = SSInt / CmpSSInt; int64_t NewCmpVal = CmpVal * Scale; APInt Mul = APInt(BitWidth*2, CmpVal); Mul = Mul * APInt(BitWidth*2, Scale); // Check for overflow. if (!Mul.isSignedIntN(BitWidth)) (gdb) print SSInt $30 = -478 (gdb) print CmpSSInt $31 = 1 (gdb) print NewCmpVal $32 = -304964 (gdb) p/x Mul.pVal[0] $34 = 0xfffffffffffb58bc (gdb) p/x Mul.pVal[1] $35 = 0x27d (gdb) print Mul.isNegative() $36 = false So yeah, the code isn't going to work if APInt doesn't handle signed multiply correctly. Who's the APInt master these days? -Dave From clattner at apple.com Wed May 6 11:41:45 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 6 May 2009 09:41:45 -0700 Subject: [llvm-commits] [llvm-testresults] buildbot failure in The LLVM Compiler Infrastructure on full-llvm-OSX In-Reply-To: <200905061101.59051.dag@cray.com> References: <20090505203815.0C25128050@relay13.apple.com> <200905061101.59051.dag@cray.com> Message-ID: <5954BE0B-D5DE-4A8D-A018-DF80F99534B3@apple.com> On May 6, 2009, at 9:01 AM, David Greene wrote: > > So yeah, the code isn't going to work if APInt doesn't handle signed > multiply > correctly. Who's the APInt master these days? Reid wrote most of APInt, but he's not active anymore. -Chris From gohman at apple.com Wed May 6 11:55:52 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 6 May 2009 09:55:52 -0700 Subject: [llvm-commits] [llvm-testresults] buildbot failure in The LLVM Compiler Infrastructure on full-llvm-OSX In-Reply-To: <200905061101.59051.dag@cray.com> References: <20090505203815.0C25128050@relay13.apple.com> <200905061101.59051.dag@cray.com> Message-ID: On May 6, 2009, at 9:01 AM, David Greene wrote: > On Tuesday 05 May 2009 15:44, Bill Wendling wrote: >> David, >> >> Your recent check-in r71008 is causing this failure. Please >> investigate: >> >> Running /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ >> CodeGen/X86/dg.exp ... >> FAIL: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ >> CodeGen/X86/change-compare-stride-1.ll >> Failed with exit(1) at line 2 >> while running: grep {cmpq $-478,} change-compare-stride-1.ll.tmp >> child process exited abnormally > > This seems to be a bug in APInt. From LoopStrengthReduce.cpp: > > Scale = SSInt / CmpSSInt; > int64_t NewCmpVal = CmpVal * Scale; > APInt Mul = APInt(BitWidth*2, CmpVal); > Mul = Mul * APInt(BitWidth*2, Scale); > > // Check for overflow. > if (!Mul.isSignedIntN(BitWidth)) > > (gdb) print SSInt > $30 = -478 > (gdb) print CmpSSInt > $31 = 1 > (gdb) print NewCmpVal > $32 = -304964 > (gdb) p/x Mul.pVal[0] > $34 = 0xfffffffffffb58bc > (gdb) p/x Mul.pVal[1] > $35 = 0x27d > (gdb) print Mul.isNegative() > $36 = false APInt's constructor has a third argument, which is a boolean specifying whether the uint64_t argument should be sign-extended out to the specified bit width. It defaults to false, so the values here are being zero-extended out to 128 bits before the multiply. It looks like true should be passed here, in order to get a full signed multiply. Dan From gohman at apple.com Wed May 6 12:12:50 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 06 May 2009 17:12:50 -0000 Subject: [llvm-commits] [llvm] r71087 - /llvm/trunk/include/llvm/Support/ValueHandle.h Message-ID: <200905061712.n46HCoDq032031@zion.cs.uiuc.edu> Author: djg Date: Wed May 6 12:12:48 2009 New Revision: 71087 URL: http://llvm.org/viewvc/llvm-project?rev=71087&view=rev Log: Add simplify_type specializations to allow WeakVH, AssertingVH, and CallbackVH to participate in dyn_cast, isa, etc. without needing an explicit conversion. Modified: llvm/trunk/include/llvm/Support/ValueHandle.h Modified: llvm/trunk/include/llvm/Support/ValueHandle.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ValueHandle.h?rev=71087&r1=71086&r2=71087&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/ValueHandle.h (original) +++ llvm/trunk/include/llvm/Support/ValueHandle.h Wed May 6 12:12:48 2009 @@ -126,8 +126,19 @@ operator Value*() const { return getValPtr(); } -}; - +}; + +// Specialize simplify_type to allow WeakVH to participate in +// dyn_cast, isa, etc. +template struct simplify_type; +template<> struct simplify_type { + typedef Value* SimpleType; + static SimpleType getSimplifiedValue(const WeakVH &WVH) { + return static_cast(WVH); + } +}; +template<> struct simplify_type : public simplify_type {}; + /// AssertingVH - This is a Value Handle that points to a value and asserts out /// if the value is destroyed while the handle is still live. This is very /// useful for catching dangling pointer bugs and other things which can be @@ -188,6 +199,18 @@ ValueTy &operator*() const { return *getValPtr(); } }; +// Specialize simplify_type to allow AssertingVH to participate in +// dyn_cast, isa, etc. +template struct simplify_type; +template<> struct simplify_type > { + typedef Value* SimpleType; + static SimpleType getSimplifiedValue(const AssertingVH &AVH) { + return static_cast(AVH); + } +}; +template<> struct simplify_type > + : public simplify_type > {}; + /// CallbackVH - This is a value handle that allows subclasses to define /// callbacks that run when the underlying Value has RAUW called on it or is /// destroyed. This class can be used as the key of a map, as long as the user @@ -232,6 +255,18 @@ virtual void allUsesReplacedWith(Value *new_value) {} }; +// Specialize simplify_type to allow CallbackVH to participate in +// dyn_cast, isa, etc. +template struct simplify_type; +template<> struct simplify_type { + typedef Value* SimpleType; + static SimpleType getSimplifiedValue(const CallbackVH &CVH) { + return static_cast(CVH); + } +}; +template<> struct simplify_type + : public simplify_type {}; + } // End llvm namespace #endif From gohman at apple.com Wed May 6 12:22:41 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 06 May 2009 17:22:41 -0000 Subject: [llvm-commits] [llvm] r71089 - in /llvm/trunk/lib/Transforms/Utils: CloneLoop.cpp Local.cpp PromoteMemoryToRegister.cpp SimplifyCFG.cpp Message-ID: <200905061722.n46HMg35032470@zion.cs.uiuc.edu> Author: djg Date: Wed May 6 12:22:41 2009 New Revision: 71089 URL: http://llvm.org/viewvc/llvm-project?rev=71089&view=rev Log: Simplify code by using SmallVector's pop_back_val() instead of separate back() and pop_back() calls. Modified: llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Modified: llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp?rev=71089&r1=71088&r2=71089&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp Wed May 6 12:22:41 2009 @@ -92,8 +92,7 @@ Loop *NewParentLoop = NULL; while (!LoopNest.empty()) { - Loop *L = LoopNest.back(); - LoopNest.pop_back(); + Loop *L = LoopNest.pop_back_val(); Loop *NewLoop = new Loop(); if (!NewParentLoop) Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=71089&r1=71088&r2=71089&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Wed May 6 12:22:41 2009 @@ -188,8 +188,7 @@ DeadInsts.push_back(I); while (!DeadInsts.empty()) { - I = DeadInsts.back(); - DeadInsts.pop_back(); + I = DeadInsts.pop_back_val(); // Null out all of the instruction's operands to see if any operand becomes // dead as we go. Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=71089&r1=71088&r2=71089&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Wed May 6 12:22:41 2009 @@ -616,8 +616,7 @@ // Now that we have a set of blocks where the phi is live-in, recursively add // their predecessors until we find the full region the value is live. while (!LiveInBlockWorklist.empty()) { - BasicBlock *BB = LiveInBlockWorklist.back(); - LiveInBlockWorklist.pop_back(); + BasicBlock *BB = LiveInBlockWorklist.pop_back_val(); // The block really is live in here, insert it into the set. If already in // the set, then it has already been processed. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=71089&r1=71088&r2=71089&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Wed May 6 12:22:41 2009 @@ -742,8 +742,7 @@ SmallVector Preds(pred_begin(BB), pred_end(BB)); while (!Preds.empty()) { - BasicBlock *Pred = Preds.back(); - Preds.pop_back(); + BasicBlock *Pred = Preds.pop_back_val(); // See if the predecessor is a comparison with the same value. TerminatorInst *PTI = Pred->getTerminator(); @@ -1805,10 +1804,9 @@ // If we found some, do the transformation! if (!UncondBranchPreds.empty()) { while (!UncondBranchPreds.empty()) { - BasicBlock *Pred = UncondBranchPreds.back(); + BasicBlock *Pred = UncondBranchPreds.pop_back_val(); DOUT << "FOLDING: " << *BB << "INTO UNCOND BRANCH PRED: " << *Pred; - UncondBranchPreds.pop_back(); Instruction *UncondBranch = Pred->getTerminator(); // Clone the return and add it to the end of the predecessor. Instruction *NewRet = RI->clone(); @@ -1847,8 +1845,7 @@ // instruction. If any of them just select between returns, change the // branch itself into a select/return pair. while (!CondBranchPreds.empty()) { - BranchInst *BI = CondBranchPreds.back(); - CondBranchPreds.pop_back(); + BranchInst *BI = CondBranchPreds.pop_back_val(); // Check to see if the non-BB successor is also a return block. if (isa(BI->getSuccessor(0)->getTerminator()) && From dag at cray.com Wed May 6 12:30:28 2009 From: dag at cray.com (David Greene) Date: Wed, 6 May 2009 12:30:28 -0500 Subject: [llvm-commits] [llvm-testresults] buildbot failure in The LLVM Compiler Infrastructure on full-llvm-OSX In-Reply-To: References: <20090505203815.0C25128050@relay13.apple.com> <200905061101.59051.dag@cray.com> Message-ID: <200905061230.29251.dag@cray.com> On Wednesday 06 May 2009 11:55, Dan Gohman wrote: > APInt's constructor has a third argument, which is a boolean > specifying whether the uint64_t argument should be sign-extended > out to the specified bit width. It defaults to false, so the > values here are being zero-extended out to 128 bits before > the multiply. It looks like true should be passed here, in > order to get a full signed multiply. Ah, ok. I'm on it. -Dave From dag at cray.com Wed May 6 12:37:54 2009 From: dag at cray.com (David Greene) Date: Wed, 6 May 2009 12:37:54 -0500 Subject: [llvm-commits] [llvm] r71013 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll In-Reply-To: <200905052050.n45KojDJ010074@zion.cs.uiuc.edu> References: <200905052050.n45KojDJ010074@zion.cs.uiuc.edu> Message-ID: <200905061237.54748.dag@cray.com> On Tuesday 05 May 2009 15:50, Bill Wendling wrote: > Author: void > Date: Tue May 5 15:49:46 2009 > New Revision: 71013 > > URL: http://llvm.org/viewvc/llvm-project?rev=71013&view=rev > Log: > Temporarily reverting r71008. It was causing this failure: > > Running /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ > CodeGen/X86/dg.exp ... > FAIL: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ > CodeGen/X86/change-compare-stride-1.ll > Failed with exit(1) at line 2 > while running: grep {cmpq $-478,} change-compare-stride-1.ll.tmp > child process exited abnormally Hmm...Can't we at least give folks a chance to fix things first? Doing this 5 minutes after sending a notice to the commits list seems a bit excessive. Now I have to deal with a conflict and reconstruct my solution. This one isn't too bad but a larger patch would have been a nightmare. -Dave From greened at obbligato.org Wed May 6 12:39:54 2009 From: greened at obbligato.org (David Greene) Date: Wed, 06 May 2009 17:39:54 -0000 Subject: [llvm-commits] [llvm] r71090 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200905061739.n46HdtsP000625@zion.cs.uiuc.edu> Author: greened Date: Wed May 6 12:39:26 2009 New Revision: 71090 URL: http://llvm.org/viewvc/llvm-project?rev=71090&view=rev Log: Make sure to use signed arithmetic in APInt to fix a regression. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=71090&r1=71089&r2=71090&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Wed May 6 12:39:26 2009 @@ -2027,9 +2027,10 @@ Scale = SSInt / CmpSSInt; int64_t NewCmpVal = CmpVal * Scale; - APInt Mul = APInt(BitWidth, NewCmpVal); + APInt Mul = APInt(BitWidth*2, CmpVal, true); + Mul = Mul * APInt(BitWidth*2, Scale, true); // Check for overflow. - if (Mul.getSExtValue() != NewCmpVal) + if (!Mul.isSignedIntN(BitWidth)) { continue; // Watch out for overflow. From evan.cheng at apple.com Wed May 6 13:01:15 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 06 May 2009 18:01:15 -0000 Subject: [llvm-commits] [llvm] r71091 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200905061801.n46I1KlV001461@zion.cs.uiuc.edu> Author: evancheng Date: Wed May 6 13:00:56 2009 New Revision: 71091 URL: http://llvm.org/viewvc/llvm-project?rev=71091&view=rev Log: Unbreak the build. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=71091&r1=71090&r2=71091&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Wed May 6 13:00:56 2009 @@ -2030,7 +2030,7 @@ APInt Mul = APInt(BitWidth*2, CmpVal, true); Mul = Mul * APInt(BitWidth*2, Scale, true); // Check for overflow. - if (!Mul.isSignedIntN(BitWidth)) { + if (!Mul.isSignedIntN(BitWidth)) continue; // Watch out for overflow. From evan.cheng at apple.com Wed May 6 13:25:02 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 06 May 2009 18:25:02 -0000 Subject: [llvm-commits] [llvm] r71098 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/ARM/2009-05-05-DAGCombineBug.ll Message-ID: <200905061825.n46IP26x002227@zion.cs.uiuc.edu> Author: evancheng Date: Wed May 6 13:25:01 2009 New Revision: 71098 URL: http://llvm.org/viewvc/llvm-project?rev=71098&view=rev Log: Do not use register as base ptr of pre- and post- inc/dec load / store nodes. Added: llvm/trunk/test/CodeGen/ARM/2009-05-05-DAGCombineBug.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=71098&r1=71097&r2=71098&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed May 6 13:25:01 2009 @@ -4536,7 +4536,7 @@ // Check #1. Preinc'ing a frame index would require copying the stack pointer // (plus the implicit offset) to a register to preinc anyway. - if (isa(BasePtr)) + if (isa(BasePtr) || isa(BasePtr)) return false; // Check #2. @@ -4663,6 +4663,9 @@ // nor a successor of N. Otherwise, if Op is folded that would // create a cycle. + if (isa(BasePtr) || isa(BasePtr)) + continue; + // Check for #1. bool TryNext = false; for (SDNode::use_iterator II = BasePtr.getNode()->use_begin(), Added: llvm/trunk/test/CodeGen/ARM/2009-05-05-DAGCombineBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-05-05-DAGCombineBug.ll?rev=71098&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2009-05-05-DAGCombineBug.ll (added) +++ llvm/trunk/test/CodeGen/ARM/2009-05-05-DAGCombineBug.ll Wed May 6 13:25:01 2009 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc -mtriple=arm-linuxeabi-unknown-gnu -mattr=+v6 +; PR4166 + + %"byte[]" = type { i32, i8* } + %tango.time.Time.Time = type { i64 } + +define fastcc void @t() { +entry: + %tmp28 = call fastcc i1 null(i32* null, %"byte[]" undef, %"byte[]" undef, %tango.time.Time.Time* byval null) ; [#uses=0] + ret void +} From isanbard at gmail.com Wed May 6 13:25:59 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 6 May 2009 11:25:59 -0700 Subject: [llvm-commits] [llvm] r71013 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll In-Reply-To: <200905061237.54748.dag@cray.com> References: <200905052050.n45KojDJ010074@zion.cs.uiuc.edu> <200905061237.54748.dag@cray.com> Message-ID: <16e5fdf90905061125r71324f35r5bbf51a4eaa4d51f@mail.gmail.com> On Wed, May 6, 2009 at 10:37 AM, David Greene wrote: > On Tuesday 05 May 2009 15:50, Bill Wendling wrote: >> Author: void >> Date: Tue May ?5 15:49:46 2009 >> New Revision: 71013 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=71013&view=rev >> Log: >> Temporarily reverting r71008. It was causing this failure: >> >> Running /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ >> CodeGen/X86/dg.exp ... >> FAIL: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ >> CodeGen/X86/change-compare-stride-1.ll >> Failed with exit(1) at line 2 >> while running: grep {cmpq ? ? ? $-478,} change-compare-stride-1.ll.tmp >> child process exited abnormally > > Hmm...Can't we at least give folks a chance to fix things first? > Doing this 5 minutes after sending a notice to the commits list seems > a bit excessive. > > Now I have to deal with a conflict and reconstruct my solution. ?This > one isn't too bad but a larger patch would have been a nightmare. > It could be avoided if you ran "make check" in release mode before submitting your patch. -bw From isanbard at gmail.com Wed May 6 13:27:00 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 6 May 2009 11:27:00 -0700 Subject: [llvm-commits] [llvm] r71013 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll In-Reply-To: <200905061237.54748.dag@cray.com> References: <200905052050.n45KojDJ010074@zion.cs.uiuc.edu> <200905061237.54748.dag@cray.com> Message-ID: <16e5fdf90905061127y367417e0v44346f73b9036c94@mail.gmail.com> On Wed, May 6, 2009 at 10:37 AM, David Greene wrote: > On Tuesday 05 May 2009 15:50, Bill Wendling wrote: >> Author: void >> Date: Tue May ?5 15:49:46 2009 >> New Revision: 71013 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=71013&view=rev >> Log: >> Temporarily reverting r71008. It was causing this failure: >> >> Running /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ >> CodeGen/X86/dg.exp ... >> FAIL: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ >> CodeGen/X86/change-compare-stride-1.ll >> Failed with exit(1) at line 2 >> while running: grep {cmpq ? ? ? $-478,} change-compare-stride-1.ll.tmp >> child process exited abnormally > > Hmm...Can't we at least give folks a chance to fix things first? > Doing this 5 minutes after sending a notice to the commits list seems > a bit excessive. > > Now I have to deal with a conflict and reconstruct my solution. ?This > one isn't too bad but a larger patch would have been a nightmare. > Also, the fact that you got to it about a day afterwards doesn't bode well for fixing it quickly. I don't like having bad patches in our tree. As it is, there's a bad patch in there that's been failing for >1 day now that I have to find and remove. -bw From clattner at apple.com Wed May 6 13:30:06 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 6 May 2009 11:30:06 -0700 Subject: [llvm-commits] [llvm] r71013 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll In-Reply-To: <200905061237.54748.dag@cray.com> References: <200905052050.n45KojDJ010074@zion.cs.uiuc.edu> <200905061237.54748.dag@cray.com> Message-ID: <01762C4C-E17A-4C8A-B7E9-58DC1CF07252@apple.com> On May 6, 2009, at 10:37 AM, David Greene wrote: >> while running: grep {cmpq $-478,} change-compare- >> stride-1.ll.tmp >> child process exited abnormally > > Hmm...Can't we at least give folks a chance to fix things first? > Doing this 5 minutes after sending a notice to the commits list seems > a bit excessive. Having a patch be reverted should not be seen as a negative thing. There are many people pulling from mainline svn: if there is a problem with a patch, I think it makes sense to revert it immediately. However, I disagree with Bill that "testing would have fixed this". There is no reasonable way to test every configuration before committing the code, and most patches don't have issues. The flip side of this is that we should aggressively revert patches that *are* found to have minor issues. -Chris From kremenek at apple.com Wed May 6 13:56:14 2009 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 06 May 2009 18:56:14 -0000 Subject: [llvm-commits] [llvm] r71101 - /llvm/tags/checker/checker-0.196/ Message-ID: <200905061856.n46IuGwf003311@zion.cs.uiuc.edu> Author: kremenek Date: Wed May 6 13:55:58 2009 New Revision: 71101 URL: http://llvm.org/viewvc/llvm-project?rev=71101&view=rev Log: Tagging checker-0.196. Added: llvm/tags/checker/checker-0.196/ - copied from r71100, llvm/trunk/ From sabre at nondot.org Wed May 6 13:56:27 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 06 May 2009 18:56:27 -0000 Subject: [llvm-commits] [test-suite] r71103 - /test-suite/trunk/SingleSource/UnitTests/2009-04-16-BitfieldInitialization.c Message-ID: <200905061856.n46IuSkC003346@zion.cs.uiuc.edu> Author: lattner Date: Wed May 6 13:56:27 2009 New Revision: 71103 URL: http://llvm.org/viewvc/llvm-project?rev=71103&view=rev Log: add testcase for rdar://6861719 Modified: test-suite/trunk/SingleSource/UnitTests/2009-04-16-BitfieldInitialization.c Modified: test-suite/trunk/SingleSource/UnitTests/2009-04-16-BitfieldInitialization.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/2009-04-16-BitfieldInitialization.c?rev=71103&r1=71102&r2=71103&view=diff ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/2009-04-16-BitfieldInitialization.c (original) +++ test-suite/trunk/SingleSource/UnitTests/2009-04-16-BitfieldInitialization.c Wed May 6 13:56:27 2009 @@ -72,6 +72,21 @@ int c : 16; } t9 = { 0, 123, 456 }; +// rdar://6861719 +#pragma pack(4) + +struct t10s { + short a; + int *b; +}; + +#pragma pack() + +int x = 42; +struct t10s t10 = { +.b = &x +}; + #include @@ -88,5 +103,6 @@ printf("7a: %d %d %d\n", t7a.x, t7a.y, t7a.q); printf("8: %d %d\n", t8.what, t8.type); printf("9: %d %d\n", t9.b, t9.c); + printf("10: %d\n", *t10.b); return 0; } From sabre at nondot.org Wed May 6 13:58:17 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 06 May 2009 18:58:17 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r71105 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200905061858.n46IwHZ5003441@zion.cs.uiuc.edu> Author: lattner Date: Wed May 6 13:58:16 2009 New Revision: 71105 URL: http://llvm.org/viewvc/llvm-project?rev=71105&view=rev Log: consider a packed C struct of {int, void*} on a 64-bit target. If we have a designated init for the pointer, then the code will insert explicit padding to pad up to byte 4 (where the pointer starts). After doing that, we then have to convert the llvm struct to a packed struct in order to get the pointer to start at byte 4 instead of byte 8. This changes the code to handle this case by recursing after inserting explicit padding. This fixes rdar://6861719 and UnitTests/2009-04-16-BitfieldInitialization.c:t10 Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=71105&r1=71104&r2=71105&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed May 6 13:58:16 2009 @@ -6834,6 +6834,7 @@ /// struct constant, change it to make all the implicit padding between elements /// be fully explicit. void ConstantLayoutInfo::ConvertToPacked() { + assert(!StructIsPacked && "Struct is already packed"); uint64_t EltOffs = 0; for (unsigned i = 0, e = ResultElts.size(); i != e; ++i) { Constant *Val = ResultElts[i]; @@ -6921,10 +6922,11 @@ if (LLVMNaturalByteOffset*8 > GCCFieldOffsetInBits) { // Switch to packed. ConvertToPacked(); - LLVMNaturalByteOffset = NextFieldByteStart; - ValLLVMAlign = 1; - assert(LLVMNaturalByteOffset*8 <= GCCFieldOffsetInBits && + assert(NextFieldByteStart*8 <= GCCFieldOffsetInBits && "Packing didn't fix the problem!"); + + // Recurse to add the field after converting to packed. + return AddFieldToRecordConstant(Val, GCCFieldOffsetInBits); } // If the LLVM offset is not large enough, we need to insert explicit @@ -6940,8 +6942,10 @@ ResultElts.push_back(Constant::getNullValue(FillTy)); NextFieldByteStart = GCCFieldOffsetInBits/8; - LLVMNaturalByteOffset - = TargetData::RoundUpAlignment(NextFieldByteStart, ValLLVMAlign); + + // Recurse to add the field. This handles the case when the LLVM struct + // needs to be converted to packed after inserting tail padding. + return AddFieldToRecordConstant(Val, GCCFieldOffsetInBits); } // Slap 'Val' onto the end of our ConstantStruct, it must be known to land From dalej at apple.com Wed May 6 14:04:47 2009 From: dalej at apple.com (Dale Johannesen) Date: Wed, 06 May 2009 19:04:47 -0000 Subject: [llvm-commits] [llvm] r71106 - /llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Message-ID: <200905061904.n46J4p2B003797@zion.cs.uiuc.edu> Author: johannes Date: Wed May 6 14:04:30 2009 New Revision: 71106 URL: http://llvm.org/viewvc/llvm-project?rev=71106&view=rev Log: Use X86AddrNumOperands instead of magic constant one more place. This fixes a bunch of x86-64 JIT regressions. (Introduced when the value of the magic constant changed in 68645. At the time apparently nobody noticed; failures were hidden in 70343-70439 by an unrelated bug, so showed up again as "new" failures in 70440.) Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=71106&r1=71105&r2=71106&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Wed May 6 14:04:30 2009 @@ -709,7 +709,8 @@ case X86II::MRM4m: case X86II::MRM5m: case X86II::MRM6m: case X86II::MRM7m: { intptr_t PCAdj = (CurOp + X86AddrNumOperands != NumOps) ? - (MI.getOperand(CurOp+4).isImm() ? X86InstrInfo::sizeOfImm(Desc) : 4) : 0; + (MI.getOperand(CurOp+X86AddrNumOperands).isImm() ? + X86InstrInfo::sizeOfImm(Desc) : 4) : 0; MCE.emitByte(BaseOpcode); emitMemModRMByte(MI, CurOp, (Desc->TSFlags & X86II::FormMask)-X86II::MRM0m, From greened at obbligato.org Wed May 6 14:42:07 2009 From: greened at obbligato.org (David A. Greene) Date: Wed, 6 May 2009 14:42:07 -0500 Subject: [llvm-commits] [llvm] r71013 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll In-Reply-To: <16e5fdf90905061125r71324f35r5bbf51a4eaa4d51f@mail.gmail.com> References: <200905052050.n45KojDJ010074@zion.cs.uiuc.edu> <200905061237.54748.dag@cray.com> <16e5fdf90905061125r71324f35r5bbf51a4eaa4d51f@mail.gmail.com> Message-ID: <200905061442.08425.greened@obbligato.org> On Wednesday 06 May 2009 13:25, Bill Wendling wrote: > > Now I have to deal with a conflict and reconstruct my solution. ?This > > one isn't too bad but a larger patch would have been a nightmare. > > It could be avoided if you ran "make check" in release mode before > submitting your patch. Which I did. I missed the failure among the noise of all the other failures. As for the time to respond, you have to consider that we all have work meetings, etc. during the day and we won't necessarily get to it until the next day. And finally, if a patch is reverted, it would be a good idea to send a personal e-mail. It's sometimes hard to wade through all of llvm-commits looking for a revert that might or might not be there. It's a process issue. We can always improve processes. -Dave From dag at cray.com Wed May 6 14:45:34 2009 From: dag at cray.com (David Greene) Date: Wed, 6 May 2009 14:45:34 -0500 Subject: [llvm-commits] [llvm] r71013 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll In-Reply-To: <01762C4C-E17A-4C8A-B7E9-58DC1CF07252@apple.com> References: <200905052050.n45KojDJ010074@zion.cs.uiuc.edu> <200905061237.54748.dag@cray.com> <01762C4C-E17A-4C8A-B7E9-58DC1CF07252@apple.com> Message-ID: <200905061445.35286.dag@cray.com> On Wednesday 06 May 2009 13:30, Chris Lattner wrote: > Having a patch be reverted should not be seen as a negative thing. It's not a negative thing as in, "I'm taking this personally." It IS a negative thing in terms of time-to-fix. Dealing with conflicts, etc. just means we take more time to fix problems. > There are many people pulling from mainline svn: if there is a problem > with a patch, I think it makes sense to revert it immediately. I really disagree with this. If someone isn't responding for days, sure, but reverting a patch means that when I update I lose some functionality I thought would be there. Things start failing that I don't expect to fail, etc. I then end up tracking down a bug I've already tracked down before. A simple personal e-mail asking for a fix should be sufficient. -Dave From isanbard at gmail.com Wed May 6 15:04:03 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 6 May 2009 13:04:03 -0700 Subject: [llvm-commits] [llvm] r71013 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll In-Reply-To: <200905061442.08425.greened@obbligato.org> References: <200905052050.n45KojDJ010074@zion.cs.uiuc.edu> <200905061237.54748.dag@cray.com> <16e5fdf90905061125r71324f35r5bbf51a4eaa4d51f@mail.gmail.com> <200905061442.08425.greened@obbligato.org> Message-ID: <16e5fdf90905061304ibfacde5gc28bae59b7ec18a7@mail.gmail.com> On Wed, May 6, 2009 at 12:42 PM, David A. Greene wrote: > Which I did. ?I missed the failure among the noise of all the other failures. > > As for the time to respond, you have to consider that we all have work > meetings, etc. during the day and we won't necessarily get to it until > the next day. > > And finally, if a patch is reverted, it would be a good idea to send a > personal e-mail. ?It's sometimes hard to wade through all of llvm-commits > looking for a revert that might or might not be there. > > It's a process issue. ?We can always improve processes. > If you can't address a pulled revision, then just reapply that to a source tree, work on the fix, then recommit it to the repository. There shouldn't be a problem here. I do this all of the time to everyone, including Chris, my manager Evan, me . . . everyone. I have a zero-tolerance policy in place because it's crucial for us to keep the tree healthy. (In reality, it's not *exactly* zero, if I have access to the person and it's obvious that it's a minor problem, then I'll ping them.) -bw From isanbard at gmail.com Wed May 6 15:05:58 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 6 May 2009 13:05:58 -0700 Subject: [llvm-commits] [llvm] r71013 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll In-Reply-To: <200905061445.35286.dag@cray.com> References: <200905052050.n45KojDJ010074@zion.cs.uiuc.edu> <200905061237.54748.dag@cray.com> <01762C4C-E17A-4C8A-B7E9-58DC1CF07252@apple.com> <200905061445.35286.dag@cray.com> Message-ID: <16e5fdf90905061305n5d0cd193t269cf01a9c6e36dc@mail.gmail.com> On Wed, May 6, 2009 at 12:45 PM, David Greene wrote: > On Wednesday 06 May 2009 13:30, Chris Lattner wrote: > >> Having a patch be reverted should not be seen as a negative thing. > > It's not a negative thing as in, "I'm taking this personally." ?It IS > a negative thing in terms of time-to-fix. ?Dealing with conflicts, > etc. just means we take more time to fix problems. > >> There are many people pulling from mainline svn: if there is a problem >> with a patch, I think it makes sense to revert it immediately. > > I really disagree with this. ?If someone isn't responding for days, sure, > but reverting a patch means that when I update I lose some functionality > I thought would be there. ?Things start failing that I don't expect to > fail, etc. ?I then end up tracking down a bug I've already tracked down > before. > > A simple personal e-mail asking for a fix should be sufficient. > I normally send out an email saying that something failed and that I reverted the patch. I apologize if you didn't get it or it got rerouted. -bw From dalej at apple.com Wed May 6 15:22:35 2009 From: dalej at apple.com (Dale Johannesen) Date: Wed, 6 May 2009 13:22:35 -0700 Subject: [llvm-commits] [llvm] r71013 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll In-Reply-To: <200905061237.54748.dag@cray.com> References: <200905052050.n45KojDJ010074@zion.cs.uiuc.edu> <200905061237.54748.dag@cray.com> Message-ID: <10259AEB-CB87-4D10-A9B4-67DA8464F23E@apple.com> On May 6, 2009, at 10:37 AMPDT, David Greene wrote: > On Tuesday 05 May 2009 15:50, Bill Wendling wrote: >> Author: void >> Date: Tue May 5 15:49:46 2009 >> New Revision: 71013 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=71013&view=rev >> Log: >> Temporarily reverting r71008. It was causing this failure: >> >> Running /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ >> CodeGen/X86/dg.exp ... >> FAIL: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/ >> CodeGen/X86/change-compare-stride-1.ll >> Failed with exit(1) at line 2 >> while running: grep {cmpq $-478,} change-compare- >> stride-1.ll.tmp >> child process exited abnormally > > Hmm...Can't we at least give folks a chance to fix things first? > Doing this 5 minutes after sending a notice to the commits list seems > a bit excessive. > > Now I have to deal with a conflict and reconstruct my solution. This > one isn't too bad but a larger patch would have been a nightmare. svn diff -r is a big help. Normally you don't need to reconstruct anything. Leaving a buggy patch in the tree, especially one that breaks the buildbots, affects everybody. Reverting it affects the person who put it there. Seems pretty simple. From ofv at wanadoo.es Wed May 6 15:40:05 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Wed, 06 May 2009 20:40:05 -0000 Subject: [llvm-commits] [llvm] r71115 - /llvm/trunk/lib/Target/PIC16/CMakeLists.txt Message-ID: <200905062040.n46Ke5Cd007052@zion.cs.uiuc.edu> Author: ofv Date: Wed May 6 15:40:05 2009 New Revision: 71115 URL: http://llvm.org/viewvc/llvm-project?rev=71115&view=rev Log: CMake: Updated lib/Target/PIC16/CMakeLists.txt. Modified: llvm/trunk/lib/Target/PIC16/CMakeLists.txt Modified: llvm/trunk/lib/Target/PIC16/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/CMakeLists.txt?rev=71115&r1=71114&r2=71115&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/CMakeLists.txt (original) +++ llvm/trunk/lib/Target/PIC16/CMakeLists.txt Wed May 6 15:40:05 2009 @@ -15,6 +15,7 @@ PIC16InstrInfo.cpp PIC16ISelDAGToDAG.cpp PIC16ISelLowering.cpp + PIC16MemSelOpt.cpp PIC16RegisterInfo.cpp PIC16Subtarget.cpp PIC16TargetAsmInfo.cpp From ofv at wanadoo.es Wed May 6 15:42:04 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Wed, 06 May 2009 20:42:04 -0000 Subject: [llvm-commits] [llvm] r71116 - /llvm/trunk/cmake/modules/AddLLVM.cmake Message-ID: <200905062042.n46Kg4Fv007109@zion.cs.uiuc.edu> Author: ofv Date: Wed May 6 15:42:04 2009 New Revision: 71116 URL: http://llvm.org/viewvc/llvm-project?rev=71116&view=rev Log: CMake: Use pthread library when requested and available. Modified: llvm/trunk/cmake/modules/AddLLVM.cmake Modified: llvm/trunk/cmake/modules/AddLLVM.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/AddLLVM.cmake?rev=71116&r1=71115&r2=71116&view=diff ============================================================================== --- llvm/trunk/cmake/modules/AddLLVM.cmake (original) +++ llvm/trunk/cmake/modules/AddLLVM.cmake Wed May 6 15:42:04 2009 @@ -34,6 +34,9 @@ target_link_libraries(${name} imagehlp psapi) elseif( CMAKE_HOST_UNIX ) target_link_libraries(${name} dl) + if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD ) + target_link_libraries(${name} pthread) + endif() endif( MINGW ) endif( MSVC ) endmacro(add_llvm_executable name) From isanbard at gmail.com Wed May 6 16:21:34 2009 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 06 May 2009 21:21:34 -0000 Subject: [llvm-commits] [llvm] r71118 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Message-ID: <200905062121.n46LLZNh008451@zion.cs.uiuc.edu> Author: void Date: Wed May 6 16:21:34 2009 New Revision: 71118 URL: http://llvm.org/viewvc/llvm-project?rev=71118&view=rev Log: - Move some debug fields to coincide with how GCC emits them. No functionality change. - Reformatting. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=71118&r1=71117&r2=71118&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Wed May 6 16:21:34 2009 @@ -1145,8 +1145,29 @@ virtual unsigned getLine() { assert ( 0 && "Unexpected scope!"); return 0; } virtual unsigned getColumn() { assert ( 0 && "Unexpected scope!"); return 0; } virtual unsigned getFile() { assert ( 0 && "Unexpected scope!"); return 0; } + +#ifndef NDEBUG + void dump() const; +#endif }; +#ifndef NDEBUG +void DbgScope::dump() const { + static unsigned IndentLevel = 0; + std::string Indent(IndentLevel, ' '); + + cerr << Indent; Desc.dump(); + cerr << " [" << StartLabelID << ", " << EndLabelID << "]\n"; + + IndentLevel += 2; + + for (unsigned i = 0, e = Scopes.size(); i != e; ++i) + if (Scopes[i] != this) + Scopes[i]->dump(); + + IndentLevel -= 2; +} +#endif //===----------------------------------------------------------------------===// /// DbgInlinedSubroutineScope - This class is used to track inlined subroutine @@ -1713,13 +1734,14 @@ break; case DW_TAG_subroutine_type: { - // Add prototype flag. - AddUInt(&Buffer, DW_AT_prototyped, DW_FORM_flag, 1); - DIArray Elements = CTy.getTypeArray(); // Add return type. + DIArray Elements = CTy.getTypeArray(); DIDescriptor RTy = Elements.getElement(0); AddType(DW_Unit, &Buffer, DIType(RTy.getGV())); + // Add prototype flag. + AddUInt(&Buffer, DW_AT_prototyped, DW_FORM_flag, 1); + // Add arguments. for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) { DIE *Arg = new DIE(DW_TAG_formal_parameter); @@ -1901,21 +1923,29 @@ /// CreateSubprogramDIE - Create new DIE using SP. DIE *CreateSubprogramDIE(CompileUnit *DW_Unit, - const DISubprogram &SP, + const DISubprogram &SP, bool IsConstructor = false) { DIE *SPDie = new DIE(DW_TAG_subprogram); + std::string Name; SP.getName(Name); AddString(SPDie, DW_AT_name, DW_FORM_string, Name); + std::string LinkageName; SP.getLinkageName(LinkageName); + if (!LinkageName.empty()) - AddString(SPDie, DW_AT_MIPS_linkage_name, DW_FORM_string, - LinkageName); + AddString(SPDie, DW_AT_MIPS_linkage_name, DW_FORM_string, LinkageName); + AddSourceLine(SPDie, &SP); DICompositeType SPTy = SP.getType(); DIArray Args = SPTy.getTypeArray(); + + // Add prototyped tag, if C or ObjC. + unsigned Lang = SP.getCompileUnit().getLanguage(); + if (Lang == DW_LANG_C99 || Lang == DW_LANG_C89 || Lang == DW_LANG_ObjC) + AddUInt(SPDie, DW_AT_prototyped, DW_FORM_flag, 1); // Add Return Type. unsigned SPTag = SPTy.getTag(); @@ -1928,26 +1958,20 @@ if (!SP.isDefinition()) { AddUInt(SPDie, DW_AT_declaration, DW_FORM_flag, 1); - // Add arguments. - // Do not add arguments for subprogram definition. They will be - // handled through RecordVariable. + // Add arguments. Do not add arguments for subprogram definition. They + // will be handled through RecordVariable. if (SPTag == DW_TAG_subroutine_type) for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { DIE *Arg = new DIE(DW_TAG_formal_parameter); AddType(DW_Unit, Arg, DIType(Args.getElement(i).getGV())); - AddUInt(Arg, DW_AT_artificial, DW_FORM_flag, 1); // ??? + AddUInt(Arg, DW_AT_artificial, DW_FORM_flag, 1); // ?? SPDie->AddChild(Arg); } } - unsigned Lang = SP.getCompileUnit().getLanguage(); - if (Lang == DW_LANG_C99 || Lang == DW_LANG_C89 - || Lang == DW_LANG_ObjC) - AddUInt(SPDie, DW_AT_prototyped, DW_FORM_flag, 1); - if (!SP.isLocalToUnit()) AddUInt(SPDie, DW_AT_external, DW_FORM_flag, 1); - + // DW_TAG_inlined_subroutine may refer to this DIE. DIE *&Slot = DW_Unit->getDieMapSlotFor(SP.getGV()); Slot = SPDie; @@ -2008,11 +2032,13 @@ DbgScope *Parent = NULL; DIBlock Block(V); + if (!Block.isNull()) { DIDescriptor ParentDesc = Block.getContext(); Parent = ParentDesc.isNull() ? NULL : getOrCreateScope(ParentDesc.getGV()); } + Slot = new DbgScope(Parent, DIDescriptor(V)); if (Parent) @@ -3007,8 +3033,10 @@ // Add to map. Slot = VariableDie; + // Add to context owner. DW_Unit->getDie()->AddChild(VariableDie); + // Expose as global. FIXME - need to check external flag. std::string Name; DW_Unit->AddGlobal(DI_GV.getName(Name), VariableDie); @@ -3033,10 +3061,9 @@ for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end(); UI != UE; ++UI) for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end(); - UUI != UUE; ++UUI) { - GlobalVariable *GV = cast(*UUI); - Result |= ConstructGlobalVariableDIE(GV); - } + UUI != UUE; ++UUI) + Result |= ConstructGlobalVariableDIE(cast(*UUI)); + return Result; } @@ -3085,10 +3112,9 @@ for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end(); UI != UE; ++UI) for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end(); - UUI != UUE; ++UUI) { - GlobalVariable *GV = cast(*UUI); - Result |= ConstructSubprogram(GV); - } + UUI != UUE; ++UUI) + Result |= ConstructSubprogram(cast(*UUI)); + return Result; } @@ -3441,6 +3467,7 @@ } else { DenseMap::iterator SI = InlinedVariableScopes.find(MI); + if (SI != InlinedVariableScopes.end()) { // or GV is an inlined local variable. Scope = SI->second; @@ -3506,6 +3533,7 @@ GlobalVariable *GV = SP.getGV(); DenseMap >::iterator I = DbgInlinedScopeMap.find(GV); + if (I == DbgInlinedScopeMap.end()) { if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -3517,6 +3545,7 @@ assert(!Scopes.empty() && "We should have at least one debug scope!"); DbgScope *Scope = Scopes.back(); Scopes.pop_back(); unsigned ID = MMI->NextLabelID(); + MMI->RecordUsedDbgLabel(ID); Scope->setEndLabelID(ID); From mrs at apple.com Wed May 6 16:36:17 2009 From: mrs at apple.com (Mike Stump) Date: Wed, 6 May 2009 14:36:17 -0700 Subject: [llvm-commits] [llvm] r71013 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2009-05-04-Overflow.ll In-Reply-To: <200905061442.08425.greened@obbligato.org> References: <200905052050.n45KojDJ010074@zion.cs.uiuc.edu> <200905061237.54748.dag@cray.com> <16e5fdf90905061125r71324f35r5bbf51a4eaa4d51f@mail.gmail.com> <200905061442.08425.greened@obbligato.org> Message-ID: <469AECF6-988B-42DD-9E24-695BE6D60755@apple.com> On May 6, 2009, at 12:42 PM, David A. Greene wrote: > Which I did. I missed the failure among the noise of all the other > failures. :-( For dejagnu style testsuite runs, use contrib/cmp_logs from gcc to compare output instead. You will discover it is much harder to ignore regressions. Also, this argues for maintaining clean results. On my platform, llvm and clang seem to maintain zero for my debug builds, and 2 failures for release-assert-x86 only. From gohman at apple.com Wed May 6 17:54:34 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 06 May 2009 22:54:34 -0000 Subject: [llvm-commits] [llvm] r71124 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200905062254.n46MsYDQ011336@zion.cs.uiuc.edu> Author: djg Date: Wed May 6 17:54:33 2009 New Revision: 71124 URL: http://llvm.org/viewvc/llvm-project?rev=71124&view=rev Log: Use stable_sort instead of plain sort to avoid the risk of generating trivially different code on different hosts (due to differing std::sort implementations). Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71124&r1=71123&r2=71124&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Wed May 6 17:54:33 2009 @@ -472,7 +472,7 @@ } // Do the rough sort by complexity. - std::sort(Ops.begin(), Ops.end(), SCEVComplexityCompare()); + std::stable_sort(Ops.begin(), Ops.end(), SCEVComplexityCompare()); // Now that we are sorted by complexity, group elements of the same // complexity. Note that this is, at worst, N^2, but the vector is likely to From akyrtzi at gmail.com Wed May 6 19:16:31 2009 From: akyrtzi at gmail.com (Argiris Kirtzidis) Date: Thu, 07 May 2009 00:16:31 -0000 Subject: [llvm-commits] [llvm] r71132 - in /llvm/trunk: include/llvm/CodeGen/DwarfWriter.h lib/CodeGen/AsmPrinter/DwarfWriter.cpp lib/CodeGen/SelectionDAG/FastISel.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200905070016.n470GVCO014800@zion.cs.uiuc.edu> Author: akirtzidis Date: Wed May 6 19:16:31 2009 New Revision: 71132 URL: http://llvm.org/viewvc/llvm-project?rev=71132&view=rev Log: Make DwarfWriter::RecordInlinedFnStart more like the other DwarfWriter's methods: -Have it return a label ID -Remove the unused Instruction parameter No functionality change. Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DwarfWriter.h?rev=71132&r1=71131&r2=71132&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/DwarfWriter.h (original) +++ llvm/trunk/include/llvm/CodeGen/DwarfWriter.h Wed May 6 19:16:31 2009 @@ -106,11 +106,11 @@ bool ShouldEmitDwarfDebug() const; //// RecordInlinedFnStart - Indicate the start of a inlined function. - void RecordInlinedFnStart(Instruction *I, DISubprogram &SP, unsigned LabelID, - DICompileUnit CU, unsigned Line, unsigned Col); + unsigned RecordInlinedFnStart(DISubprogram SP, DICompileUnit CU, + unsigned Line, unsigned Col); /// RecordInlinedFnEnd - Indicate the end of inlined subroutine. - unsigned RecordInlinedFnEnd(DISubprogram &SP); + unsigned RecordInlinedFnEnd(DISubprogram SP); /// RecordVariableScope - Record scope for the variable declared by /// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=71132&r1=71131&r2=71132&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Wed May 6 19:16:31 2009 @@ -3487,10 +3487,12 @@ } //// RecordInlinedFnStart - Indicate the start of inlined subroutine. - void RecordInlinedFnStart(Instruction *FSI, DISubprogram &SP, unsigned LabelID, - DICompileUnit CU, unsigned Line, unsigned Col) { + unsigned RecordInlinedFnStart(DISubprogram &SP, DICompileUnit CU, + unsigned Line, unsigned Col) { + unsigned LabelID = MMI->NextLabelID(); + if (!TAI->doesDwarfUsesInlineInfoSection()) - return; + return LabelID; if (TimePassesIsEnabled) DebugTimer->startTimer(); @@ -3520,6 +3522,8 @@ if (TimePassesIsEnabled) DebugTimer->stopTimer(); + + return LabelID; } /// RecordInlinedFnEnd - Indicate the end of inlined subroutine. @@ -4749,14 +4753,13 @@ //// RecordInlinedFnStart - Global variable GV is inlined at the location marked //// by LabelID label. -void DwarfWriter::RecordInlinedFnStart(Instruction *I, DISubprogram &SP, - unsigned LabelID, DICompileUnit CU, - unsigned Line, unsigned Col) { - DD->RecordInlinedFnStart(I, SP, LabelID, CU, Line, Col); +unsigned DwarfWriter::RecordInlinedFnStart(DISubprogram SP, DICompileUnit CU, + unsigned Line, unsigned Col) { + return DD->RecordInlinedFnStart(SP, CU, Line, Col); } /// RecordInlinedFnEnd - Indicate the end of inlined subroutine. -unsigned DwarfWriter::RecordInlinedFnEnd(DISubprogram &SP) { +unsigned DwarfWriter::RecordInlinedFnEnd(DISubprogram SP) { return DD->RecordInlinedFnEnd(SP); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=71132&r1=71131&r2=71132&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Wed May 6 19:16:31 2009 @@ -397,14 +397,13 @@ CompileUnit.getGV(), Line, 0))); if (DW && DW->ShouldEmitDwarfDebug()) { - unsigned LabelID = MMI->NextLabelID(); + DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); + unsigned LabelID = DW->RecordInlinedFnStart(Subprogram, + DICompileUnit(PrevLocTpl.CompileUnit), + PrevLocTpl.Line, + PrevLocTpl.Col); const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); BuildMI(MBB, DL, II).addImm(LabelID); - DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); - DW->RecordInlinedFnStart(FSI, Subprogram, LabelID, - DICompileUnit(PrevLocTpl.CompileUnit), - PrevLocTpl.Line, - PrevLocTpl.Col); } } else { // Record the source line. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=71132&r1=71131&r2=71132&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Wed May 6 19:16:31 2009 @@ -3981,14 +3981,13 @@ MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0))); if (DW && DW->ShouldEmitDwarfDebug()) { - unsigned LabelID = DAG.getMachineModuleInfo()->NextLabelID(); + DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); + unsigned LabelID = DW->RecordInlinedFnStart(Subprogram, + DICompileUnit(PrevLocTpl.CompileUnit), + PrevLocTpl.Line, + PrevLocTpl.Col); DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), getRoot(), LabelID)); - DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); - DW->RecordInlinedFnStart(&FSI, Subprogram, LabelID, - DICompileUnit(PrevLocTpl.CompileUnit), - PrevLocTpl.Line, - PrevLocTpl.Col); } } else { // Record the source line. From isanbard at gmail.com Wed May 6 20:27:26 2009 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 07 May 2009 01:27:26 -0000 Subject: [llvm-commits] [llvm] r71138 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/StackSlotColoring.cpp test/CodeGen/X86/2009-03-16-SpillerBug.ll test/CodeGen/X86/stack-color-with-reg.ll Message-ID: <200905070127.n471RQSb017114@zion.cs.uiuc.edu> Author: void Date: Wed May 6 20:27:25 2009 New Revision: 71138 URL: http://llvm.org/viewvc/llvm-project?rev=71138&view=rev Log: Temporarily revert r71010. It was causing massive failures during self-hosting. Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp llvm/trunk/lib/CodeGen/StackSlotColoring.cpp llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=71138&r1=71137&r2=71138&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed May 6 20:27:25 2009 @@ -191,7 +191,7 @@ FunctionPass *createMachineSinkingPass(); /// createStackSlotColoringPass - This pass performs stack slot coloring. - FunctionPass *createStackSlotColoringPass(bool); + FunctionPass *createStackSlotColoringPass(); /// createStackProtectorPass - This pass adds stack protectors to functions. FunctionPass *createStackProtectorPass(const TargetLowering *tli); Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=71138&r1=71137&r2=71138&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Wed May 6 20:27:25 2009 @@ -193,7 +193,7 @@ // Perform stack slot coloring. if (OptLevel != CodeGenOpt::None) - PM.add(createStackSlotColoringPass(OptLevel >= CodeGenOpt::Aggressive)); + PM.add(createStackSlotColoringPass()); if (PrintMachineCode) // Print the register-allocated code PM.add(createMachineFunctionPrinterPass(cerr)); Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=71138&r1=71137&r2=71138&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Wed May 6 20:27:25 2009 @@ -37,22 +37,21 @@ cl::desc("Suppress slot sharing during stack coloring")); static cl::opt -ColorWithRegsOpt("color-ss-with-regs", - cl::init(false), cl::Hidden, - cl::desc("Color stack slots with free registers")); +ColorWithRegs("color-ss-with-regs", + cl::init(false), cl::Hidden, + cl::desc("Color stack slots with free registers")); static cl::opt DCELimit("ssc-dce-limit", cl::init(-1), cl::Hidden); STATISTIC(NumEliminated, "Number of stack slots eliminated due to coloring"); STATISTIC(NumRegRepl, "Number of stack slot refs replaced with reg refs"); -STATISTIC(NumLoadElim, "Number of loads eliminated"); +STATISTIC(NumLoadElim, "Number of load eliminated"); STATISTIC(NumStoreElim, "Number of stores eliminated"); STATISTIC(NumDead, "Number of trivially dead stack accesses eliminated"); namespace { class VISIBILITY_HIDDEN StackSlotColoring : public MachineFunctionPass { - bool ColorWithRegs; LiveStacks* LS; VirtRegMap* VRM; MachineFrameInfo *MFI; @@ -90,10 +89,7 @@ public: static char ID; // Pass identification - StackSlotColoring() : - MachineFunctionPass(&ID), ColorWithRegs(false), NextColor(-1) {} - StackSlotColoring(bool RegColor) : - MachineFunctionPass(&ID), ColorWithRegs(RegColor), NextColor(-1) {} + StackSlotColoring() : MachineFunctionPass(&ID), NextColor(-1) {} virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -140,8 +136,8 @@ static RegisterPass X("stack-slot-coloring", "Stack Slot Coloring"); -FunctionPass *llvm::createStackSlotColoringPass(bool RegColor) { - return new StackSlotColoring(RegColor); +FunctionPass *llvm::createStackSlotColoringPass() { + return new StackSlotColoring(); } namespace { @@ -235,7 +231,7 @@ StackSlotColoring::ColorSlotsWithFreeRegs(SmallVector &SlotMapping, SmallVector, 16> &RevMap, BitVector &SlotIsReg) { - if (!(ColorWithRegs || ColorWithRegsOpt) || !VRM->HasUnusedRegisters()) + if (!ColorWithRegs || !VRM->HasUnusedRegisters()) return false; bool Changed = false; @@ -243,9 +239,7 @@ for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) { LiveInterval *li = SSIntervals[i]; int SS = li->getStackSlotIndex(); - if (!UsedColors[SS] || li->weight < 20) - // If the weight is < 20, i.e. two references in a loop with depth 1, - // don't bother with it. + if (!UsedColors[SS]) continue; // These slots allow to share the same registers. @@ -478,9 +472,6 @@ bool StackSlotColoring::PropagateBackward(MachineBasicBlock::iterator MII, MachineBasicBlock *MBB, unsigned OldReg, unsigned NewReg) { - if (MII == MBB->begin()) - return false; - SmallVector Refs; while (--MII != MBB->begin()) { bool FoundDef = false; // Not counting 2address def. @@ -531,9 +522,6 @@ bool StackSlotColoring::PropagateForward(MachineBasicBlock::iterator MII, MachineBasicBlock *MBB, unsigned OldReg, unsigned NewReg) { - if (MII == MBB->end()) - return false; - SmallVector Uses; while (++MII != MBB->end()) { bool FoundUse = false; Modified: llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll?rev=71138&r1=71137&r2=71138&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll (original) +++ llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll Wed May 6 20:27:25 2009 @@ -1,4 +1,5 @@ ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin -stats |& grep virtregrewriter | not grep {stores unfolded} +; XFAIL: * ; rdar://6682365 ; Do not clobber a register if another spill slot is available in it and it's marked "do not clobber". Modified: llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll?rev=71138&r1=71137&r2=71138&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll (original) +++ llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll Wed May 6 20:27:25 2009 @@ -1,6 +1,7 @@ ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin10 -relocation-model=pic -disable-fp-elim -O3 -stats -info-output-file - > %t ; RUN: grep stackcoloring %t | grep "loads eliminated" ; RUN: grep stackcoloring %t | grep "stores eliminated" +; XFAIL: * type { [62 x %struct.Bitvec*] } ; type %0 type { i8* } ; type %1 From isanbard at gmail.com Wed May 6 20:33:41 2009 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 07 May 2009 01:33:41 -0000 Subject: [llvm-commits] [llvm] r71140 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/StackSlotColoring.cpp Message-ID: <200905070133.n471XfgS017315@zion.cs.uiuc.edu> Author: void Date: Wed May 6 20:33:38 2009 New Revision: 71140 URL: http://llvm.org/viewvc/llvm-project?rev=71140&view=rev Log: Just turn aggressive stack coloring off at -O3. Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=71140&r1=71139&r2=71140&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed May 6 20:33:38 2009 @@ -191,7 +191,7 @@ FunctionPass *createMachineSinkingPass(); /// createStackSlotColoringPass - This pass performs stack slot coloring. - FunctionPass *createStackSlotColoringPass(); + FunctionPass *createStackSlotColoringPass(bool); /// createStackProtectorPass - This pass adds stack protectors to functions. FunctionPass *createStackProtectorPass(const TargetLowering *tli); Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=71140&r1=71139&r2=71140&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Wed May 6 20:33:38 2009 @@ -193,7 +193,8 @@ // Perform stack slot coloring. if (OptLevel != CodeGenOpt::None) - PM.add(createStackSlotColoringPass()); + PM.add(createStackSlotColoringPass(false)); + /*OptLevel >= CodeGenOpt::Aggressive*/ if (PrintMachineCode) // Print the register-allocated code PM.add(createMachineFunctionPrinterPass(cerr)); Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=71140&r1=71139&r2=71140&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Wed May 6 20:33:38 2009 @@ -37,21 +37,22 @@ cl::desc("Suppress slot sharing during stack coloring")); static cl::opt -ColorWithRegs("color-ss-with-regs", - cl::init(false), cl::Hidden, - cl::desc("Color stack slots with free registers")); +ColorWithRegsOpt("color-ss-with-regs", + cl::init(false), cl::Hidden, + cl::desc("Color stack slots with free registers")); static cl::opt DCELimit("ssc-dce-limit", cl::init(-1), cl::Hidden); STATISTIC(NumEliminated, "Number of stack slots eliminated due to coloring"); STATISTIC(NumRegRepl, "Number of stack slot refs replaced with reg refs"); -STATISTIC(NumLoadElim, "Number of load eliminated"); +STATISTIC(NumLoadElim, "Number of loads eliminated"); STATISTIC(NumStoreElim, "Number of stores eliminated"); STATISTIC(NumDead, "Number of trivially dead stack accesses eliminated"); namespace { class VISIBILITY_HIDDEN StackSlotColoring : public MachineFunctionPass { + bool ColorWithRegs; LiveStacks* LS; VirtRegMap* VRM; MachineFrameInfo *MFI; @@ -89,7 +90,10 @@ public: static char ID; // Pass identification - StackSlotColoring() : MachineFunctionPass(&ID), NextColor(-1) {} + StackSlotColoring() : + MachineFunctionPass(&ID), ColorWithRegs(false), NextColor(-1) {} + StackSlotColoring(bool RegColor) : + MachineFunctionPass(&ID), ColorWithRegs(RegColor), NextColor(-1) {} virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -136,8 +140,8 @@ static RegisterPass X("stack-slot-coloring", "Stack Slot Coloring"); -FunctionPass *llvm::createStackSlotColoringPass() { - return new StackSlotColoring(); +FunctionPass *llvm::createStackSlotColoringPass(bool RegColor) { + return new StackSlotColoring(RegColor); } namespace { @@ -231,7 +235,7 @@ StackSlotColoring::ColorSlotsWithFreeRegs(SmallVector &SlotMapping, SmallVector, 16> &RevMap, BitVector &SlotIsReg) { - if (!ColorWithRegs || !VRM->HasUnusedRegisters()) + if (!(ColorWithRegs || ColorWithRegsOpt) || !VRM->HasUnusedRegisters()) return false; bool Changed = false; @@ -239,7 +243,9 @@ for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) { LiveInterval *li = SSIntervals[i]; int SS = li->getStackSlotIndex(); - if (!UsedColors[SS]) + if (!UsedColors[SS] || li->weight < 20) + // If the weight is < 20, i.e. two references in a loop with depth 1, + // don't bother with it. continue; // These slots allow to share the same registers. @@ -472,6 +478,9 @@ bool StackSlotColoring::PropagateBackward(MachineBasicBlock::iterator MII, MachineBasicBlock *MBB, unsigned OldReg, unsigned NewReg) { + if (MII == MBB->begin()) + return false; + SmallVector Refs; while (--MII != MBB->begin()) { bool FoundDef = false; // Not counting 2address def. @@ -522,6 +531,9 @@ bool StackSlotColoring::PropagateForward(MachineBasicBlock::iterator MII, MachineBasicBlock *MBB, unsigned OldReg, unsigned NewReg) { + if (MII == MBB->end()) + return false; + SmallVector Uses; while (++MII != MBB->end()) { bool FoundUse = false; From isanbard at gmail.com Wed May 6 20:41:42 2009 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 07 May 2009 01:41:42 -0000 Subject: [llvm-commits] [llvm] r71142 - /llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll Message-ID: <200905070141.n471fgxr017542@zion.cs.uiuc.edu> Author: void Date: Wed May 6 20:41:42 2009 New Revision: 71142 URL: http://llvm.org/viewvc/llvm-project?rev=71142&view=rev Log: THis doesn't fail. Modified: llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll Modified: llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll?rev=71142&r1=71141&r2=71142&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll (original) +++ llvm/trunk/test/CodeGen/X86/2009-03-16-SpillerBug.ll Wed May 6 20:41:42 2009 @@ -1,5 +1,4 @@ ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin -stats |& grep virtregrewriter | not grep {stores unfolded} -; XFAIL: * ; rdar://6682365 ; Do not clobber a register if another spill slot is available in it and it's marked "do not clobber". From nicholas at mxc.ca Wed May 6 22:02:37 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 06 May 2009 20:02:37 -0700 Subject: [llvm-commits] [llvm] r71077 - in /llvm/trunk: lib/Transforms/IPO/FunctionAttrs.cpp test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll In-Reply-To: <200905060842.n468g7cX013662@zion.cs.uiuc.edu> References: <200905060842.n468g7cX013662@zion.cs.uiuc.edu> Message-ID: <4A024F4D.2090606@mxc.ca> Duncan Sands wrote: > Author: baldrick > Date: Wed May 6 03:42:00 2009 > New Revision: 71077 > > URL: http://llvm.org/viewvc/llvm-project?rev=71077&view=rev > Log: > Fix PR3754: don't mark functions that wrap MallocInst with > the readnone. Since MallocInst is scheduled for deletion > it doesn't seem worth doing anything more subtle, such as > having mayWriteToMemory return true for MallocInst. I don't like this fix at all. What's wrong with just making mayWriteToMemory return true on MallocInst? > > Added: > llvm/trunk/test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll > Modified: > llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp > > Modified: llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp?rev=71077&r1=71076&r2=71077&view=diff > > ============================================================================== > --- llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp (original) > +++ llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp Wed May 6 03:42:00 2009 > @@ -152,6 +152,11 @@ > if (I->mayWriteToMemory()) > // Writes memory. Just give up. > return false; > + > + if (isa(I)) > + // MallocInst claims not to write memory! PR3754. > + return false; > + > // If this instruction may read memory, remember that. > ReadsMemory |= I->mayReadFromMemory(); > } > > Added: llvm/trunk/test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll?rev=71077&view=auto > > ============================================================================== > --- llvm/trunk/test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll (added) > +++ llvm/trunk/test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll Wed May 6 03:42:00 2009 > @@ -0,0 +1,7 @@ > +; RUN: llvm-as < %s | opt -functionattrs | llvm-dis | not grep read > +; PR3754 > + > +define i8* @m(i32 %size) { > + %tmp = malloc i8, i32 %size ; [#uses=1] > + ret i8* %tmp > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From clattner at apple.com Wed May 6 23:26:38 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 6 May 2009 21:26:38 -0700 Subject: [llvm-commits] [llvm] r71077 - in /llvm/trunk: lib/Transforms/IPO/FunctionAttrs.cpp test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll In-Reply-To: <4A024F4D.2090606@mxc.ca> References: <200905060842.n468g7cX013662@zion.cs.uiuc.edu> <4A024F4D.2090606@mxc.ca> Message-ID: <22BEF759-CB40-4C8F-A370-5426FB4C5849@apple.com> On May 6, 2009, at 8:02 PM, Nick Lewycky wrote: > Duncan Sands wrote: >> Author: baldrick >> Date: Wed May 6 03:42:00 2009 >> New Revision: 71077 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=71077&view=rev >> Log: >> Fix PR3754: don't mark functions that wrap MallocInst with >> the readnone. Since MallocInst is scheduled for deletion >> it doesn't seem worth doing anything more subtle, such as >> having mayWriteToMemory return true for MallocInst. > > I don't like this fix at all. What's wrong with just making > mayWriteToMemory return true on MallocInst? I agree, that seems like the obvious fix...? -Chris From stoklund at 2pi.dk Wed May 6 23:41:26 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 07 May 2009 04:41:26 -0000 Subject: [llvm-commits] [llvm] r71147 - /llvm/trunk/include/llvm/CodeGen/MachineFunction.h Message-ID: <200905070441.n474fQNq023002@zion.cs.uiuc.edu> Author: stoklund Date: Wed May 6 23:41:26 2009 New Revision: 71147 URL: http://llvm.org/viewvc/llvm-project?rev=71147&view=rev Log: Add const modifiers. Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunction.h?rev=71147&r1=71146&r2=71147&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFunction.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineFunction.h Wed May 6 23:41:26 2009 @@ -176,7 +176,7 @@ /// basic block can be found by using the MBB::getBlockNumber method, this /// method provides the inverse mapping. /// - MachineBasicBlock *getBlockNumbered(unsigned N) { + MachineBasicBlock *getBlockNumbered(unsigned N) const { assert(N < MBBNumbering.size() && "Illegal block number"); assert(MBBNumbering[N] && "Block was removed from the machine function!"); return MBBNumbering[N]; From evan.cheng at apple.com Thu May 7 00:31:56 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 07 May 2009 05:31:56 -0000 Subject: [llvm-commits] [llvm] r71149 - /llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp Message-ID: <200905070531.n475Vu6M024542@zion.cs.uiuc.edu> Author: evancheng Date: Thu May 7 00:31:56 2009 New Revision: 71149 URL: http://llvm.org/viewvc/llvm-project?rev=71149&view=rev Log: Eliminate compiler warnings. Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp?rev=71149&r1=71148&r2=71149&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp Thu May 7 00:31:56 2009 @@ -87,7 +87,7 @@ // No BSS section spacious enough was found. Crate a new one. if (! FoundBSS) { char *name = new char[32]; - sprintf (name, "udata.%d.# UDATA", BSSSections.size()); + sprintf (name, "udata.%d.# UDATA", (int)BSSSections.size()); const Section *NewSection = getNamedSection (name); FoundBSS = new PIC16Section(NewSection); @@ -133,7 +133,7 @@ // No IDATA section spacious enough was found. Crate a new one. if (! FoundIDATA) { char *name = new char[32]; - sprintf (name, "idata.%d.# IDATA", IDATASections.size()); + sprintf (name, "idata.%d.# IDATA", (int)IDATASections.size()); const Section *NewSection = getNamedSection (name); FoundIDATA = new PIC16Section(NewSection); From evan.cheng at apple.com Thu May 7 00:42:24 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 07 May 2009 05:42:24 -0000 Subject: [llvm-commits] [llvm] r71150 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CodePlacementOpt.cpp lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/LoopAligner.cpp Message-ID: <200905070542.n475gOnD024875@zion.cs.uiuc.edu> Author: evancheng Date: Thu May 7 00:42:24 2009 New Revision: 71150 URL: http://llvm.org/viewvc/llvm-project?rev=71150&view=rev Log: Rename "loop aligner" pass to "code placement optimization" pass. Added: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp - copied, changed from r71116, llvm/trunk/lib/CodeGen/LoopAligner.cpp Removed: llvm/trunk/lib/CodeGen/LoopAligner.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/lib/CodeGen/CMakeLists.txt llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=71150&r1=71149&r2=71150&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Thu May 7 00:42:24 2009 @@ -146,9 +146,9 @@ /// IfConverter Pass - This pass performs machine code if conversion. FunctionPass *createIfConverterPass(); - /// LoopAligner Pass - This pass aligns loop headers to target specific - /// alignment boundary. - FunctionPass *createLoopAlignerPass(); + /// Code Placement Pass - This pass optimize code placement and aligns loop + /// headers to target specific alignment boundary. + FunctionPass *createCodePlacementOptPass(); /// DebugLabelFoldingPass - This pass prunes out redundant debug labels. This /// allows a debug emitter to determine if the range of two labels is empty, Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=71150&r1=71149&r2=71150&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Thu May 7 00:42:24 2009 @@ -1,5 +1,6 @@ add_llvm_library(LLVMCodeGen BranchFolding.cpp + CodePlacementOpt.cpp DeadMachineInstructionElim.cpp ELFWriter.cpp GCMetadata.cpp @@ -13,7 +14,6 @@ LiveIntervalAnalysis.cpp LiveStackAnalysis.cpp LiveVariables.cpp - LoopAligner.cpp LowerSubregs.cpp MachOWriter.cpp MachineBasicBlock.cpp Copied: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp (from r71116, llvm/trunk/lib/CodeGen/LoopAligner.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp?p2=llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp&p1=llvm/trunk/lib/CodeGen/LoopAligner.cpp&r1=71116&r2=71150&rev=71150&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LoopAligner.cpp (original) +++ llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Thu May 7 00:42:24 2009 @@ -1,4 +1,4 @@ -//===-- LoopAligner.cpp - Loop aligner pass. ------------------------------===// +//===-- CodePlacementOpt.cpp - Code Placement pass. -----------------------===// // // The LLVM Compiler Infrastructure // @@ -7,12 +7,12 @@ // //===----------------------------------------------------------------------===// // -// This file implements the pass that align loop headers to target specific -// alignment boundary. +// This file implements the pass that optimize code placement and align loop +// headers to target specific alignment boundary. // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "loopalign" +#define DEBUG_TYPE "code-placement" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/Passes.h" @@ -23,13 +23,15 @@ using namespace llvm; namespace { - class LoopAligner : public MachineFunctionPass { + class CodePlacementOpt : public MachineFunctionPass { public: static char ID; - LoopAligner() : MachineFunctionPass(&ID) {} + CodePlacementOpt() : MachineFunctionPass(&ID) {} virtual bool runOnMachineFunction(MachineFunction &MF); - virtual const char *getPassName() const { return "Loop aligner"; } + virtual const char *getPassName() const { + return "Code Placement Optimizater"; + } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -39,12 +41,14 @@ } }; - char LoopAligner::ID = 0; + char CodePlacementOpt::ID = 0; } // end anonymous namespace -FunctionPass *llvm::createLoopAlignerPass() { return new LoopAligner(); } +FunctionPass *llvm::createCodePlacementOptPass() { + return new CodePlacementOpt(); +} -bool LoopAligner::runOnMachineFunction(MachineFunction &MF) { +bool CodePlacementOpt::runOnMachineFunction(MachineFunction &MF) { const MachineLoopInfo *MLI = &getAnalysis(); if (MLI->empty()) Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=71150&r1=71149&r2=71150&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Thu May 7 00:42:24 2009 @@ -70,7 +70,7 @@ PM.add(createMachineFunctionPrinterPass(cerr)); if (OptLevel != CodeGenOpt::None) - PM.add(createLoopAlignerPass()); + PM.add(createCodePlacementOptPass()); switch (FileType) { default: Removed: llvm/trunk/lib/CodeGen/LoopAligner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LoopAligner.cpp?rev=71149&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/LoopAligner.cpp (original) +++ llvm/trunk/lib/CodeGen/LoopAligner.cpp (removed) @@ -1,78 +0,0 @@ -//===-- LoopAligner.cpp - Loop aligner pass. ------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the pass that align loop headers to target specific -// alignment boundary. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "loopalign" -#include "llvm/CodeGen/MachineLoopInfo.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/Passes.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/Debug.h" -using namespace llvm; - -namespace { - class LoopAligner : public MachineFunctionPass { - public: - static char ID; - LoopAligner() : MachineFunctionPass(&ID) {} - - virtual bool runOnMachineFunction(MachineFunction &MF); - virtual const char *getPassName() const { return "Loop aligner"; } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - AU.addPreserved(); - AU.addPreservedID(MachineDominatorsID); - MachineFunctionPass::getAnalysisUsage(AU); - } - }; - - char LoopAligner::ID = 0; -} // end anonymous namespace - -FunctionPass *llvm::createLoopAlignerPass() { return new LoopAligner(); } - -bool LoopAligner::runOnMachineFunction(MachineFunction &MF) { - const MachineLoopInfo *MLI = &getAnalysis(); - - if (MLI->empty()) - return false; // No loops. - - const TargetLowering *TLI = MF.getTarget().getTargetLowering(); - if (!TLI) - return false; - - unsigned Align = TLI->getPrefLoopAlignment(); - if (!Align) - return false; // Don't care about loop alignment. - - const Function *F = MF.getFunction(); - if (F->hasFnAttr(Attribute::OptimizeForSize)) - return false; - - for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { - MachineBasicBlock *MBB = I; - if (MLI->isLoopHeader(MBB)) { - MachineBasicBlock *PredBB = prior(I); - if (MLI->getLoopFor(MBB) == MLI->getLoopFor(PredBB)) - // If previously BB is in the same loop, don't align this BB. We want - // to prevent adding noop's inside a loop. - continue; - MBB->setAlignment(Align); - } - } - - return true; -} From evan.cheng at apple.com Thu May 7 00:49:39 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 07 May 2009 05:49:39 -0000 Subject: [llvm-commits] [llvm] r71151 - /llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Message-ID: <200905070549.n475ndv6025073@zion.cs.uiuc.edu> Author: evancheng Date: Thu May 7 00:49:39 2009 New Revision: 71151 URL: http://llvm.org/viewvc/llvm-project?rev=71151&view=rev Log: Code refactoring. Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp?rev=71151&r1=71150&r2=71151&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp (original) +++ llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Thu May 7 00:49:39 2009 @@ -24,6 +24,8 @@ namespace { class CodePlacementOpt : public MachineFunctionPass { + const MachineLoopInfo *MLI; + public: static char ID; CodePlacementOpt() : MachineFunctionPass(&ID) {} @@ -39,6 +41,9 @@ AU.addPreservedID(MachineDominatorsID); MachineFunctionPass::getAnalysisUsage(AU); } + + private: + bool AlignLoops(MachineFunction &MF); }; char CodePlacementOpt::ID = 0; @@ -48,12 +53,9 @@ return new CodePlacementOpt(); } -bool CodePlacementOpt::runOnMachineFunction(MachineFunction &MF) { - const MachineLoopInfo *MLI = &getAnalysis(); - - if (MLI->empty()) - return false; // No loops. - +/// AlignLoops - Align loop headers to target preferred alignments. +/// +bool CodePlacementOpt::AlignLoops(MachineFunction &MF) { const TargetLowering *TLI = MF.getTarget().getTargetLowering(); if (!TLI) return false; @@ -66,6 +68,7 @@ if (F->hasFnAttr(Attribute::OptimizeForSize)) return false; + bool Changed = false; for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { MachineBasicBlock *MBB = I; if (MLI->isLoopHeader(MBB)) { @@ -75,8 +78,20 @@ // to prevent adding noop's inside a loop. continue; MBB->setAlignment(Align); + Changed = true; } } - return true; + return Changed; +} + +bool CodePlacementOpt::runOnMachineFunction(MachineFunction &MF) { + MLI = &getAnalysis(); + if (MLI->empty()) + return false; // No loops. + + bool Changed = false; + Changed |= AlignLoops(MF); + + return Changed; } From mikael.lepisto at tut.fi Thu May 7 02:56:45 2009 From: mikael.lepisto at tut.fi (=?ISO-8859-1?Q?Mikael_Lepist=F6?=) Date: Thu, 07 May 2009 10:56:45 +0300 Subject: [llvm-commits] [PATCH] Added TCE target to llvm-gcc In-Reply-To: <49CB8AC9.80308@tut.fi> References: <49CB688D.8070606@tut.fi> <200903261405.48884.baldrick@free.fr> <49CB8AC9.80308@tut.fi> Message-ID: <4A02943D.9010108@tut.fi> Mikael Lepist? wrote: > Duncan Sands wrote: > >> Hi, are you planning to get this target into mainline gcc >> at some point? >> > I don't think that it's possible since we generate new version of our > backend for each processor configuration (with different instruction > sets and registers) and load it as a plugin to our own llc replacement. > This replacement also converts llvm bitcode to our native format. > >> Why do you only emit bitcode - are you >> planning to implement an LLVM code generator for your >> target? >> > > In short: We already have LLVM code generator, but it's quite different > approach that usual llvm backends... > > We do linking and optimizing on llvm IR (also linking static newlib to > program). After we have fully linked bitcode we build code generation > plugin which contains information about customizes resources of the > processor. That plugin generates our native IR out of bitcode and use > generated IR for scheduling program to a specific processor configuration. > > So basically bitcode programs are universal programs, which can be > converted to run on any different processor configuration. For more > information on tce.cs.tut.fi page contains tutorials and videos about > the system. There is also a masters thesis about to be released (in few > months) which covers our compiler chain. > > >> Finally, does this break the llvm-gcc build if >> llvm-gcc is configured with LLVM support disabled? >> >> > Looks like it compiled fine without special --target setting. However > --target=tce-llvm without --enable-llvm failed. Patch has really small > changes to configure system just for recognizing that new > --target=tce-llvm target exists. > >> Ciao, >> >> Duncan. >> >> > Mikael > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > Hi, Any news if this patch could be applied and which modifications it would need? I attached the latest version of the patch which is made towards llvm-gcc trunk with "svn diff -x -u". This patch would help greatly our users to be able to use llvm-gcc sources gotten directly from llvm, instead using our patched version. Also it would help a bit maintaining llvm trunk synchronized branch of the tce toolset. Mikael Lepist? http://llvm.org/ProjectsWithLLVM/#tta-tce -------------- next part -------------- A non-text attachment was scrubbed... Name: tce_target.patch Type: text/x-patch Size: 47176 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090507/d2bf5d3f/attachment.bin From jay.foad at gmail.com Thu May 7 07:09:18 2009 From: jay.foad at gmail.com (Jay Foad) Date: Thu, 7 May 2009 13:09:18 +0100 Subject: [llvm-commits] [PATCH] TargetData::getIntPtrType() to return IntegerType Message-ID: The attached patch lets me avoid some casts to IntegerType in some code I'm working on. Thoughts? It passes regression tests and cfe and llvm-gcc still build. It's a bit unfortunate that TargetData.h has to include DerivedTypes.h, but otherwise this would break code like: const Type *Ty = TD->getIntPtrType(); which now needs to know that IntegerType is derived from Type. Thanks, Jay. -------------- next part -------------- A non-text attachment was scrubbed... Name: patch.intptr Type: application/octet-stream Size: 1372 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090507/53143c4e/attachment.obj From jay.foad at gmail.com Thu May 7 08:28:56 2009 From: jay.foad at gmail.com (Jay Foad) Date: Thu, 7 May 2009 14:28:56 +0100 Subject: [llvm-commits] [PATCH] optimise constant arguments in LowerIntrinsicCall() Message-ID: Given this source: void f(int *p) { p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = p[8] = p[9] = 0; } if I compile with optimisation and then run it through the C backend: $ .../llvm-gcc4.2-2.5-x86-linux-RHEL4/bin/llvm-gcc -emit-llvm -O2 -c m.c $ llc -march=c -o - m.o I get: void f(unsigned int *llvm_cbe_p) { unsigned char *ltmp_0_1; *llvm_cbe_p = 0u; ltmp_0_1 = memset((((unsigned char *)((&llvm_cbe_p[((signed int )1u)])))), (((unsigned int )(unsigned char )((unsigned char )0))), (((unsigned int )36ull))); return; } The second and third arguments in the call to memset() involve unnecessary casts of a constant value. This happens because LowerIntrinsicCall() turns: call void @llvm.memset.i64(i8* %1, i8 0, i64 36, i32 4) into: %2 = trunc i64 36 to i32 ; [#uses=1] %3 = zext i8 0 to i32 ; [#uses=1] %4 = call i8* @memset(i8* %1, i32 %3, i32 %2) ; and nothing later constant-folds the trunc and zext instructions. The attached patch addresses this, by optimising LowerIntrinsicCall() for the case of constant arguments. With this patch applied, the C backend produces: ltmp_0_1 = memset((((unsigned char *)((&llvm_cbe_p[((signed int )1u)])))), 0u, 36u); The patch passes "make check". Alternatively, maybe some other optimisation pass could be scheduled that constant-folds the trunc and zext instructions, but this seems like overkill to me. Incidentally, it seems a bit odd that llvm-gcc generates llvm.memset.i64 instead of llvm.memset.i32 in the first place, but I haven't investigated why this happens. Thanks, Jay. -------------- next part -------------- A non-text attachment was scrubbed... Name: patch.lic Type: application/octet-stream Size: 5018 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090507/91c1f37b/attachment.obj From akyrtzi at gmail.com Thu May 7 08:55:56 2009 From: akyrtzi at gmail.com (Argiris Kirtzidis) Date: Thu, 07 May 2009 13:55:56 -0000 Subject: [llvm-commits] [llvm] r71156 - in /llvm/trunk: include/llvm/CodeGen/AsmPrinter.h lib/CodeGen/AsmPrinter/AsmPrinter.cpp utils/TableGen/AsmWriterEmitter.cpp Message-ID: <200905071355.n47Dtxq1019549@zion.cs.uiuc.edu> Author: akirtzidis Date: Thu May 7 08:55:51 2009 New Revision: 71156 URL: http://llvm.org/viewvc/llvm-project?rev=71156&view=rev Log: Move the tablegen-produced DebugLoc handling into a AsmWriter::processDebugLoc function. No functionality change. Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AsmPrinter.h?rev=71156&r1=71155&r2=71156&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original) +++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Thu May 7 08:55:51 2009 @@ -18,7 +18,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Support/DataTypes.h" #include "llvm/Target/TargetMachine.h" #include @@ -342,6 +341,10 @@ void EmitGlobalConstant(const Constant* CV, unsigned AddrSpace = 0); virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); + + /// processDebugLoc - Processes the debug information of each machine + /// instruction's DebugLoc. + void processDebugLoc(DebugLoc DL); /// printInlineAsm - This method formats and prints the specified machine /// instruction that is an inline asm. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=71156&r1=71155&r2=71156&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Thu May 7 08:55:51 2009 @@ -21,6 +21,7 @@ #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/DwarfWriter.h" +#include "llvm/Analysis/DebugInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Mangler.h" #include "llvm/Support/raw_ostream.h" @@ -1305,6 +1306,22 @@ } } +/// processDebugLoc - Processes the debug information of each machine +/// instruction's DebugLoc. +void AsmPrinter::processDebugLoc(DebugLoc DL) { + if (TAI->doesSupportDebugInformation() && DW->ShouldEmitDwarfDebug()) { + if (!DL.isUnknown()) { + static DebugLocTuple PrevDLT(0, ~0U, ~0U); + DebugLocTuple CurDLT = MF->getDebugLocTuple(DL); + + if (CurDLT.CompileUnit != 0 && PrevDLT != CurDLT) + printLabel(DW->RecordSourceLine(CurDLT.Line, CurDLT.Col, + DICompileUnit(CurDLT.CompileUnit))); + + PrevDLT = CurDLT; + } + } +} /// printInlineAsm - This method formats and prints the specified machine /// instruction that is an inline asm. Modified: llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp?rev=71156&r1=71155&r2=71156&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp Thu May 7 08:55:51 2009 @@ -649,18 +649,7 @@ } O << "\";\n\n"; - O << " if (TAI->doesSupportDebugInformation() &&\n" - << " DW->ShouldEmitDwarfDebug()) {\n" - << " DebugLoc CurDL = MI->getDebugLoc();\n\n" - << " if (!CurDL.isUnknown()) {\n" - << " static DebugLocTuple PrevDLT(0, ~0U, ~0U);\n" - << " DebugLocTuple CurDLT = MF->getDebugLocTuple(CurDL);\n\n" - << " if (CurDLT.CompileUnit != 0 && PrevDLT != CurDLT)\n" - << " printLabel(DW->RecordSourceLine(CurDLT.Line, CurDLT.Col,\n" - << " DICompileUnit(CurDLT.CompileUnit)));\n\n" - << " PrevDLT = CurDLT;\n" - << " }\n" - << " }\n\n"; + O << " processDebugLoc(MI->getDebugLoc());\n\n"; O << " if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {\n" << " O << \"\\t\";\n" From gohman at apple.com Thu May 7 09:00:20 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 07 May 2009 14:00:20 -0000 Subject: [llvm-commits] [llvm] r71157 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolutionExpressions.h lib/Analysis/ScalarEvolution.cpp Message-ID: <200905071400.n47E0Nve019720@zion.cs.uiuc.edu> Author: djg Date: Thu May 7 09:00:19 2009 New Revision: 71157 URL: http://llvm.org/viewvc/llvm-project?rev=71157&view=rev Log: Factor out a common base class between SCEVCommutativeExpr and SCEVAddRecExpr. This eliminates redundant code for visiting all the operands of an expression. Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h?rev=71157&r1=71156&r2=71157&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h Thu May 7 09:00:19 2009 @@ -194,20 +194,13 @@ }; - //===--------------------------------------------------------------------===// - /// SCEVCommutativeExpr - This node is the base class for n'ary commutative - /// operators. - /// - class SCEVCommutativeExpr : public SCEV { + class SCEVNAryExpr : public SCEV { + protected: std::vector Operands; - protected: - SCEVCommutativeExpr(enum SCEVTypes T, const std::vector &ops) - : SCEV(T) { - Operands.reserve(ops.size()); - Operands.insert(Operands.end(), ops.begin(), ops.end()); - } - ~SCEVCommutativeExpr(); + SCEVNAryExpr(enum SCEVTypes T, const std::vector &ops) + : SCEV(T), Operands(ops) {} + virtual ~SCEVNAryExpr() {} public: unsigned getNumOperands() const { return (unsigned)Operands.size(); } @@ -221,7 +214,6 @@ op_iterator op_begin() const { return Operands.begin(); } op_iterator op_end() const { return Operands.end(); } - virtual bool isLoopInvariant(const Loop *L) const { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) if (!getOperand(i)->isLoopInvariant(L)) return false; @@ -243,15 +235,38 @@ return HasVarying; } + bool dominates(BasicBlock *BB, DominatorTree *DT) const; + + virtual const Type *getType() const { return getOperand(0)->getType(); } + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVNAryExpr *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scAddExpr || + S->getSCEVType() == scMulExpr || + S->getSCEVType() == scSMaxExpr || + S->getSCEVType() == scUMaxExpr || + S->getSCEVType() == scAddRecExpr; + } + }; + + //===--------------------------------------------------------------------===// + /// SCEVCommutativeExpr - This node is the base class for n'ary commutative + /// operators. + /// + class SCEVCommutativeExpr : public SCEVNAryExpr { + protected: + SCEVCommutativeExpr(enum SCEVTypes T, const std::vector &ops) + : SCEVNAryExpr(T, ops) {} + ~SCEVCommutativeExpr(); + + public: SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, const SCEVHandle &Conc, ScalarEvolution &SE) const; - bool dominates(BasicBlock *BB, DominatorTree *DT) const; - virtual const char *getOperationStr() const = 0; - virtual const Type *getType() const { return getOperand(0)->getType(); } virtual void print(raw_ostream &OS) const; /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -364,30 +379,23 @@ /// /// All operands of an AddRec are required to be loop invariant. /// - class SCEVAddRecExpr : public SCEV { + class SCEVAddRecExpr : public SCEVNAryExpr { friend class ScalarEvolution; - std::vector Operands; const Loop *L; SCEVAddRecExpr(const std::vector &ops, const Loop *l) - : SCEV(scAddRecExpr), Operands(ops), L(l) { + : SCEVNAryExpr(scAddRecExpr, ops), L(l) { for (size_t i = 0, e = Operands.size(); i != e; ++i) assert(Operands[i]->isLoopInvariant(l) && "Operands of AddRec must be loop-invariant!"); } ~SCEVAddRecExpr(); - public: - typedef std::vector::const_iterator op_iterator; - op_iterator op_begin() const { return Operands.begin(); } - op_iterator op_end() const { return Operands.end(); } - unsigned getNumOperands() const { return (unsigned)Operands.size(); } - const SCEVHandle &getOperand(unsigned i) const { return Operands[i]; } + public: const SCEVHandle &getStart() const { return Operands[0]; } const Loop *getLoop() const { return L; } - /// getStepRecurrence - This method constructs and returns the recurrence /// indicating how much this expression steps by. If this is a polynomial /// of degree N, it returns a chrec of degree N-1. @@ -404,8 +412,6 @@ virtual bool isLoopInvariant(const Loop *QueryLoop) const; - virtual const Type *getType() const { return Operands[0]->getType(); } - /// isAffine - Return true if this is an affine AddRec (i.e., it represents /// an expressions A+B*x where A and B are loop invariant values. bool isAffine() const { @@ -438,8 +444,6 @@ const SCEVHandle &Conc, ScalarEvolution &SE) const; - bool dominates(BasicBlock *BB, DominatorTree *DT) const; - virtual void print(raw_ostream &OS) const; /// Methods for support type inquiry through isa, cast, and dyn_cast: Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71157&r1=71156&r2=71157&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Thu May 7 09:00:19 2009 @@ -316,7 +316,7 @@ return this; } -bool SCEVCommutativeExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { +bool SCEVNAryExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { if (!getOperand(i)->dominates(BB, DT)) return false; @@ -359,15 +359,6 @@ SCEVAddRecExprs->erase(std::make_pair(L, SCEVOps)); } -bool SCEVAddRecExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - if (!getOperand(i)->dominates(BB, DT)) - return false; - } - return true; -} - - SCEVHandle SCEVAddRecExpr:: replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, const SCEVHandle &Conc, From gohman at apple.com Thu May 7 09:25:13 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 07 May 2009 14:25:13 -0000 Subject: [llvm-commits] [llvm] r71158 - in /llvm/trunk: lib/Analysis/ConstantFolding.cpp test/Transforms/InstCombine/constant-fold-ptr-casts.ll Message-ID: <200905071425.n47EPFEb020594@zion.cs.uiuc.edu> Author: djg Date: Thu May 7 09:24:56 2009 New Revision: 71158 URL: http://llvm.org/viewvc/llvm-project?rev=71158&view=rev Log: Constant-fold ptrtoint+add+inttoptr to gep when the pointer is an array and the add is within range. This helps simplify expressions expanded by ScalarEvolutionExpander. Added: llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=71158&r1=71157&r2=71158&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Thu May 7 09:24:56 2009 @@ -16,6 +16,7 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" +#include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/ADT/SmallVector.h" @@ -383,12 +384,43 @@ // the int size is >= the ptr size. This requires knowing the width of a // pointer, so it can't be done in ConstantExpr::getCast. if (ConstantExpr *CE = dyn_cast(Ops[0])) { - if (TD && CE->getOpcode() == Instruction::PtrToInt && + if (TD && TD->getPointerSizeInBits() <= CE->getType()->getPrimitiveSizeInBits()) { - Constant *Input = CE->getOperand(0); - Constant *C = FoldBitCast(Input, DestTy, *TD); - return C ? C : ConstantExpr::getBitCast(Input, DestTy); + if (CE->getOpcode() == Instruction::PtrToInt) { + Constant *Input = CE->getOperand(0); + Constant *C = FoldBitCast(Input, DestTy, *TD); + return C ? C : ConstantExpr::getBitCast(Input, DestTy); + } + // If there's a constant offset added to the integer value before + // it is casted back to a pointer, see if the expression can be + // converted into a GEP. + if (CE->getOpcode() == Instruction::Add) + if (ConstantInt *L = dyn_cast(CE->getOperand(0))) + if (ConstantExpr *R = dyn_cast(CE->getOperand(1))) + if (R->getOpcode() == Instruction::PtrToInt) + if (GlobalVariable *GV = + dyn_cast(R->getOperand(0))) { + const PointerType *GVTy = cast(GV->getType()); + if (const ArrayType *AT = + dyn_cast(GVTy->getElementType())) { + const Type *ElTy = AT->getElementType(); + uint64_t PaddedSize = TD->getTypePaddedSize(ElTy); + APInt PSA(L->getValue().getBitWidth(), PaddedSize); + if (ElTy == cast(DestTy)->getElementType() && + L->getValue().urem(PSA) == 0) { + APInt ElemIdx = L->getValue().udiv(PSA); + if (ElemIdx.ult(APInt(ElemIdx.getBitWidth(), + AT->getNumElements()))) { + Constant *Index[] = { + Constant::getNullValue(CE->getType()), + ConstantInt::get(ElemIdx) + }; + return ConstantExpr::getGetElementPtr(GV, &Index[0], 2); + } + } + } + } } } return ConstantExpr::getCast(Opcode, Ops[0], DestTy); Added: llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll?rev=71158&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll Thu May 7 09:24:56 2009 @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i32 2143034560} + +; Instcombine should be able to completely fold this code. + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i686-apple-darwin8" + + at bar = constant [3 x i64] [i64 9220983451228067448, i64 9220983451228067449, i64 9220983450959631991], align 8 + +define i32 @foo() nounwind { +entry: + %tmp87.2 = load i64* inttoptr (i32 add (i32 16, i32 ptrtoint ([3 x i64]* @bar to i32)) to i64*), align 8 + %t0 = bitcast i64 %tmp87.2 to double + %tmp9192.2 = fptrunc double %t0 to float + %t1 = bitcast float %tmp9192.2 to i32 + ret i32 %t1 +} + From gohman at apple.com Thu May 7 09:30:30 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 07 May 2009 14:30:30 -0000 Subject: [llvm-commits] [llvm] r71159 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200905071430.n47EUUaS020756@zion.cs.uiuc.edu> Author: djg Date: Thu May 7 09:30:26 2009 New Revision: 71159 URL: http://llvm.org/viewvc/llvm-project?rev=71159&view=rev Log: Trim unnecessary headers. Code in Analysis shouldn't use Transforms headers due to library dependencies. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71159&r1=71158&r2=71159&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Thu May 7 09:30:26 2009 @@ -70,8 +70,6 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/Assembly/Writer.h" #include "llvm/Target/TargetData.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ConstantRange.h" @@ -84,7 +82,6 @@ #include "llvm/ADT/STLExtras.h" #include #include -#include using namespace llvm; STATISTIC(NumArrayLenItCounts, From gohman at apple.com Thu May 7 09:39:10 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 07 May 2009 14:39:10 -0000 Subject: [llvm-commits] [llvm] r71160 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200905071439.n47EdB8f021036@zion.cs.uiuc.edu> Author: djg Date: Thu May 7 09:39:04 2009 New Revision: 71160 URL: http://llvm.org/viewvc/llvm-project?rev=71160&view=rev Log: Make ScalarEvolution's GroupByComplexity more thorough. In addition to sorting SCEVs by their kind, sort SCEVs of the same kind according to their operands. This helps avoid things like (a+b) being a distinct expression from (b+a). Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71160&r1=71159&r2=71160&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Thu May 7 09:39:04 2009 @@ -432,9 +432,84 @@ /// SCEVComplexityCompare - Return true if the complexity of the LHS is less /// than the complexity of the RHS. This comparator is used to canonicalize /// expressions. - struct VISIBILITY_HIDDEN SCEVComplexityCompare { + class VISIBILITY_HIDDEN SCEVComplexityCompare { + LoopInfo *LI; + public: + explicit SCEVComplexityCompare(LoopInfo *li) : LI(li) {} + bool operator()(const SCEV *LHS, const SCEV *RHS) const { - return LHS->getSCEVType() < RHS->getSCEVType(); + // Primarily, sort the SCEVs by their getSCEVType(). + if (LHS->getSCEVType() != RHS->getSCEVType()) + return LHS->getSCEVType() < RHS->getSCEVType(); + + // Aside from the getSCEVType() ordering, the particular ordering + // isn't very important except that it's beneficial to be consistent, + // so that (a + b) and (b + a) don't end up as different expressions. + + // Sort SCEVUnknown values with some loose heuristics. TODO: This is + // not as complete as it could be. + if (const SCEVUnknown *LU = dyn_cast(LHS)) { + const SCEVUnknown *RU = cast(RHS); + + // Compare getValueID values. + if (LU->getValue()->getValueID() != RU->getValue()->getValueID()) + return LU->getValue()->getValueID() < RU->getValue()->getValueID(); + + // Sort arguments by their position. + if (const Argument *LA = dyn_cast(LU->getValue())) { + const Argument *RA = cast(RU->getValue()); + return LA->getArgNo() < RA->getArgNo(); + } + + // For instructions, compare their loop depth, and their opcode. + // This is pretty loose. + if (Instruction *LV = dyn_cast(LU->getValue())) { + Instruction *RV = cast(RU->getValue()); + + // Compare loop depths. + if (LI->getLoopDepth(LV->getParent()) != + LI->getLoopDepth(RV->getParent())) + return LI->getLoopDepth(LV->getParent()) < + LI->getLoopDepth(RV->getParent()); + + // Compare opcodes. + if (LV->getOpcode() != RV->getOpcode()) + return LV->getOpcode() < RV->getOpcode(); + + // Compare the number of operands. + if (LV->getNumOperands() != RV->getNumOperands()) + return LV->getNumOperands() < RV->getNumOperands(); + } + + return false; + } + + // Constant sorting doesn't matter since they'll be folded. + if (isa(LHS)) + return false; + + // Lexicographically compare n-ary expressions. + if (const SCEVNAryExpr *LC = dyn_cast(LHS)) { + const SCEVNAryExpr *RC = cast(RHS); + for (unsigned i = 0, e = LC->getNumOperands(); i != e; ++i) { + if (i >= RC->getNumOperands()) + return false; + if (operator()(LC->getOperand(i), RC->getOperand(i))) + return true; + if (operator()(RC->getOperand(i), LC->getOperand(i))) + return false; + } + return LC->getNumOperands() < RC->getNumOperands(); + } + + // Compare cast expressions by operand. + if (const SCEVCastExpr *LC = dyn_cast(LHS)) { + const SCEVCastExpr *RC = cast(RHS); + return operator()(LC->getOperand(), RC->getOperand()); + } + + assert(0 && "Unknown SCEV kind!"); + return false; } }; } @@ -449,18 +524,19 @@ /// this to depend on where the addresses of various SCEV objects happened to /// land in memory. /// -static void GroupByComplexity(std::vector &Ops) { +static void GroupByComplexity(std::vector &Ops, + LoopInfo *LI) { if (Ops.size() < 2) return; // Noop if (Ops.size() == 2) { // This is the common case, which also happens to be trivially simple. // Special case it. - if (SCEVComplexityCompare()(Ops[1], Ops[0])) + if (SCEVComplexityCompare(LI)(Ops[1], Ops[0])) std::swap(Ops[0], Ops[1]); return; } // Do the rough sort by complexity. - std::stable_sort(Ops.begin(), Ops.end(), SCEVComplexityCompare()); + std::stable_sort(Ops.begin(), Ops.end(), SCEVComplexityCompare(LI)); // Now that we are sorted by complexity, group elements of the same // complexity. Note that this is, at worst, N^2, but the vector is likely to @@ -833,7 +909,7 @@ if (Ops.size() == 1) return Ops[0]; // Sort by complexity, this groups all similar expression types together. - GroupByComplexity(Ops); + GroupByComplexity(Ops, LI); // If there are any constants, fold them together. unsigned Idx = 0; @@ -1058,7 +1134,7 @@ assert(!Ops.empty() && "Cannot get empty mul!"); // Sort by complexity, this groups all similar expression types together. - GroupByComplexity(Ops); + GroupByComplexity(Ops, LI); // If there are any constants, fold them together. unsigned Idx = 0; @@ -1292,7 +1368,7 @@ if (Ops.size() == 1) return Ops[0]; // Sort by complexity, this groups all similar expression types together. - GroupByComplexity(Ops); + GroupByComplexity(Ops, LI); // If there are any constants, fold them together. unsigned Idx = 0; @@ -1372,7 +1448,7 @@ if (Ops.size() == 1) return Ops[0]; // Sort by complexity, this groups all similar expression types together. - GroupByComplexity(Ops); + GroupByComplexity(Ops, LI); // If there are any constants, fold them together. unsigned Idx = 0; From baldrick at free.fr Thu May 7 11:45:03 2009 From: baldrick at free.fr (Duncan Sands) Date: Thu, 7 May 2009 18:45:03 +0200 Subject: [llvm-commits] [llvm] r71077 - in /llvm/trunk: lib/Transforms/IPO/FunctionAttrs.cpp test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll In-Reply-To: <22BEF759-CB40-4C8F-A370-5426FB4C5849@apple.com> References: <200905060842.n468g7cX013662@zion.cs.uiuc.edu> <4A024F4D.2090606@mxc.ca> <22BEF759-CB40-4C8F-A370-5426FB4C5849@apple.com> Message-ID: <200905071845.04149.baldrick@free.fr> Hi, > >> Fix PR3754: don't mark functions that wrap MallocInst with > >> the readnone. Since MallocInst is scheduled for deletion > >> it doesn't seem worth doing anything more subtle, such as > >> having mayWriteToMemory return true for MallocInst. > > > > I don't like this fix at all. What's wrong with just making > > mayWriteToMemory return true on MallocInst? > > I agree, that seems like the obvious fix...? because that would possibly pessimize places that may start thinking that a MallocInst can modify local memory etc. Rather than analyzing all such places etc, I'd prefer to spend my time on deleting MallocInst altogether. In the meantime, this small patch fixes a real problem. Ciao, Duncan. From resistor at mac.com Thu May 7 11:57:36 2009 From: resistor at mac.com (Owen Anderson) Date: Thu, 07 May 2009 09:57:36 -0700 Subject: [llvm-commits] [llvm] r71077 - in /llvm/trunk: lib/Transforms/IPO/FunctionAttrs.cpp test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll In-Reply-To: <200905071845.04149.baldrick@free.fr> References: <200905060842.n468g7cX013662@zion.cs.uiuc.edu> <4A024F4D.2090606@mxc.ca> <22BEF759-CB40-4C8F-A370-5426FB4C5849@apple.com> <200905071845.04149.baldrick@free.fr> Message-ID: <26E7B419-0070-4F9C-8106-D7402197F1DF@mac.com> On May 7, 2009, at 9:45 AM, Duncan Sands wrote: > Hi, > >>>> Fix PR3754: don't mark functions that wrap MallocInst with >>>> the readnone. Since MallocInst is scheduled for deletion >>>> it doesn't seem worth doing anything more subtle, such as >>>> having mayWriteToMemory return true for MallocInst. >>> >>> I don't like this fix at all. What's wrong with just making >>> mayWriteToMemory return true on MallocInst? >> >> I agree, that seems like the obvious fix...? > > because that would possibly pessimize places that may start > thinking that a MallocInst can modify local memory etc. Rather > than analyzing all such places etc, I'd prefer to spend my time > on deleting MallocInst altogether. In the meantime, this small > patch fixes a real problem. > We don't do much in the way of optimization of MallocInst anyways. The only thing that this helps is that it prevents a call to malloc() from clobbering results of a memory dependence query. As I've advocated on IRC, I think we should just add LibCallAA support for saying that malloc() clobbers no known pointers, just like we can use it to say that libm functions only clobber errno. This seems like the "right" way to go to me. --Owen From baldrick at free.fr Thu May 7 12:09:32 2009 From: baldrick at free.fr (Duncan Sands) Date: Thu, 7 May 2009 19:09:32 +0200 Subject: [llvm-commits] [llvm] r71077 - in /llvm/trunk: lib/Transforms/IPO/FunctionAttrs.cpp test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll In-Reply-To: <26E7B419-0070-4F9C-8106-D7402197F1DF@mac.com> References: <200905060842.n468g7cX013662@zion.cs.uiuc.edu> <200905071845.04149.baldrick@free.fr> <26E7B419-0070-4F9C-8106-D7402197F1DF@mac.com> Message-ID: <200905071909.33340.baldrick@free.fr> Hi Owen, > We don't do much in the way of optimization of MallocInst anyways. > The only thing that this helps is that it prevents a call to malloc() > from clobbering results of a memory dependence query. As I've > advocated on IRC, I think we should just add LibCallAA support for > saying that malloc() clobbers no known pointers, just like we can use > it to say that libm functions only clobber errno. This seems like the > "right" way to go to me. "malloc" is already marked as returning a "noalias" result IIRC. Thus there is nothing to be done for malloc: it has already been done! MallocInst is different to malloc, and should just be removed from LLVM. The only problem I see with this is how to autoupgrade existing llvm that uses the malloc instruction. Some trick (GEP?) will be needed to get the size of the object being allocated. Ciao, Duncan. From isanbard at gmail.com Thu May 7 12:26:14 2009 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 07 May 2009 17:26:14 -0000 Subject: [llvm-commits] [llvm] r71165 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h include/llvm/CodeGen/DwarfWriter.h lib/Analysis/ConstantFolding.cpp lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfWriter.cpp lib/CodeGen/SelectionDAG/FastISel.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp test/Transforms/InstCombine/constant-fold-ptr-casts.ll Message-ID: <200905071726.n47HQFM0026686@zion.cs.uiuc.edu> Author: void Date: Thu May 7 12:26:14 2009 New Revision: 71165 URL: http://llvm.org/viewvc/llvm-project?rev=71165&view=rev Log: Temporarily revert r71158. It was causing a failure during a full bootstrap: checking for bcopy... no checking for getc_unlocked... Assertion failed: (0 && "Unknown SCEV kind!"), function operator(), file /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/llvmCore~obj/src/lib/Analysis/ScalarEvolution.cpp, line 511. /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmgcc42.roots/llvmgcc42~obj/src/libdecnumber/decUtility.c:360: internal compiler error: Abort trap Please submit a full bug report, with preprocessed source if appropriate. See for instructions. make[4]: *** [decUtility.o] Error 1 make[4]: *** Waiting for unfinished jobs.... Assertion failed: (0 && "Unknown SCEV kind!"), function operator(), file /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/llvmCore~obj/src/lib/Analysis/ScalarEvolution.cpp, line 511. /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmgcc42.roots/llvmgcc42~obj/src/libdecnumber/decNumber.c:5591: internal compiler error: Abort trap Please submit a full bug report, with preprocessed source if appropriate. See for instructions. make[4]: *** [decNumber.o] Error 1 make[3]: *** [all-stage2-libdecnumber] Error 2 make[3]: *** Waiting for unfinished jobs.... Removed: llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/include/llvm/CodeGen/DwarfWriter.h llvm/trunk/lib/Analysis/ConstantFolding.cpp llvm/trunk/lib/Analysis/DebugInfo.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=71165&r1=71164&r2=71165&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Thu May 7 12:26:14 2009 @@ -321,6 +321,19 @@ bool describes(const Function *F); }; + /// DIInlinedSubprogram - This is a wrapper for an inlined subprogram. + class DIInlinedSubprogram : public DIGlobal { + public: + explicit DIInlinedSubprogram(GlobalVariable *GV = 0); + DICompositeType getType() const { return getFieldAs(8); } + + /// Verify - Verify that an inlined subprogram descriptor is well formed. + bool Verify() const; + + /// dump - print inlined subprogram. + void dump() const; + }; + /// DIGlobalVariable - This is a wrapper for a global variable. class DIGlobalVariable : public DIGlobal { public: @@ -363,6 +376,7 @@ public: explicit DIBlock(GlobalVariable *GV = 0); + DICompileUnit getCompileUnit() const{ return getFieldAs(1); } DIDescriptor getContext() const { return getDescriptorField(1); } }; Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DwarfWriter.h?rev=71165&r1=71164&r2=71165&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/DwarfWriter.h (original) +++ llvm/trunk/include/llvm/CodeGen/DwarfWriter.h Thu May 7 12:26:14 2009 @@ -91,7 +91,7 @@ unsigned RecordRegionStart(GlobalVariable *V); /// RecordRegionEnd - Indicate the end of a region. - unsigned RecordRegionEnd(GlobalVariable *V); + unsigned RecordRegionEnd(GlobalVariable *V, DISubprogram &SP); /// getRecordSourceLineCount - Count source lines. unsigned getRecordSourceLineCount(); Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=71165&r1=71164&r2=71165&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Thu May 7 12:26:14 2009 @@ -16,7 +16,6 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" -#include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/ADT/SmallVector.h" @@ -384,43 +383,12 @@ // the int size is >= the ptr size. This requires knowing the width of a // pointer, so it can't be done in ConstantExpr::getCast. if (ConstantExpr *CE = dyn_cast(Ops[0])) { - if (TD && + if (TD && CE->getOpcode() == Instruction::PtrToInt && TD->getPointerSizeInBits() <= CE->getType()->getPrimitiveSizeInBits()) { - if (CE->getOpcode() == Instruction::PtrToInt) { - Constant *Input = CE->getOperand(0); - Constant *C = FoldBitCast(Input, DestTy, *TD); - return C ? C : ConstantExpr::getBitCast(Input, DestTy); - } - // If there's a constant offset added to the integer value before - // it is casted back to a pointer, see if the expression can be - // converted into a GEP. - if (CE->getOpcode() == Instruction::Add) - if (ConstantInt *L = dyn_cast(CE->getOperand(0))) - if (ConstantExpr *R = dyn_cast(CE->getOperand(1))) - if (R->getOpcode() == Instruction::PtrToInt) - if (GlobalVariable *GV = - dyn_cast(R->getOperand(0))) { - const PointerType *GVTy = cast(GV->getType()); - if (const ArrayType *AT = - dyn_cast(GVTy->getElementType())) { - const Type *ElTy = AT->getElementType(); - uint64_t PaddedSize = TD->getTypePaddedSize(ElTy); - APInt PSA(L->getValue().getBitWidth(), PaddedSize); - if (ElTy == cast(DestTy)->getElementType() && - L->getValue().urem(PSA) == 0) { - APInt ElemIdx = L->getValue().udiv(PSA); - if (ElemIdx.ult(APInt(ElemIdx.getBitWidth(), - AT->getNumElements()))) { - Constant *Index[] = { - Constant::getNullValue(CE->getType()), - ConstantInt::get(ElemIdx) - }; - return ConstantExpr::getGetElementPtr(GV, &Index[0], 2); - } - } - } - } + Constant *Input = CE->getOperand(0); + Constant *C = FoldBitCast(Input, DestTy, *TD); + return C ? C : ConstantExpr::getBitCast(Input, DestTy); } } return ConstantExpr::getCast(Opcode, Ops[0], DestTy); Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=71165&r1=71164&r2=71165&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Thu May 7 12:26:14 2009 @@ -59,6 +59,9 @@ case DW_TAG_subprogram: assert(DISubprogram(GV).Verify() && "Invalid DebugInfo value"); break; + case DW_TAG_inlined_subroutine: + assert(DIInlinedSubprogram(GV).Verify() && "Invalid DebugInfo value"); + break; case DW_TAG_lexical_block: /// FIXME. This interfers with the quality of generated code when /// during optimization. @@ -146,6 +149,8 @@ : DIType(GV, dwarf::DW_TAG_base_type) {} DISubprogram::DISubprogram(GlobalVariable *GV) : DIGlobal(GV, dwarf::DW_TAG_subprogram) {} +DIInlinedSubprogram::DIInlinedSubprogram(GlobalVariable *GV) + : DIGlobal(GV, dwarf::DW_TAG_inlined_subroutine) {} DIGlobalVariable::DIGlobalVariable(GlobalVariable *GV) : DIGlobal(GV, dwarf::DW_TAG_variable) {} DIBlock::DIBlock(GlobalVariable *GV) @@ -286,6 +291,25 @@ return true; } +/// Verify - Verify that an inlined subprogram descriptor is well formed. +bool DIInlinedSubprogram::Verify() const { + if (isNull()) + return false; + + if (getContext().isNull()) + return false; + + DICompileUnit CU = getCompileUnit(); + if (!CU.Verify()) + return false; + + DICompositeType Ty = getType(); + if (!Ty.isNull() && !Ty.Verify()) + return false; + + return true; +} + /// Verify - Verify that a global variable descriptor is well formed. bool DIGlobalVariable::Verify() const { if (isNull()) @@ -983,7 +1007,8 @@ /// dump - print descriptor. void DIDescriptor::dump() const { - cerr << " [" << dwarf::TagString(getTag()) << "]\n"; + cerr << "[" << dwarf::TagString(getTag()) << "] "; + cerr << std::hex << "[GV:" << GV << "]" << std::dec; } /// dump - print compile unit. @@ -1085,6 +1110,11 @@ DIGlobal::dump(); } +/// dump - print subprogram. +void DIInlinedSubprogram::dump() const { + DIGlobal::dump(); +} + /// dump - print global variable. void DIGlobalVariable::dump() const { cerr << " ["; getGlobal()->dump(); cerr << "] "; Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=71165&r1=71164&r2=71165&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Thu May 7 12:26:14 2009 @@ -1094,7 +1094,7 @@ /// class DbgVariable { DIVariable Var; // Variable Descriptor. - unsigned FrameIndex; // Variable frame index. + unsigned FrameIndex; // Variable frame index. public: DbgVariable(DIVariable V, unsigned I) : Var(V), FrameIndex(I) {} @@ -1280,14 +1280,32 @@ /// DbgInlinedScopeMap - Tracks inlined scopes in the current function. DenseMap > DbgInlinedScopeMap; - /// InlineInfo - Keep track of inlined functions and their location. - /// This information is used to populate debug_inlined section. + /// InlineInfo - Keep track of inlined functions and their location. This + /// information is used to populate debug_inlined section. DenseMap > InlineInfo; /// InlinedVariableScopes - Scopes information for the inlined subroutine /// variables. DenseMap InlinedVariableScopes; + /// AbstractInstanceRootMap - Map of abstract instance roots of inlined + /// functions. These are subroutine entries that contain a DW_AT_inline + /// attribute. + DenseMap AbstractInstanceRootMap; + + /// AbstractInstanceRootList - List of abstract instance roots of inlined + /// functions. These are subroutine entries that contain a DW_AT_inline + /// attribute. + SmallVector AbstractInstanceRootList; + + /// LexicalScopeToConcreteInstMap - Map a concrete instance's DIE to the + /// lexical scope it's in. + DenseMap LexicalScopeToConcreteInstMap; + + /// LexicalScopeStack - A stack of lexical scopes. The top one is the current + /// scope. + SmallVector LexicalScopeStack; + /// DebugTimer - Timer for the Dwarf debug writer. Timer *DebugTimer; @@ -1769,7 +1787,7 @@ if (Element.getTag() == dwarf::DW_TAG_subprogram) ElemDie = CreateSubprogramDIE(DW_Unit, DISubprogram(Element.getGV())); - else if (Element.getTag() == dwarf::DW_TAG_variable) // ??? + else if (Element.getTag() == dwarf::DW_TAG_variable) // ?? ElemDie = CreateGlobalVariableDIE(DW_Unit, DIGlobalVariable(Element.getGV())); else @@ -1958,6 +1976,7 @@ if (!SP.isDefinition()) { AddUInt(SPDie, DW_AT_declaration, DW_FORM_flag, 1); + // Add arguments. Do not add arguments for subprogram definition. They // will be handled through RecordVariable. if (SPTag == DW_TAG_subroutine_type) @@ -2030,6 +2049,13 @@ DbgScope *&Slot = DbgScopeMap[V]; if (Slot) return Slot; + // Don't create a new scope if we already created one for an inlined + // function. + DenseMap::iterator + II = AbstractInstanceRootMap.find(V); + if (II != AbstractInstanceRootMap.end()) + return LexicalScopeStack.back(); + DbgScope *Parent = NULL; DIBlock Block(V); @@ -2050,31 +2076,19 @@ return Slot; } - /// createInlinedSubroutineScope - Returns the scope associated with the - /// inlined subroutine. - /// - DbgScope *createInlinedSubroutineScope(DISubprogram SP, unsigned Src, - unsigned Line, unsigned Col) { - DbgScope *Scope = - new DbgInlinedSubroutineScope(NULL, SP, Src, Line, Col); - - // FIXME - Add inlined function scopes to the root so we can delete them - // later. - assert (FunctionDbgScope && "Function scope info missing!"); - FunctionDbgScope->AddScope(Scope); - return Scope; - } - /// ConstructDbgScope - Construct the components of a scope. /// void ConstructDbgScope(DbgScope *ParentScope, unsigned ParentStartID, unsigned ParentEndID, DIE *ParentDie, CompileUnit *Unit) { - // Add variables to scope. - SmallVector &Variables = ParentScope->getVariables(); - for (unsigned i = 0, N = Variables.size(); i < N; ++i) { - DIE *VariableDie = NewDbgScopeVariable(Variables[i], Unit); - if (VariableDie) ParentDie->AddChild(VariableDie); + if (LexicalScopeToConcreteInstMap.find(ParentScope) == + LexicalScopeToConcreteInstMap.end()) { + // Add variables to scope. + SmallVector &Variables = ParentScope->getVariables(); + for (unsigned i = 0, N = Variables.size(); i < N; ++i) { + DIE *VariableDie = NewDbgScopeVariable(Variables[i], Unit); + if (VariableDie) ParentDie->AddChild(VariableDie); + } } // Add nested scopes. @@ -2099,17 +2113,14 @@ ConstructDbgScope(Scope, ParentStartID, ParentEndID, ParentDie, Unit); } else { DIE *ScopeDie = NULL; - if (MainCU && TAI->doesDwarfUsesInlineInfoSection() - && Scope->isInlinedSubroutine()) { - ScopeDie = new DIE(DW_TAG_inlined_subroutine); - DIE *Origin = MainCU->getDieMapSlotFor(Scope->getDesc().getGV()); - AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin); - AddUInt(ScopeDie, DW_AT_call_file, 0, Scope->getFile()); - AddUInt(ScopeDie, DW_AT_call_line, 0, Scope->getLine()); - AddUInt(ScopeDie, DW_AT_call_column, 0, Scope->getColumn()); - } else { + + DenseMap::iterator I = + LexicalScopeToConcreteInstMap.find(Scope); + + if (I != LexicalScopeToConcreteInstMap.end()) + ScopeDie = I->second; + else ScopeDie = new DIE(DW_TAG_lexical_block); - } // Add the scope bounds. if (StartID) @@ -2165,6 +2176,29 @@ ConstructDbgScope(RootScope, 0, 0, SPDie, Unit); } + void ConstructAbstractDbgScope(DbgScope *AbsScope) { + // Exit if there is no root scope. + if (!AbsScope) return; + + DIDescriptor Desc = AbsScope->getDesc(); + if (Desc.isNull()) + return; + + // Get the subprogram debug information entry. + DISubprogram SPD(Desc.getGV()); + + // Get the compile unit context. + CompileUnit *Unit = MainCU; + if (!Unit) + Unit = &FindCompileUnit(SPD.getCompileUnit()); + + // Get the subprogram die. + DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV()); + assert(SPDie && "Missing subprogram descriptor"); + + ConstructDbgScope(AbsScope, 0, 0, SPDie, Unit); + } + /// ConstructDefaultDbgScope - Construct a default scope for the subprogram. /// void ConstructDefaultDbgScope(MachineFunction *MF) { @@ -2891,7 +2925,6 @@ DISubprogram SP(GV); std::string Name; std::string LName; - SP.getLinkageName(LName); SP.getName(Name); @@ -3087,8 +3120,10 @@ // Add to map. Slot = SubprogramDie; + // Add to context owner. Unit->getDie()->AddChild(SubprogramDie); + // Expose as global. std::string Name; Unit->AddGlobal(SP.getName(Name), SubprogramDie); @@ -3136,6 +3171,11 @@ for (unsigned j = 0, M = Values.size(); j < M; ++j) delete Values[j]; + for (DenseMap::iterator + I = AbstractInstanceRootMap.begin(), + E = AbstractInstanceRootMap.end(); I != E;++I) + delete I->second; + delete DebugTimer; } @@ -3342,6 +3382,12 @@ // information) needs to be explored. ConstructDefaultDbgScope(MF); + // Construct the DbgScope for abstract instances. + for (SmallVector::iterator + I = AbstractInstanceRootList.begin(), + E = AbstractInstanceRootList.end(); I != E; ++I) + ConstructAbstractDbgScope(*I); + DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount, MMI->getFrameMoves())); @@ -3352,6 +3398,9 @@ DbgInlinedScopeMap.clear(); InlinedVariableScopes.clear(); FunctionDbgScope = NULL; + LexicalScopeStack.clear(); + AbstractInstanceRootList.clear(); + LexicalScopeToConcreteInstMap.clear(); } Lines.clear(); @@ -3429,6 +3478,7 @@ DbgScope *Scope = getOrCreateScope(V); unsigned ID = MMI->NextLabelID(); if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID); + LexicalScopeStack.push_back(Scope); if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -3437,13 +3487,14 @@ } /// RecordRegionEnd - Indicate the end of a region. - unsigned RecordRegionEnd(GlobalVariable *V) { + unsigned RecordRegionEnd(GlobalVariable *V, DISubprogram &SP) { if (TimePassesIsEnabled) DebugTimer->startTimer(); - DbgScope *Scope = getOrCreateScope(V); unsigned ID = MMI->NextLabelID(); + DbgScope *Scope = getOrCreateScope(V); Scope->setEndLabelID(ID); + LexicalScopeStack.pop_back(); if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -3497,28 +3548,59 @@ if (TimePassesIsEnabled) DebugTimer->startTimer(); - std::string Dir, Fn; - unsigned Src = GetOrCreateSourceID(CU.getDirectory(Dir), - CU.getFilename(Fn)); - DbgScope *Scope = createInlinedSubroutineScope(SP, Src, Line, Col); - Scope->setStartLabelID(LabelID); - MMI->RecordUsedDbgLabel(LabelID); GlobalVariable *GV = SP.getGV(); + DenseMap::iterator + II = AbstractInstanceRootMap.find(GV); - DenseMap >::iterator - SI = DbgInlinedScopeMap.find(GV); + if (II == AbstractInstanceRootMap.end()) { + // Create an abstract instance entry for this inlined function if it + // doesn't already exist. + DbgScope *Scope = new DbgScope(NULL, DIDescriptor(GV)); + + // Get the compile unit context. + CompileUnit *Unit = &FindCompileUnit(SP.getCompileUnit()); + DIE *SPDie = Unit->getDieMapSlotFor(GV); + assert(SPDie && "Missing subprogram descriptor!"); + + // Mark as being inlined. This makes this subprogram entry an abstract + // instance root. + // FIXME: Our debugger doesn't care about the value of DW_AT_inline, only + // that it's defined. It probably won't change in the future, but this + // could be more elegant. + AddUInt(SPDie, DW_AT_inline, 0, DW_INL_declared_not_inlined); + + // Keep track of the scope that's inlined into this function. + DenseMap >::iterator + SI = DbgInlinedScopeMap.find(GV); - if (SI == DbgInlinedScopeMap.end()) - DbgInlinedScopeMap[GV].push_back(Scope); - else - SI->second.push_back(Scope); + if (SI == DbgInlinedScopeMap.end()) + DbgInlinedScopeMap[GV].push_back(Scope); + else + SI->second.push_back(Scope); + + // Track the start label for this inlined function. + DenseMap >::iterator + I = InlineInfo.find(GV); - DenseMap >::iterator - I = InlineInfo.find(GV); - if (I == InlineInfo.end()) - InlineInfo[GV].push_back(LabelID); - else - I->second.push_back(LabelID); + if (I == InlineInfo.end()) + InlineInfo[GV].push_back(LabelID); + else + I->second.push_back(LabelID); + + AbstractInstanceRootMap[GV] = Scope; + AbstractInstanceRootList.push_back(Scope); + } + + // Create a concrete inlined instance for this inlined function. + DIE *ScopeDie = new DIE(DW_TAG_inlined_subroutine); + CompileUnit *Unit = &FindCompileUnit(SP.getCompileUnit()); + DIE *Origin = Unit->getDieMapSlotFor(GV); + AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin); + AddUInt(ScopeDie, DW_AT_call_file, 0, Unit->getID()); + AddUInt(ScopeDie, DW_AT_call_line, 0, Line); + AddUInt(ScopeDie, DW_AT_call_column, 0, Col); + + LexicalScopeToConcreteInstMap[LexicalScopeStack.back()] = ScopeDie; if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -3528,6 +3610,7 @@ /// RecordInlinedFnEnd - Indicate the end of inlined subroutine. unsigned RecordInlinedFnEnd(DISubprogram &SP) { + // FIXME: This function never seems to be called!! if (!TAI->doesDwarfUsesInlineInfoSection()) return 0; @@ -4729,8 +4812,8 @@ } /// RecordRegionEnd - Indicate the end of a region. -unsigned DwarfWriter::RecordRegionEnd(GlobalVariable *V) { - return DD->RecordRegionEnd(V); +unsigned DwarfWriter::RecordRegionEnd(GlobalVariable *V, DISubprogram &SP) { + return DD->RecordRegionEnd(V, SP); } /// getRecordSourceLineCount - Count source lines. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=71165&r1=71164&r2=71165&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Thu May 7 12:26:14 2009 @@ -365,7 +365,8 @@ BuildMI(MBB, DL, II).addImm(ID); } else { const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); - ID = DW->RecordRegionEnd(cast(REI->getContext())); + ID = DW->RecordRegionEnd(cast(REI->getContext()), + Subprogram); BuildMI(MBB, DL, II).addImm(ID); } } @@ -391,6 +392,7 @@ // FIXME : Why DebugLoc is reset at the beginning of each block ? if (PrevLoc.isUnknown()) return true; + // Record the source line. unsigned Line = Subprogram.getLineNumber(); setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID( @@ -410,10 +412,10 @@ unsigned Line = Subprogram.getLineNumber(); MF.setDefaultDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID( CompileUnit.getGV(), Line, 0))); - if (DW && DW->ShouldEmitDwarfDebug()) { + + if (DW && DW->ShouldEmitDwarfDebug()) // llvm.dbg.func_start also defines beginning of function scope. DW->RecordRegionStart(cast(FSI->getSubprogram())); - } } return true; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=71165&r1=71164&r2=71165&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu May 7 12:26:14 2009 @@ -3944,7 +3944,8 @@ } unsigned LabelID = - DW->RecordRegionEnd(cast(REI.getContext())); + DW->RecordRegionEnd(cast(REI.getContext()), + Subprogram); DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), getRoot(), LabelID)); } Removed: llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll?rev=71164&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll (removed) @@ -1,18 +0,0 @@ -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i32 2143034560} - -; Instcombine should be able to completely fold this code. - -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" -target triple = "i686-apple-darwin8" - - at bar = constant [3 x i64] [i64 9220983451228067448, i64 9220983451228067449, i64 9220983450959631991], align 8 - -define i32 @foo() nounwind { -entry: - %tmp87.2 = load i64* inttoptr (i32 add (i32 16, i32 ptrtoint ([3 x i64]* @bar to i32)) to i64*), align 8 - %t0 = bitcast i64 %tmp87.2 to double - %tmp9192.2 = fptrunc double %t0 to float - %t1 = bitcast float %tmp9192.2 to i32 - ret i32 %t1 -} - From isanbard at gmail.com Thu May 7 12:27:10 2009 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 7 May 2009 10:27:10 -0700 Subject: [llvm-commits] [llvm] r71158 - in /llvm/trunk: lib/Analysis/ConstantFolding.cpp test/Transforms/InstCombine/constant-fold-ptr-casts.ll In-Reply-To: <200905071425.n47EPFEb020594@zion.cs.uiuc.edu> References: <200905071425.n47EPFEb020594@zion.cs.uiuc.edu> Message-ID: <16e5fdf90905071027v16f74207hc5c809b1212e32cd@mail.gmail.com> Dan, This appears to have broken a full bootstrap. Could you investigate please? See here for details: http://blamebot.apple.com:8020/builders/full-llvm-OSX/builds/1486/steps/shell/logs/stdio -bw On Thu, May 7, 2009 at 7:25 AM, Dan Gohman wrote: > Author: djg > Date: Thu May ?7 09:24:56 2009 > New Revision: 71158 > > URL: http://llvm.org/viewvc/llvm-project?rev=71158&view=rev > Log: > Constant-fold ptrtoint+add+inttoptr to gep when the pointer is an > array and the add is within range. This helps simplify expressions > expanded by ScalarEvolutionExpander. > > Added: > ? ?llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll > Modified: > ? ?llvm/trunk/lib/Analysis/ConstantFolding.cpp > > Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=71158&r1=71157&r2=71158&view=diff > > ============================================================================== > --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) > +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Thu May ?7 09:24:56 2009 > @@ -16,6 +16,7 @@ > ?#include "llvm/Constants.h" > ?#include "llvm/DerivedTypes.h" > ?#include "llvm/Function.h" > +#include "llvm/GlobalVariable.h" > ?#include "llvm/Instructions.h" > ?#include "llvm/Intrinsics.h" > ?#include "llvm/ADT/SmallVector.h" > @@ -383,12 +384,43 @@ > ? ? // the int size is >= the ptr size. ?This requires knowing the width of a > ? ? // pointer, so it can't be done in ConstantExpr::getCast. > ? ? if (ConstantExpr *CE = dyn_cast(Ops[0])) { > - ? ? ?if (TD && CE->getOpcode() == Instruction::PtrToInt && > + ? ? ?if (TD && > ? ? ? ? ? TD->getPointerSizeInBits() <= > ? ? ? ? ? CE->getType()->getPrimitiveSizeInBits()) { > - ? ? ? ?Constant *Input = CE->getOperand(0); > - ? ? ? ?Constant *C = FoldBitCast(Input, DestTy, *TD); > - ? ? ? ?return C ? C : ConstantExpr::getBitCast(Input, DestTy); > + ? ? ? ?if (CE->getOpcode() == Instruction::PtrToInt) { > + ? ? ? ? ?Constant *Input = CE->getOperand(0); > + ? ? ? ? ?Constant *C = FoldBitCast(Input, DestTy, *TD); > + ? ? ? ? ?return C ? C : ConstantExpr::getBitCast(Input, DestTy); > + ? ? ? ?} > + ? ? ? ?// If there's a constant offset added to the integer value before > + ? ? ? ?// it is casted back to a pointer, see if the expression can be > + ? ? ? ?// converted into a GEP. > + ? ? ? ?if (CE->getOpcode() == Instruction::Add) > + ? ? ? ? ?if (ConstantInt *L = dyn_cast(CE->getOperand(0))) > + ? ? ? ? ? ?if (ConstantExpr *R = dyn_cast(CE->getOperand(1))) > + ? ? ? ? ? ? ?if (R->getOpcode() == Instruction::PtrToInt) > + ? ? ? ? ? ? ? ?if (GlobalVariable *GV = > + ? ? ? ? ? ? ? ? ? ? ?dyn_cast(R->getOperand(0))) { > + ? ? ? ? ? ? ? ? ?const PointerType *GVTy = cast(GV->getType()); > + ? ? ? ? ? ? ? ? ?if (const ArrayType *AT = > + ? ? ? ? ? ? ? ? ? ? ? ?dyn_cast(GVTy->getElementType())) { > + ? ? ? ? ? ? ? ? ? ?const Type *ElTy = AT->getElementType(); > + ? ? ? ? ? ? ? ? ? ?uint64_t PaddedSize = TD->getTypePaddedSize(ElTy); > + ? ? ? ? ? ? ? ? ? ?APInt PSA(L->getValue().getBitWidth(), PaddedSize); > + ? ? ? ? ? ? ? ? ? ?if (ElTy == cast(DestTy)->getElementType() && > + ? ? ? ? ? ? ? ? ? ? ? ?L->getValue().urem(PSA) == 0) { > + ? ? ? ? ? ? ? ? ? ? ?APInt ElemIdx = L->getValue().udiv(PSA); > + ? ? ? ? ? ? ? ? ? ? ?if (ElemIdx.ult(APInt(ElemIdx.getBitWidth(), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?AT->getNumElements()))) { > + ? ? ? ? ? ? ? ? ? ? ? ?Constant *Index[] = { > + ? ? ? ? ? ? ? ? ? ? ? ? ?Constant::getNullValue(CE->getType()), > + ? ? ? ? ? ? ? ? ? ? ? ? ?ConstantInt::get(ElemIdx) > + ? ? ? ? ? ? ? ? ? ? ? ?}; > + ? ? ? ? ? ? ? ? ? ? ? ?return ConstantExpr::getGetElementPtr(GV, &Index[0], 2); > + ? ? ? ? ? ? ? ? ? ? ?} > + ? ? ? ? ? ? ? ? ? ?} > + ? ? ? ? ? ? ? ? ?} > + ? ? ? ? ? ? ? ?} > ? ? ? } > ? ? } > ? ? return ConstantExpr::getCast(Opcode, Ops[0], DestTy); > > Added: llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll?rev=71158&view=auto > > ============================================================================== > --- llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll (added) > +++ llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll Thu May ?7 09:24:56 2009 > @@ -0,0 +1,18 @@ > +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i32 2143034560} > + > +; Instcombine should be able to completely fold this code. > + > +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" > +target triple = "i686-apple-darwin8" > + > + at bar = constant [3 x i64] [i64 9220983451228067448, i64 9220983451228067449, i64 9220983450959631991], align 8 > + > +define i32 @foo() nounwind { > +entry: > + ? ? ? %tmp87.2 = load i64* inttoptr (i32 add (i32 16, i32 ptrtoint ([3 x i64]* @bar to i32)) to i64*), align 8 > + ? ? ? %t0 = bitcast i64 %tmp87.2 to double > + ? ? ? %tmp9192.2 = fptrunc double %t0 to float > + ? ? ? %t1 = bitcast float %tmp9192.2 to i32 > + ? ? ? ret i32 %t1 > +} > + > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From anton at korobeynikov.info Thu May 7 13:02:19 2009 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Thu, 7 May 2009 22:02:19 +0400 Subject: [llvm-commits] [llvm] r71149 - /llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp In-Reply-To: <200905070531.n475Vu6M024542@zion.cs.uiuc.edu> References: <200905070531.n475Vu6M024542@zion.cs.uiuc.edu> Message-ID: Hello, Evan > - ? ?sprintf (name, "udata.%d.# UDATA", BSSSections.size()); > + ? ?sprintf (name, "udata.%d.# UDATA", (int)BSSSections.size()); Why don't use %u instead of cast? -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From baldrick at free.fr Thu May 7 13:08:34 2009 From: baldrick at free.fr (Duncan Sands) Date: Thu, 07 May 2009 18:08:34 -0000 Subject: [llvm-commits] [llvm] r71168 - in /llvm/trunk: lib/Analysis/CaptureTracking.cpp test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll Message-ID: <200905071808.n47I8Yaj028022@zion.cs.uiuc.edu> Author: baldrick Date: Thu May 7 13:08:34 2009 New Revision: 71168 URL: http://llvm.org/viewvc/llvm-project?rev=71168&view=rev Log: Revert r70876 and add a testcase (@c7) showing the problem: bits captured, but the pointer marked nocapture. In fact I now recall that this problem is why only readnone functions returning void were considered before! However keep a small fix that was also in r70876: a readnone function returning void can result in bits being captured if it unwinds, so test for this. Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=71168&r1=71167&r2=71168&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original) +++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Thu May 7 13:08:34 2009 @@ -49,7 +49,13 @@ switch (I->getOpcode()) { case Instruction::Call: case Instruction::Invoke: { - CallSite CS(I); + CallSite CS = CallSite::get(I); + // Not captured if the callee is readonly, doesn't return a copy through + // its return value and doesn't unwind (a readonly function can leak bits + // by throwing an exception or not depending on the input value). + if (CS.onlyReadsMemory() && CS.doesNotThrow() && + I->getType() == Type::VoidTy) + break; // Not captured if only passed via 'nocapture' arguments. Note that // calling a function pointer does not in itself cause the pointer to @@ -58,69 +64,46 @@ // that loading a value from a pointer does not cause the pointer to be // captured, even though the loaded value might be the pointer itself // (think of self-referential objects). - bool MayBeCaptured = false; CallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end(); for (CallSite::arg_iterator A = B; A != E; ++A) - if (A->get() == V && !CS.paramHasAttr(A-B+1, Attribute::NoCapture)) { - // The parameter is not marked 'nocapture' - handled by generic code - // below. - MayBeCaptured = true; - break; - } - if (!MayBeCaptured) - // Only passed via 'nocapture' arguments, or is the called function - - // not captured. - continue; - if (!CS.doesNotThrow()) - // Even a readonly function can leak bits by throwing an exception or - // not depending on the input value. - return true; - // Fall through to the generic code. + if (A->get() == V && !CS.paramHasAttr(A - B + 1, Attribute::NoCapture)) + // The parameter is not marked 'nocapture' - captured. + return true; + // Only passed via 'nocapture' arguments, or is the called function - not + // captured. break; } case Instruction::Free: // Freeing a pointer does not cause it to be captured. - continue; + break; case Instruction::Load: // Loading from a pointer does not cause it to be captured. - continue; + break; case Instruction::Ret: if (ReturnCaptures) return true; - continue; + break; case Instruction::Store: if (V == I->getOperand(0)) // Stored the pointer - it may be captured. return true; // Storing to the pointee does not cause the pointer to be captured. - continue; - } - - // If it may write to memory and isn't one of the special cases above, - // be conservative and assume the pointer is captured. - if (I->mayWriteToMemory()) - return true; - - // If the instruction doesn't write memory, it can only capture by - // having its own value depend on the input value. - const Type* Ty = I->getType(); - if (Ty == Type::VoidTy) - // The value of an instruction can't be a copy if it can't contain any - // information. - continue; - if (!isa(Ty)) - // At the moment, we don't track non-pointer values, so be conservative - // and assume the pointer is captured. - // FIXME: Track these too. This would need to be done very carefully as - // it is easy to leak bits via control flow if integer values are allowed. + break; + case Instruction::BitCast: + case Instruction::GetElementPtr: + case Instruction::PHI: + case Instruction::Select: + // The original value is not captured via this if the new value isn't. + for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end(); + UI != UE; ++UI) { + Use *U = &UI.getUse(); + if (Visited.insert(U)) + Worklist.push_back(U); + } + break; + default: + // Something else - be conservative and say it is captured. return true; - - // The original value is not captured via this if the new value isn't. - for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end(); - UI != UE; ++UI) { - Use *U = &UI.getUse(); - if (Visited.insert(U)) - Worklist.push_back(U); } } Modified: llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll?rev=71168&r1=71167&r2=71168&view=diff ============================================================================== --- llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll (original) +++ llvm/trunk/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll Thu May 7 13:08:34 2009 @@ -49,6 +49,21 @@ ret i1 1 } +define i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind { + %tmp = ptrtoint i32* %q to i32 + %tmp2 = lshr i32 %tmp, %bitno + %bit = and i32 %tmp2, 1 + %lookup = getelementptr [2 x i1]* @lookup_table, i32 0, i32 %bit + ret i1* %lookup +} + +define i1 @c7(i32* %q, i32 %bitno) { + %ptr = call i1* @lookup_bit(i32* %q, i32 %bitno) + %val = load i1* %ptr + ret i1 %val +} + + define i32 @nc1(i32* %q, i32* %p, i1 %b) { e: br label %l @@ -79,14 +94,8 @@ ret void } -define void @nc5(void (i8*)* %p, i8* %r) { - call void %p(i8* %r) - call void %p(i8* nocapture %r) - ret void -} - -declare i8* @external_identity(i8*) readonly nounwind -define void @nc6(i8* %p) { - call i8* @external_identity(i8* %p) +define void @nc5(void (i8*)* %f, i8* %p) { + call void %f(i8* %p) readonly nounwind + call void %f(i8* nocapture %p) ret void } From gohman at apple.com Thu May 7 14:23:22 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 07 May 2009 19:23:22 -0000 Subject: [llvm-commits] [llvm] r71173 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200905071923.n47JNMYv030532@zion.cs.uiuc.edu> Author: djg Date: Thu May 7 14:23:21 2009 New Revision: 71173 URL: http://llvm.org/viewvc/llvm-project?rev=71173&view=rev Log: SCEVComplexityCompare's new code was missing SCEVUDivExpr. Implement the SCEVUDivExpr case. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71173&r1=71172&r2=71173&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Thu May 7 14:23:21 2009 @@ -502,6 +502,20 @@ return LC->getNumOperands() < RC->getNumOperands(); } + // Lexicographically compare udiv expressions. + if (const SCEVUDivExpr *LC = dyn_cast(LHS)) { + const SCEVUDivExpr *RC = cast(RHS); + if (operator()(LC->getLHS(), RC->getLHS())) + return true; + if (operator()(RC->getLHS(), LC->getLHS())) + return false; + if (operator()(LC->getRHS(), RC->getRHS())) + return true; + if (operator()(RC->getRHS(), LC->getRHS())) + return false; + return false; + } + // Compare cast expressions by operand. if (const SCEVCastExpr *LC = dyn_cast(LHS)) { const SCEVCastExpr *RC = cast(RHS); From daniel at zuster.org Thu May 7 14:26:06 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 7 May 2009 12:26:06 -0700 Subject: [llvm-commits] [llvm] r71165 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h include/llvm/CodeGen/DwarfWriter.h lib/Analysis/ConstantFolding.cpp lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfWriter.cpp lib/CodeGen/SelectionDAG/FastIS Message-ID: <6a8523d60905071226o556b0a0dmd5317dad403d0dad@mail.gmail.com> This commit does a lot more than just revert 71158, and I'm getting a lot of asserts in debug info generation now. Can you revert this and re-revert 71158? - Daniel On Thu, May 7, 2009 at 10:26 AM, Bill Wendling wrote: > Author: void > Date: Thu May 7 12:26:14 2009 > New Revision: 71165 > > URL: http://llvm.org/viewvc/llvm-project?rev=71165&view=rev > Log: > Temporarily revert r71158. It was causing a failure during a full > bootstrap: > > checking for bcopy... no > checking for getc_unlocked... Assertion failed: (0 && "Unknown SCEV > kind!"), function operator(), file > /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/llvmCore~obj/src/lib/Analysis/ScalarEvolution.cpp, > line 511. > /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmgcc42.roots/llvmgcc42~obj/src/libdecnumber/decUtility.c:360: > internal compiler error: Abort trap > Please submit a full bug report, > with preprocessed source if appropriate. > See for instructions. > make[4]: *** [decUtility.o] Error 1 > make[4]: *** Waiting for unfinished jobs.... > Assertion failed: (0 && "Unknown SCEV kind!"), function operator(), file > /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/llvmCore~obj/src/lib/Analysis/ScalarEvolution.cpp, > line 511. > /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmgcc42.roots/llvmgcc42~obj/src/libdecnumber/decNumber.c:5591: > internal compiler error: Abort trap > Please submit a full bug report, > with preprocessed source if appropriate. > See for instructions. > make[4]: *** [decNumber.o] Error 1 > make[3]: *** [all-stage2-libdecnumber] Error 2 > make[3]: *** Waiting for unfinished jobs.... > > > Removed: > llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll > Modified: > llvm/trunk/include/llvm/Analysis/DebugInfo.h > llvm/trunk/include/llvm/CodeGen/DwarfWriter.h > llvm/trunk/lib/Analysis/ConstantFolding.cpp > llvm/trunk/lib/Analysis/DebugInfo.cpp > llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp > llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp > llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp > > Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=71165&r1=71164&r2=71165&view=diff > > > ============================================================================== > --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) > +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Thu May 7 12:26:14 2009 > @@ -321,6 +321,19 @@ > bool describes(const Function *F); > }; > > + /// DIInlinedSubprogram - This is a wrapper for an inlined subprogram. > + class DIInlinedSubprogram : public DIGlobal { > + public: > + explicit DIInlinedSubprogram(GlobalVariable *GV = 0); > + DICompositeType getType() const { return > getFieldAs(8); } > + > + /// Verify - Verify that an inlined subprogram descriptor is well > formed. > + bool Verify() const; > + > + /// dump - print inlined subprogram. > + void dump() const; > + }; > + > /// DIGlobalVariable - This is a wrapper for a global variable. > class DIGlobalVariable : public DIGlobal { > public: > @@ -363,6 +376,7 @@ > public: > explicit DIBlock(GlobalVariable *GV = 0); > > + DICompileUnit getCompileUnit() const{ return > getFieldAs(1); } > DIDescriptor getContext() const { return getDescriptorField(1); } > }; > > > Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DwarfWriter.h?rev=71165&r1=71164&r2=71165&view=diff > > > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/DwarfWriter.h (original) > +++ llvm/trunk/include/llvm/CodeGen/DwarfWriter.h Thu May 7 12:26:14 2009 > @@ -91,7 +91,7 @@ > unsigned RecordRegionStart(GlobalVariable *V); > > /// RecordRegionEnd - Indicate the end of a region. > - unsigned RecordRegionEnd(GlobalVariable *V); > + unsigned RecordRegionEnd(GlobalVariable *V, DISubprogram &SP); > > /// getRecordSourceLineCount - Count source lines. > unsigned getRecordSourceLineCount(); > > Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=71165&r1=71164&r2=71165&view=diff > > > ============================================================================== > --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) > +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Thu May 7 12:26:14 2009 > @@ -16,7 +16,6 @@ > #include "llvm/Constants.h" > #include "llvm/DerivedTypes.h" > #include "llvm/Function.h" > -#include "llvm/GlobalVariable.h" > #include "llvm/Instructions.h" > #include "llvm/Intrinsics.h" > #include "llvm/ADT/SmallVector.h" > @@ -384,43 +383,12 @@ > // the int size is >= the ptr size. This requires knowing the width of > a > // pointer, so it can't be done in ConstantExpr::getCast. > if (ConstantExpr *CE = dyn_cast(Ops[0])) { > - if (TD && > + if (TD && CE->getOpcode() == Instruction::PtrToInt && > TD->getPointerSizeInBits() <= > CE->getType()->getPrimitiveSizeInBits()) { > - if (CE->getOpcode() == Instruction::PtrToInt) { > - Constant *Input = CE->getOperand(0); > - Constant *C = FoldBitCast(Input, DestTy, *TD); > - return C ? C : ConstantExpr::getBitCast(Input, DestTy); > - } > - // If there's a constant offset added to the integer value before > - // it is casted back to a pointer, see if the expression can be > - // converted into a GEP. > - if (CE->getOpcode() == Instruction::Add) > - if (ConstantInt *L = dyn_cast(CE->getOperand(0))) > - if (ConstantExpr *R = > dyn_cast(CE->getOperand(1))) > - if (R->getOpcode() == Instruction::PtrToInt) > - if (GlobalVariable *GV = > - dyn_cast(R->getOperand(0))) { > - const PointerType *GVTy = > cast(GV->getType()); > - if (const ArrayType *AT = > - dyn_cast(GVTy->getElementType())) { > - const Type *ElTy = AT->getElementType(); > - uint64_t PaddedSize = TD->getTypePaddedSize(ElTy); > - APInt PSA(L->getValue().getBitWidth(), PaddedSize); > - if (ElTy == > cast(DestTy)->getElementType() && > - L->getValue().urem(PSA) == 0) { > - APInt ElemIdx = L->getValue().udiv(PSA); > - if (ElemIdx.ult(APInt(ElemIdx.getBitWidth(), > - AT->getNumElements()))) { > - Constant *Index[] = { > - Constant::getNullValue(CE->getType()), > - ConstantInt::get(ElemIdx) > - }; > - return ConstantExpr::getGetElementPtr(GV, > &Index[0], 2); > - } > - } > - } > - } > + Constant *Input = CE->getOperand(0); > + Constant *C = FoldBitCast(Input, DestTy, *TD); > + return C ? C : ConstantExpr::getBitCast(Input, DestTy); > } > } > return ConstantExpr::getCast(Opcode, Ops[0], DestTy); > > Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=71165&r1=71164&r2=71165&view=diff > > > ============================================================================== > --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) > +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Thu May 7 12:26:14 2009 > @@ -59,6 +59,9 @@ > case DW_TAG_subprogram: > assert(DISubprogram(GV).Verify() && "Invalid DebugInfo value"); > break; > + case DW_TAG_inlined_subroutine: > + assert(DIInlinedSubprogram(GV).Verify() && "Invalid DebugInfo value"); > + break; > case DW_TAG_lexical_block: > /// FIXME. This interfers with the quality of generated code when > /// during optimization. > @@ -146,6 +149,8 @@ > : DIType(GV, dwarf::DW_TAG_base_type) {} > DISubprogram::DISubprogram(GlobalVariable *GV) > : DIGlobal(GV, dwarf::DW_TAG_subprogram) {} > +DIInlinedSubprogram::DIInlinedSubprogram(GlobalVariable *GV) > + : DIGlobal(GV, dwarf::DW_TAG_inlined_subroutine) {} > DIGlobalVariable::DIGlobalVariable(GlobalVariable *GV) > : DIGlobal(GV, dwarf::DW_TAG_variable) {} > DIBlock::DIBlock(GlobalVariable *GV) > @@ -286,6 +291,25 @@ > return true; > } > > +/// Verify - Verify that an inlined subprogram descriptor is well formed. > +bool DIInlinedSubprogram::Verify() const { > + if (isNull()) > + return false; > + > + if (getContext().isNull()) > + return false; > + > + DICompileUnit CU = getCompileUnit(); > + if (!CU.Verify()) > + return false; > + > + DICompositeType Ty = getType(); > + if (!Ty.isNull() && !Ty.Verify()) > + return false; > + > + return true; > +} > + > /// Verify - Verify that a global variable descriptor is well formed. > bool DIGlobalVariable::Verify() const { > if (isNull()) > @@ -983,7 +1007,8 @@ > > /// dump - print descriptor. > void DIDescriptor::dump() const { > - cerr << " [" << dwarf::TagString(getTag()) << "]\n"; > + cerr << "[" << dwarf::TagString(getTag()) << "] "; > + cerr << std::hex << "[GV:" << GV << "]" << std::dec; > } > > /// dump - print compile unit. > @@ -1085,6 +1110,11 @@ > DIGlobal::dump(); > } > > +/// dump - print subprogram. > +void DIInlinedSubprogram::dump() const { > + DIGlobal::dump(); > +} > + > /// dump - print global variable. > void DIGlobalVariable::dump() const { > cerr << " ["; getGlobal()->dump(); cerr << "] "; > > Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=71165&r1=71164&r2=71165&view=diff > > > ============================================================================== > --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) > +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Thu May 7 12:26:14 > 2009 > @@ -1094,7 +1094,7 @@ > /// > class DbgVariable { > DIVariable Var; // Variable Descriptor. > - unsigned FrameIndex; // Variable frame index. > + unsigned FrameIndex; // Variable frame index. > public: > DbgVariable(DIVariable V, unsigned I) : Var(V), FrameIndex(I) {} > > @@ -1280,14 +1280,32 @@ > /// DbgInlinedScopeMap - Tracks inlined scopes in the current function. > DenseMap > > DbgInlinedScopeMap; > > - /// InlineInfo - Keep track of inlined functions and their location. > - /// This information is used to populate debug_inlined section. > + /// InlineInfo - Keep track of inlined functions and their location. > This > + /// information is used to populate debug_inlined section. > DenseMap > InlineInfo; > > /// InlinedVariableScopes - Scopes information for the inlined subroutine > /// variables. > DenseMap InlinedVariableScopes; > > + /// AbstractInstanceRootMap - Map of abstract instance roots of inlined > + /// functions. These are subroutine entries that contain a DW_AT_inline > + /// attribute. > + DenseMap AbstractInstanceRootMap; > + > + /// AbstractInstanceRootList - List of abstract instance roots of > inlined > + /// functions. These are subroutine entries that contain a DW_AT_inline > + /// attribute. > + SmallVector AbstractInstanceRootList; > + > + /// LexicalScopeToConcreteInstMap - Map a concrete instance's DIE to the > + /// lexical scope it's in. > + DenseMap LexicalScopeToConcreteInstMap; > + > + /// LexicalScopeStack - A stack of lexical scopes. The top one is the > current > + /// scope. > + SmallVector LexicalScopeStack; > + > /// DebugTimer - Timer for the Dwarf debug writer. > Timer *DebugTimer; > > @@ -1769,7 +1787,7 @@ > if (Element.getTag() == dwarf::DW_TAG_subprogram) > ElemDie = CreateSubprogramDIE(DW_Unit, > DISubprogram(Element.getGV())); > - else if (Element.getTag() == dwarf::DW_TAG_variable) // ??? > + else if (Element.getTag() == dwarf::DW_TAG_variable) // ?? > ElemDie = CreateGlobalVariableDIE(DW_Unit, > > DIGlobalVariable(Element.getGV())); > else > @@ -1958,6 +1976,7 @@ > > if (!SP.isDefinition()) { > AddUInt(SPDie, DW_AT_declaration, DW_FORM_flag, 1); > + > // Add arguments. Do not add arguments for subprogram definition. > They > // will be handled through RecordVariable. > if (SPTag == DW_TAG_subroutine_type) > @@ -2030,6 +2049,13 @@ > DbgScope *&Slot = DbgScopeMap[V]; > if (Slot) return Slot; > > + // Don't create a new scope if we already created one for an inlined > + // function. > + DenseMap::iterator > + II = AbstractInstanceRootMap.find(V); > + if (II != AbstractInstanceRootMap.end()) > + return LexicalScopeStack.back(); > + > DbgScope *Parent = NULL; > DIBlock Block(V); > > @@ -2050,31 +2076,19 @@ > return Slot; > } > > - /// createInlinedSubroutineScope - Returns the scope associated with the > - /// inlined subroutine. > - /// > - DbgScope *createInlinedSubroutineScope(DISubprogram SP, unsigned Src, > - unsigned Line, unsigned Col) { > - DbgScope *Scope = > - new DbgInlinedSubroutineScope(NULL, SP, Src, Line, Col); > - > - // FIXME - Add inlined function scopes to the root so we can delete > them > - // later. > - assert (FunctionDbgScope && "Function scope info missing!"); > - FunctionDbgScope->AddScope(Scope); > - return Scope; > - } > - > /// ConstructDbgScope - Construct the components of a scope. > /// > void ConstructDbgScope(DbgScope *ParentScope, > unsigned ParentStartID, unsigned ParentEndID, > DIE *ParentDie, CompileUnit *Unit) { > - // Add variables to scope. > - SmallVector &Variables = > ParentScope->getVariables(); > - for (unsigned i = 0, N = Variables.size(); i < N; ++i) { > - DIE *VariableDie = NewDbgScopeVariable(Variables[i], Unit); > - if (VariableDie) ParentDie->AddChild(VariableDie); > + if (LexicalScopeToConcreteInstMap.find(ParentScope) == > + LexicalScopeToConcreteInstMap.end()) { > + // Add variables to scope. > + SmallVector &Variables = > ParentScope->getVariables(); > + for (unsigned i = 0, N = Variables.size(); i < N; ++i) { > + DIE *VariableDie = NewDbgScopeVariable(Variables[i], Unit); > + if (VariableDie) ParentDie->AddChild(VariableDie); > + } > } > > // Add nested scopes. > @@ -2099,17 +2113,14 @@ > ConstructDbgScope(Scope, ParentStartID, ParentEndID, ParentDie, > Unit); > } else { > DIE *ScopeDie = NULL; > - if (MainCU && TAI->doesDwarfUsesInlineInfoSection() > - && Scope->isInlinedSubroutine()) { > - ScopeDie = new DIE(DW_TAG_inlined_subroutine); > - DIE *Origin = > MainCU->getDieMapSlotFor(Scope->getDesc().getGV()); > - AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, > Origin); > - AddUInt(ScopeDie, DW_AT_call_file, 0, Scope->getFile()); > - AddUInt(ScopeDie, DW_AT_call_line, 0, Scope->getLine()); > - AddUInt(ScopeDie, DW_AT_call_column, 0, Scope->getColumn()); > - } else { > + > + DenseMap::iterator I = > + LexicalScopeToConcreteInstMap.find(Scope); > + > + if (I != LexicalScopeToConcreteInstMap.end()) > + ScopeDie = I->second; > + else > ScopeDie = new DIE(DW_TAG_lexical_block); > - } > > // Add the scope bounds. > if (StartID) > @@ -2165,6 +2176,29 @@ > ConstructDbgScope(RootScope, 0, 0, SPDie, Unit); > } > > + void ConstructAbstractDbgScope(DbgScope *AbsScope) { > + // Exit if there is no root scope. > + if (!AbsScope) return; > + > + DIDescriptor Desc = AbsScope->getDesc(); > + if (Desc.isNull()) > + return; > + > + // Get the subprogram debug information entry. > + DISubprogram SPD(Desc.getGV()); > + > + // Get the compile unit context. > + CompileUnit *Unit = MainCU; > + if (!Unit) > + Unit = &FindCompileUnit(SPD.getCompileUnit()); > + > + // Get the subprogram die. > + DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV()); > + assert(SPDie && "Missing subprogram descriptor"); > + > + ConstructDbgScope(AbsScope, 0, 0, SPDie, Unit); > + } > + > /// ConstructDefaultDbgScope - Construct a default scope for the > subprogram. > /// > void ConstructDefaultDbgScope(MachineFunction *MF) { > @@ -2891,7 +2925,6 @@ > DISubprogram SP(GV); > std::string Name; > std::string LName; > - > SP.getLinkageName(LName); > SP.getName(Name); > > @@ -3087,8 +3120,10 @@ > > // Add to map. > Slot = SubprogramDie; > + > // Add to context owner. > Unit->getDie()->AddChild(SubprogramDie); > + > // Expose as global. > std::string Name; > Unit->AddGlobal(SP.getName(Name), SubprogramDie); > @@ -3136,6 +3171,11 @@ > for (unsigned j = 0, M = Values.size(); j < M; ++j) > delete Values[j]; > > + for (DenseMap::iterator > + I = AbstractInstanceRootMap.begin(), > + E = AbstractInstanceRootMap.end(); I != E;++I) > + delete I->second; > + > delete DebugTimer; > } > > @@ -3342,6 +3382,12 @@ > // information) needs to be explored. > ConstructDefaultDbgScope(MF); > > + // Construct the DbgScope for abstract instances. > + for (SmallVector::iterator > + I = AbstractInstanceRootList.begin(), > + E = AbstractInstanceRootList.end(); I != E; ++I) > + ConstructAbstractDbgScope(*I); > + > DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount, > MMI->getFrameMoves())); > > @@ -3352,6 +3398,9 @@ > DbgInlinedScopeMap.clear(); > InlinedVariableScopes.clear(); > FunctionDbgScope = NULL; > + LexicalScopeStack.clear(); > + AbstractInstanceRootList.clear(); > + LexicalScopeToConcreteInstMap.clear(); > } > > Lines.clear(); > @@ -3429,6 +3478,7 @@ > DbgScope *Scope = getOrCreateScope(V); > unsigned ID = MMI->NextLabelID(); > if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID); > + LexicalScopeStack.push_back(Scope); > > if (TimePassesIsEnabled) > DebugTimer->stopTimer(); > @@ -3437,13 +3487,14 @@ > } > > /// RecordRegionEnd - Indicate the end of a region. > - unsigned RecordRegionEnd(GlobalVariable *V) { > + unsigned RecordRegionEnd(GlobalVariable *V, DISubprogram &SP) { > if (TimePassesIsEnabled) > DebugTimer->startTimer(); > > - DbgScope *Scope = getOrCreateScope(V); > unsigned ID = MMI->NextLabelID(); > + DbgScope *Scope = getOrCreateScope(V); > Scope->setEndLabelID(ID); > + LexicalScopeStack.pop_back(); > > if (TimePassesIsEnabled) > DebugTimer->stopTimer(); > @@ -3497,28 +3548,59 @@ > if (TimePassesIsEnabled) > DebugTimer->startTimer(); > > - std::string Dir, Fn; > - unsigned Src = GetOrCreateSourceID(CU.getDirectory(Dir), > - CU.getFilename(Fn)); > - DbgScope *Scope = createInlinedSubroutineScope(SP, Src, Line, Col); > - Scope->setStartLabelID(LabelID); > - MMI->RecordUsedDbgLabel(LabelID); > GlobalVariable *GV = SP.getGV(); > + DenseMap::iterator > + II = AbstractInstanceRootMap.find(GV); > > - DenseMap >::iterator > - SI = DbgInlinedScopeMap.find(GV); > + if (II == AbstractInstanceRootMap.end()) { > + // Create an abstract instance entry for this inlined function if it > + // doesn't already exist. > + DbgScope *Scope = new DbgScope(NULL, DIDescriptor(GV)); > + > + // Get the compile unit context. > + CompileUnit *Unit = &FindCompileUnit(SP.getCompileUnit()); > + DIE *SPDie = Unit->getDieMapSlotFor(GV); > + assert(SPDie && "Missing subprogram descriptor!"); > + > + // Mark as being inlined. This makes this subprogram entry an > abstract > + // instance root. > + // FIXME: Our debugger doesn't care about the value of DW_AT_inline, > only > + // that it's defined. It probably won't change in the future, but > this > + // could be more elegant. > + AddUInt(SPDie, DW_AT_inline, 0, DW_INL_declared_not_inlined); > + > + // Keep track of the scope that's inlined into this function. > + DenseMap >::iterator > + SI = DbgInlinedScopeMap.find(GV); > > - if (SI == DbgInlinedScopeMap.end()) > - DbgInlinedScopeMap[GV].push_back(Scope); > - else > - SI->second.push_back(Scope); > + if (SI == DbgInlinedScopeMap.end()) > + DbgInlinedScopeMap[GV].push_back(Scope); > + else > + SI->second.push_back(Scope); > + > + // Track the start label for this inlined function. > + DenseMap >::iterator > + I = InlineInfo.find(GV); > > - DenseMap >::iterator > - I = InlineInfo.find(GV); > - if (I == InlineInfo.end()) > - InlineInfo[GV].push_back(LabelID); > - else > - I->second.push_back(LabelID); > + if (I == InlineInfo.end()) > + InlineInfo[GV].push_back(LabelID); > + else > + I->second.push_back(LabelID); > + > + AbstractInstanceRootMap[GV] = Scope; > + AbstractInstanceRootList.push_back(Scope); > + } > + > + // Create a concrete inlined instance for this inlined function. > + DIE *ScopeDie = new DIE(DW_TAG_inlined_subroutine); > + CompileUnit *Unit = &FindCompileUnit(SP.getCompileUnit()); > + DIE *Origin = Unit->getDieMapSlotFor(GV); > + AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin); > + AddUInt(ScopeDie, DW_AT_call_file, 0, Unit->getID()); > + AddUInt(ScopeDie, DW_AT_call_line, 0, Line); > + AddUInt(ScopeDie, DW_AT_call_column, 0, Col); > + > + LexicalScopeToConcreteInstMap[LexicalScopeStack.back()] = ScopeDie; > > if (TimePassesIsEnabled) > DebugTimer->stopTimer(); > @@ -3528,6 +3610,7 @@ > > /// RecordInlinedFnEnd - Indicate the end of inlined subroutine. > unsigned RecordInlinedFnEnd(DISubprogram &SP) { > + // FIXME: This function never seems to be called!! > if (!TAI->doesDwarfUsesInlineInfoSection()) > return 0; > > @@ -4729,8 +4812,8 @@ > } > > /// RecordRegionEnd - Indicate the end of a region. > -unsigned DwarfWriter::RecordRegionEnd(GlobalVariable *V) { > - return DD->RecordRegionEnd(V); > +unsigned DwarfWriter::RecordRegionEnd(GlobalVariable *V, DISubprogram &SP) > { > + return DD->RecordRegionEnd(V, SP); > } > > /// getRecordSourceLineCount - Count source lines. > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=71165&r1=71164&r2=71165&view=diff > > > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Thu May 7 12:26:14 > 2009 > @@ -365,7 +365,8 @@ > BuildMI(MBB, DL, II).addImm(ID); > } else { > const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); > - ID = > DW->RecordRegionEnd(cast(REI->getContext())); > + ID = DW->RecordRegionEnd(cast(REI->getContext()), > + Subprogram); > BuildMI(MBB, DL, II).addImm(ID); > } > } > @@ -391,6 +392,7 @@ > // FIXME : Why DebugLoc is reset at the beginning of each block ? > if (PrevLoc.isUnknown()) > return true; > + > // Record the source line. > unsigned Line = Subprogram.getLineNumber(); > setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID( > @@ -410,10 +412,10 @@ > unsigned Line = Subprogram.getLineNumber(); > MF.setDefaultDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID( > CompileUnit.getGV(), Line, > 0))); > - if (DW && DW->ShouldEmitDwarfDebug()) { > + > + if (DW && DW->ShouldEmitDwarfDebug()) > // llvm.dbg.func_start also defines beginning of function scope. > DW->RecordRegionStart(cast(FSI->getSubprogram())); > - } > } > > return true; > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=71165&r1=71164&r2=71165&view=diff > > > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu May 7 > 12:26:14 2009 > @@ -3944,7 +3944,8 @@ > } > > unsigned LabelID = > - DW->RecordRegionEnd(cast(REI.getContext())); > + DW->RecordRegionEnd(cast(REI.getContext()), > + Subprogram); > DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), > getRoot(), LabelID)); > } > > Removed: llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll?rev=71164&view=auto > > > ============================================================================== > --- llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll > (original) > +++ llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll > (removed) > @@ -1,18 +0,0 @@ > -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i32 > 2143034560} > - > -; Instcombine should be able to completely fold this code. > - > -target datalayout = > "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" > -target triple = "i686-apple-darwin8" > - > - at bar = constant [3 x i64] [i64 9220983451228067448, i64 > 9220983451228067449, i64 9220983450959631991], align 8 > - > -define i32 @foo() nounwind { > -entry: > - %tmp87.2 = load i64* inttoptr (i32 add (i32 16, i32 ptrtoint ([3 x > i64]* @bar to i32)) to i64*), align 8 > - %t0 = bitcast i64 %tmp87.2 to double > - %tmp9192.2 = fptrunc double %t0 to float > - %t1 = bitcast float %tmp9192.2 to i32 > - ret i32 %t1 > -} > - > > > _______________________________________________ > 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/20090507/0545592f/attachment.html From gohman at apple.com Thu May 7 14:43:39 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 07 May 2009 19:43:39 -0000 Subject: [llvm-commits] [llvm] r71175 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200905071943.n47Jhemn031034@zion.cs.uiuc.edu> Author: djg Date: Thu May 7 14:43:39 2009 New Revision: 71175 URL: http://llvm.org/viewvc/llvm-project?rev=71175&view=rev Log: Perform constant folding on operands of instructions with non-void types, such as loads and calls. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=71175&r1=71174&r2=71175&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Thu May 7 14:43:39 2009 @@ -12770,7 +12770,9 @@ continue; } - if (TD && I->getType()->getTypeID() == Type::VoidTyID) { + if (TD && + (I->getType()->getTypeID() == Type::VoidTyID || + I->isTrapping())) { // See if we can constant fold its operands. for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) if (ConstantExpr *CE = dyn_cast(i)) From gohman at apple.com Thu May 7 14:46:25 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 07 May 2009 19:46:25 -0000 Subject: [llvm-commits] [llvm] r71176 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h include/llvm/CodeGen/DwarfWriter.h lib/Analysis/ConstantFolding.cpp lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfWriter.cpp lib/CodeGen/SelectionDAG/FastISel.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp test/Transforms/InstCombine/constant-fold-ptr-casts.ll Message-ID: <200905071946.n47JkPrI031120@zion.cs.uiuc.edu> Author: djg Date: Thu May 7 14:46:24 2009 New Revision: 71176 URL: http://llvm.org/viewvc/llvm-project?rev=71176&view=rev Log: Revert 71165. It did more than just revert 71158 and it introduced several regressions. The problem due to 71158 is now fixed. Added: llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll - copied unchanged from r71164, llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/include/llvm/CodeGen/DwarfWriter.h llvm/trunk/lib/Analysis/ConstantFolding.cpp llvm/trunk/lib/Analysis/DebugInfo.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=71176&r1=71175&r2=71176&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Thu May 7 14:46:24 2009 @@ -321,19 +321,6 @@ bool describes(const Function *F); }; - /// DIInlinedSubprogram - This is a wrapper for an inlined subprogram. - class DIInlinedSubprogram : public DIGlobal { - public: - explicit DIInlinedSubprogram(GlobalVariable *GV = 0); - DICompositeType getType() const { return getFieldAs(8); } - - /// Verify - Verify that an inlined subprogram descriptor is well formed. - bool Verify() const; - - /// dump - print inlined subprogram. - void dump() const; - }; - /// DIGlobalVariable - This is a wrapper for a global variable. class DIGlobalVariable : public DIGlobal { public: @@ -376,7 +363,6 @@ public: explicit DIBlock(GlobalVariable *GV = 0); - DICompileUnit getCompileUnit() const{ return getFieldAs(1); } DIDescriptor getContext() const { return getDescriptorField(1); } }; Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DwarfWriter.h?rev=71176&r1=71175&r2=71176&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/DwarfWriter.h (original) +++ llvm/trunk/include/llvm/CodeGen/DwarfWriter.h Thu May 7 14:46:24 2009 @@ -91,7 +91,7 @@ unsigned RecordRegionStart(GlobalVariable *V); /// RecordRegionEnd - Indicate the end of a region. - unsigned RecordRegionEnd(GlobalVariable *V, DISubprogram &SP); + unsigned RecordRegionEnd(GlobalVariable *V); /// getRecordSourceLineCount - Count source lines. unsigned getRecordSourceLineCount(); Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=71176&r1=71175&r2=71176&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Thu May 7 14:46:24 2009 @@ -16,6 +16,7 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" +#include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/ADT/SmallVector.h" @@ -383,12 +384,43 @@ // the int size is >= the ptr size. This requires knowing the width of a // pointer, so it can't be done in ConstantExpr::getCast. if (ConstantExpr *CE = dyn_cast(Ops[0])) { - if (TD && CE->getOpcode() == Instruction::PtrToInt && + if (TD && TD->getPointerSizeInBits() <= CE->getType()->getPrimitiveSizeInBits()) { - Constant *Input = CE->getOperand(0); - Constant *C = FoldBitCast(Input, DestTy, *TD); - return C ? C : ConstantExpr::getBitCast(Input, DestTy); + if (CE->getOpcode() == Instruction::PtrToInt) { + Constant *Input = CE->getOperand(0); + Constant *C = FoldBitCast(Input, DestTy, *TD); + return C ? C : ConstantExpr::getBitCast(Input, DestTy); + } + // If there's a constant offset added to the integer value before + // it is casted back to a pointer, see if the expression can be + // converted into a GEP. + if (CE->getOpcode() == Instruction::Add) + if (ConstantInt *L = dyn_cast(CE->getOperand(0))) + if (ConstantExpr *R = dyn_cast(CE->getOperand(1))) + if (R->getOpcode() == Instruction::PtrToInt) + if (GlobalVariable *GV = + dyn_cast(R->getOperand(0))) { + const PointerType *GVTy = cast(GV->getType()); + if (const ArrayType *AT = + dyn_cast(GVTy->getElementType())) { + const Type *ElTy = AT->getElementType(); + uint64_t PaddedSize = TD->getTypePaddedSize(ElTy); + APInt PSA(L->getValue().getBitWidth(), PaddedSize); + if (ElTy == cast(DestTy)->getElementType() && + L->getValue().urem(PSA) == 0) { + APInt ElemIdx = L->getValue().udiv(PSA); + if (ElemIdx.ult(APInt(ElemIdx.getBitWidth(), + AT->getNumElements()))) { + Constant *Index[] = { + Constant::getNullValue(CE->getType()), + ConstantInt::get(ElemIdx) + }; + return ConstantExpr::getGetElementPtr(GV, &Index[0], 2); + } + } + } + } } } return ConstantExpr::getCast(Opcode, Ops[0], DestTy); Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=71176&r1=71175&r2=71176&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Thu May 7 14:46:24 2009 @@ -59,9 +59,6 @@ case DW_TAG_subprogram: assert(DISubprogram(GV).Verify() && "Invalid DebugInfo value"); break; - case DW_TAG_inlined_subroutine: - assert(DIInlinedSubprogram(GV).Verify() && "Invalid DebugInfo value"); - break; case DW_TAG_lexical_block: /// FIXME. This interfers with the quality of generated code when /// during optimization. @@ -149,8 +146,6 @@ : DIType(GV, dwarf::DW_TAG_base_type) {} DISubprogram::DISubprogram(GlobalVariable *GV) : DIGlobal(GV, dwarf::DW_TAG_subprogram) {} -DIInlinedSubprogram::DIInlinedSubprogram(GlobalVariable *GV) - : DIGlobal(GV, dwarf::DW_TAG_inlined_subroutine) {} DIGlobalVariable::DIGlobalVariable(GlobalVariable *GV) : DIGlobal(GV, dwarf::DW_TAG_variable) {} DIBlock::DIBlock(GlobalVariable *GV) @@ -291,25 +286,6 @@ return true; } -/// Verify - Verify that an inlined subprogram descriptor is well formed. -bool DIInlinedSubprogram::Verify() const { - if (isNull()) - return false; - - if (getContext().isNull()) - return false; - - DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) - return false; - - DICompositeType Ty = getType(); - if (!Ty.isNull() && !Ty.Verify()) - return false; - - return true; -} - /// Verify - Verify that a global variable descriptor is well formed. bool DIGlobalVariable::Verify() const { if (isNull()) @@ -1007,8 +983,7 @@ /// dump - print descriptor. void DIDescriptor::dump() const { - cerr << "[" << dwarf::TagString(getTag()) << "] "; - cerr << std::hex << "[GV:" << GV << "]" << std::dec; + cerr << " [" << dwarf::TagString(getTag()) << "]\n"; } /// dump - print compile unit. @@ -1110,11 +1085,6 @@ DIGlobal::dump(); } -/// dump - print subprogram. -void DIInlinedSubprogram::dump() const { - DIGlobal::dump(); -} - /// dump - print global variable. void DIGlobalVariable::dump() const { cerr << " ["; getGlobal()->dump(); cerr << "] "; Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=71176&r1=71175&r2=71176&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Thu May 7 14:46:24 2009 @@ -1094,7 +1094,7 @@ /// class DbgVariable { DIVariable Var; // Variable Descriptor. - unsigned FrameIndex; // Variable frame index. + unsigned FrameIndex; // Variable frame index. public: DbgVariable(DIVariable V, unsigned I) : Var(V), FrameIndex(I) {} @@ -1280,32 +1280,14 @@ /// DbgInlinedScopeMap - Tracks inlined scopes in the current function. DenseMap > DbgInlinedScopeMap; - /// InlineInfo - Keep track of inlined functions and their location. This - /// information is used to populate debug_inlined section. + /// InlineInfo - Keep track of inlined functions and their location. + /// This information is used to populate debug_inlined section. DenseMap > InlineInfo; /// InlinedVariableScopes - Scopes information for the inlined subroutine /// variables. DenseMap InlinedVariableScopes; - /// AbstractInstanceRootMap - Map of abstract instance roots of inlined - /// functions. These are subroutine entries that contain a DW_AT_inline - /// attribute. - DenseMap AbstractInstanceRootMap; - - /// AbstractInstanceRootList - List of abstract instance roots of inlined - /// functions. These are subroutine entries that contain a DW_AT_inline - /// attribute. - SmallVector AbstractInstanceRootList; - - /// LexicalScopeToConcreteInstMap - Map a concrete instance's DIE to the - /// lexical scope it's in. - DenseMap LexicalScopeToConcreteInstMap; - - /// LexicalScopeStack - A stack of lexical scopes. The top one is the current - /// scope. - SmallVector LexicalScopeStack; - /// DebugTimer - Timer for the Dwarf debug writer. Timer *DebugTimer; @@ -1787,7 +1769,7 @@ if (Element.getTag() == dwarf::DW_TAG_subprogram) ElemDie = CreateSubprogramDIE(DW_Unit, DISubprogram(Element.getGV())); - else if (Element.getTag() == dwarf::DW_TAG_variable) // ?? + else if (Element.getTag() == dwarf::DW_TAG_variable) // ??? ElemDie = CreateGlobalVariableDIE(DW_Unit, DIGlobalVariable(Element.getGV())); else @@ -1976,7 +1958,6 @@ if (!SP.isDefinition()) { AddUInt(SPDie, DW_AT_declaration, DW_FORM_flag, 1); - // Add arguments. Do not add arguments for subprogram definition. They // will be handled through RecordVariable. if (SPTag == DW_TAG_subroutine_type) @@ -2049,13 +2030,6 @@ DbgScope *&Slot = DbgScopeMap[V]; if (Slot) return Slot; - // Don't create a new scope if we already created one for an inlined - // function. - DenseMap::iterator - II = AbstractInstanceRootMap.find(V); - if (II != AbstractInstanceRootMap.end()) - return LexicalScopeStack.back(); - DbgScope *Parent = NULL; DIBlock Block(V); @@ -2076,19 +2050,31 @@ return Slot; } + /// createInlinedSubroutineScope - Returns the scope associated with the + /// inlined subroutine. + /// + DbgScope *createInlinedSubroutineScope(DISubprogram SP, unsigned Src, + unsigned Line, unsigned Col) { + DbgScope *Scope = + new DbgInlinedSubroutineScope(NULL, SP, Src, Line, Col); + + // FIXME - Add inlined function scopes to the root so we can delete them + // later. + assert (FunctionDbgScope && "Function scope info missing!"); + FunctionDbgScope->AddScope(Scope); + return Scope; + } + /// ConstructDbgScope - Construct the components of a scope. /// void ConstructDbgScope(DbgScope *ParentScope, unsigned ParentStartID, unsigned ParentEndID, DIE *ParentDie, CompileUnit *Unit) { - if (LexicalScopeToConcreteInstMap.find(ParentScope) == - LexicalScopeToConcreteInstMap.end()) { - // Add variables to scope. - SmallVector &Variables = ParentScope->getVariables(); - for (unsigned i = 0, N = Variables.size(); i < N; ++i) { - DIE *VariableDie = NewDbgScopeVariable(Variables[i], Unit); - if (VariableDie) ParentDie->AddChild(VariableDie); - } + // Add variables to scope. + SmallVector &Variables = ParentScope->getVariables(); + for (unsigned i = 0, N = Variables.size(); i < N; ++i) { + DIE *VariableDie = NewDbgScopeVariable(Variables[i], Unit); + if (VariableDie) ParentDie->AddChild(VariableDie); } // Add nested scopes. @@ -2113,14 +2099,17 @@ ConstructDbgScope(Scope, ParentStartID, ParentEndID, ParentDie, Unit); } else { DIE *ScopeDie = NULL; - - DenseMap::iterator I = - LexicalScopeToConcreteInstMap.find(Scope); - - if (I != LexicalScopeToConcreteInstMap.end()) - ScopeDie = I->second; - else + if (MainCU && TAI->doesDwarfUsesInlineInfoSection() + && Scope->isInlinedSubroutine()) { + ScopeDie = new DIE(DW_TAG_inlined_subroutine); + DIE *Origin = MainCU->getDieMapSlotFor(Scope->getDesc().getGV()); + AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin); + AddUInt(ScopeDie, DW_AT_call_file, 0, Scope->getFile()); + AddUInt(ScopeDie, DW_AT_call_line, 0, Scope->getLine()); + AddUInt(ScopeDie, DW_AT_call_column, 0, Scope->getColumn()); + } else { ScopeDie = new DIE(DW_TAG_lexical_block); + } // Add the scope bounds. if (StartID) @@ -2176,29 +2165,6 @@ ConstructDbgScope(RootScope, 0, 0, SPDie, Unit); } - void ConstructAbstractDbgScope(DbgScope *AbsScope) { - // Exit if there is no root scope. - if (!AbsScope) return; - - DIDescriptor Desc = AbsScope->getDesc(); - if (Desc.isNull()) - return; - - // Get the subprogram debug information entry. - DISubprogram SPD(Desc.getGV()); - - // Get the compile unit context. - CompileUnit *Unit = MainCU; - if (!Unit) - Unit = &FindCompileUnit(SPD.getCompileUnit()); - - // Get the subprogram die. - DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV()); - assert(SPDie && "Missing subprogram descriptor"); - - ConstructDbgScope(AbsScope, 0, 0, SPDie, Unit); - } - /// ConstructDefaultDbgScope - Construct a default scope for the subprogram. /// void ConstructDefaultDbgScope(MachineFunction *MF) { @@ -2925,6 +2891,7 @@ DISubprogram SP(GV); std::string Name; std::string LName; + SP.getLinkageName(LName); SP.getName(Name); @@ -3120,10 +3087,8 @@ // Add to map. Slot = SubprogramDie; - // Add to context owner. Unit->getDie()->AddChild(SubprogramDie); - // Expose as global. std::string Name; Unit->AddGlobal(SP.getName(Name), SubprogramDie); @@ -3171,11 +3136,6 @@ for (unsigned j = 0, M = Values.size(); j < M; ++j) delete Values[j]; - for (DenseMap::iterator - I = AbstractInstanceRootMap.begin(), - E = AbstractInstanceRootMap.end(); I != E;++I) - delete I->second; - delete DebugTimer; } @@ -3382,12 +3342,6 @@ // information) needs to be explored. ConstructDefaultDbgScope(MF); - // Construct the DbgScope for abstract instances. - for (SmallVector::iterator - I = AbstractInstanceRootList.begin(), - E = AbstractInstanceRootList.end(); I != E; ++I) - ConstructAbstractDbgScope(*I); - DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount, MMI->getFrameMoves())); @@ -3398,9 +3352,6 @@ DbgInlinedScopeMap.clear(); InlinedVariableScopes.clear(); FunctionDbgScope = NULL; - LexicalScopeStack.clear(); - AbstractInstanceRootList.clear(); - LexicalScopeToConcreteInstMap.clear(); } Lines.clear(); @@ -3478,7 +3429,6 @@ DbgScope *Scope = getOrCreateScope(V); unsigned ID = MMI->NextLabelID(); if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID); - LexicalScopeStack.push_back(Scope); if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -3487,14 +3437,13 @@ } /// RecordRegionEnd - Indicate the end of a region. - unsigned RecordRegionEnd(GlobalVariable *V, DISubprogram &SP) { + unsigned RecordRegionEnd(GlobalVariable *V) { if (TimePassesIsEnabled) DebugTimer->startTimer(); - unsigned ID = MMI->NextLabelID(); DbgScope *Scope = getOrCreateScope(V); + unsigned ID = MMI->NextLabelID(); Scope->setEndLabelID(ID); - LexicalScopeStack.pop_back(); if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -3548,59 +3497,28 @@ if (TimePassesIsEnabled) DebugTimer->startTimer(); + std::string Dir, Fn; + unsigned Src = GetOrCreateSourceID(CU.getDirectory(Dir), + CU.getFilename(Fn)); + DbgScope *Scope = createInlinedSubroutineScope(SP, Src, Line, Col); + Scope->setStartLabelID(LabelID); + MMI->RecordUsedDbgLabel(LabelID); GlobalVariable *GV = SP.getGV(); - DenseMap::iterator - II = AbstractInstanceRootMap.find(GV); - - if (II == AbstractInstanceRootMap.end()) { - // Create an abstract instance entry for this inlined function if it - // doesn't already exist. - DbgScope *Scope = new DbgScope(NULL, DIDescriptor(GV)); - - // Get the compile unit context. - CompileUnit *Unit = &FindCompileUnit(SP.getCompileUnit()); - DIE *SPDie = Unit->getDieMapSlotFor(GV); - assert(SPDie && "Missing subprogram descriptor!"); - - // Mark as being inlined. This makes this subprogram entry an abstract - // instance root. - // FIXME: Our debugger doesn't care about the value of DW_AT_inline, only - // that it's defined. It probably won't change in the future, but this - // could be more elegant. - AddUInt(SPDie, DW_AT_inline, 0, DW_INL_declared_not_inlined); - - // Keep track of the scope that's inlined into this function. - DenseMap >::iterator - SI = DbgInlinedScopeMap.find(GV); - - if (SI == DbgInlinedScopeMap.end()) - DbgInlinedScopeMap[GV].push_back(Scope); - else - SI->second.push_back(Scope); - - // Track the start label for this inlined function. - DenseMap >::iterator - I = InlineInfo.find(GV); - if (I == InlineInfo.end()) - InlineInfo[GV].push_back(LabelID); - else - I->second.push_back(LabelID); - - AbstractInstanceRootMap[GV] = Scope; - AbstractInstanceRootList.push_back(Scope); - } + DenseMap >::iterator + SI = DbgInlinedScopeMap.find(GV); - // Create a concrete inlined instance for this inlined function. - DIE *ScopeDie = new DIE(DW_TAG_inlined_subroutine); - CompileUnit *Unit = &FindCompileUnit(SP.getCompileUnit()); - DIE *Origin = Unit->getDieMapSlotFor(GV); - AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin); - AddUInt(ScopeDie, DW_AT_call_file, 0, Unit->getID()); - AddUInt(ScopeDie, DW_AT_call_line, 0, Line); - AddUInt(ScopeDie, DW_AT_call_column, 0, Col); + if (SI == DbgInlinedScopeMap.end()) + DbgInlinedScopeMap[GV].push_back(Scope); + else + SI->second.push_back(Scope); - LexicalScopeToConcreteInstMap[LexicalScopeStack.back()] = ScopeDie; + DenseMap >::iterator + I = InlineInfo.find(GV); + if (I == InlineInfo.end()) + InlineInfo[GV].push_back(LabelID); + else + I->second.push_back(LabelID); if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -3610,7 +3528,6 @@ /// RecordInlinedFnEnd - Indicate the end of inlined subroutine. unsigned RecordInlinedFnEnd(DISubprogram &SP) { - // FIXME: This function never seems to be called!! if (!TAI->doesDwarfUsesInlineInfoSection()) return 0; @@ -4812,8 +4729,8 @@ } /// RecordRegionEnd - Indicate the end of a region. -unsigned DwarfWriter::RecordRegionEnd(GlobalVariable *V, DISubprogram &SP) { - return DD->RecordRegionEnd(V, SP); +unsigned DwarfWriter::RecordRegionEnd(GlobalVariable *V) { + return DD->RecordRegionEnd(V); } /// getRecordSourceLineCount - Count source lines. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=71176&r1=71175&r2=71176&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Thu May 7 14:46:24 2009 @@ -365,8 +365,7 @@ BuildMI(MBB, DL, II).addImm(ID); } else { const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); - ID = DW->RecordRegionEnd(cast(REI->getContext()), - Subprogram); + ID = DW->RecordRegionEnd(cast(REI->getContext())); BuildMI(MBB, DL, II).addImm(ID); } } @@ -392,7 +391,6 @@ // FIXME : Why DebugLoc is reset at the beginning of each block ? if (PrevLoc.isUnknown()) return true; - // Record the source line. unsigned Line = Subprogram.getLineNumber(); setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID( @@ -412,10 +410,10 @@ unsigned Line = Subprogram.getLineNumber(); MF.setDefaultDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID( CompileUnit.getGV(), Line, 0))); - - if (DW && DW->ShouldEmitDwarfDebug()) + if (DW && DW->ShouldEmitDwarfDebug()) { // llvm.dbg.func_start also defines beginning of function scope. DW->RecordRegionStart(cast(FSI->getSubprogram())); + } } return true; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=71176&r1=71175&r2=71176&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu May 7 14:46:24 2009 @@ -3944,8 +3944,7 @@ } unsigned LabelID = - DW->RecordRegionEnd(cast(REI.getContext()), - Subprogram); + DW->RecordRegionEnd(cast(REI.getContext())); DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), getRoot(), LabelID)); } From isanbard at gmail.com Thu May 7 15:24:12 2009 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 7 May 2009 13:24:12 -0700 Subject: [llvm-commits] [llvm] r71165 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h include/llvm/CodeGen/DwarfWriter.h lib/Analysis/ConstantFolding.cpp lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfWriter.cpp lib/CodeGen/SelectionDAG/FastIS In-Reply-To: <6a8523d60905071226o556b0a0dmd5317dad403d0dad@mail.gmail.com> References: <6a8523d60905071226o556b0a0dmd5317dad403d0dad@mail.gmail.com> Message-ID: <16e5fdf90905071324m34cf1eabqe382e3ca45188a35@mail.gmail.com> On Thu, May 7, 2009 at 12:26 PM, Daniel Dunbar wrote: > This commit does a lot more than just revert 71158, and I'm getting a lot of > asserts in debug info generation now. Can you revert this and re-revert > 71158? > Dan fixed this already. -bw From bob.wilson at apple.com Thu May 7 16:19:49 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 07 May 2009 21:19:49 -0000 Subject: [llvm-commits] [llvm] r71179 - /llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Message-ID: <200905072119.n47LJoAv001859@zion.cs.uiuc.edu> Author: bwilson Date: Thu May 7 16:19:45 2009 New Revision: 71179 URL: http://llvm.org/viewvc/llvm-project?rev=71179&view=rev Log: Fix a comment. Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=71179&r1=71178&r2=71179&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Thu May 7 16:19:45 2009 @@ -226,7 +226,7 @@ unsigned getReg(MachineBasicBlock &MBB, MachineInstr *MI, unsigned VirtReg, bool NoFree = false); - /// reloadVirtReg - This method transforms the specified specified virtual + /// reloadVirtReg - This method transforms the specified virtual /// register use to refer to a physical register. This method may do this /// in one of several ways: if the register is available in a physical /// register already, it uses that physical register. If the value is not From bob.wilson at apple.com Thu May 7 16:20:42 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 07 May 2009 21:20:42 -0000 Subject: [llvm-commits] [llvm] r71180 - /llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Message-ID: <200905072120.n47LKgsY001905@zion.cs.uiuc.edu> Author: bwilson Date: Thu May 7 16:20:42 2009 New Revision: 71180 URL: http://llvm.org/viewvc/llvm-project?rev=71180&view=rev Log: Fix a comment (again). Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=71180&r1=71179&r2=71180&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Thu May 7 16:20:42 2009 @@ -464,7 +464,7 @@ } -/// reloadVirtReg - This method transforms the specified specified virtual +/// reloadVirtReg - This method transforms the specified virtual /// register use to refer to a physical register. This method may do this in /// one of several ways: if the register is available in a physical register /// already, it uses that physical register. If the value is not in a physical From bob.wilson at apple.com Thu May 7 18:47:03 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 07 May 2009 23:47:03 -0000 Subject: [llvm-commits] [llvm] r71196 - in /llvm/trunk: lib/CodeGen/RegAllocLocal.cpp test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll Message-ID: <200905072347.n47Nl4Pu006476@zion.cs.uiuc.edu> Author: bwilson Date: Thu May 7 18:47:03 2009 New Revision: 71196 URL: http://llvm.org/viewvc/llvm-project?rev=71196&view=rev Log: Fix pr4100. Do not remove no-op copies when they are dead. The register scavenger gets confused about register liveness if it doesn't see them. I'm not thrilled with this solution, but it only comes up when there are dead copies in the code, which is something that hopefully doesn't happen much. Here is what happens in pr4100: As shown in the following excerpt from the debug output of llc, the source of a move gets reloaded from the stack, inserting a new load instruction before the move. Since that source operand is a kill, the physical register is free to be reused for the destination of the move. The move ends up being a no-op, copying R3 to R3, so it is deleted. But, it leaves behind the load to reload %reg1028 into R3, and that load is not updated to show that it's destination operand (R3) is dead. The scavenger gets confused by that load because it thinks that R3 is live. Starting RegAlloc of: %reg1025 = MOVr %reg1028, 14, %reg0, %reg0 Regs have values: Reloading %reg1028 into R3 Last use of R3[%reg1028], removing it from live set Assigning R3 to %reg1025 Register R3 [%reg1025] is never used, removing it from live set Alternative solutions might be either marking the load as dead, or zapping the load along with the no-op copy. I couldn't see an easy way to do either of those, though. Added: llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=71196&r1=71195&r2=71196&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Thu May 7 18:47:03 2009 @@ -981,10 +981,12 @@ } } - // Finally, if this is a noop copy instruction, zap it. + // Finally, if this is a noop copy instruction, zap it. (Except that if + // the copy is dead, it must be kept to avoid messing up liveness info for + // the register scavenger. See pr4100.) unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && - SrcReg == DstReg) + SrcReg == DstReg && DeadDefs.empty()) MBB.erase(MI); } Added: llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll?rev=71196&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll (added) +++ llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll Thu May 7 18:47:03 2009 @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | llc -mtriple=armv5-unknown-linux-gnueabi -O0 -regalloc=local +; PR4100 + at .str = external constant [30 x i8] ; <[30 x i8]*> [#uses=1] + +define i16 @fn16(i16 %arg0.0, <2 x i16> %arg1, i16 %arg2.0) nounwind { +entry: + store <2 x i16> %arg1, <2 x i16>* null + %0 = call i32 (i8*, ...)* @printf(i8* getelementptr ([30 x i8]* @.str, i32 0, i32 0), i32 0) nounwind ; [#uses=0] + ret i16 0 +} + +declare i32 @printf(i8*, ...) nounwind From eli.friedman at gmail.com Thu May 7 19:22:05 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Fri, 08 May 2009 00:22:05 -0000 Subject: [llvm-commits] [llvm] r71199 - in /llvm/trunk: lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll Message-ID: <200905080022.n480M5KM007428@zion.cs.uiuc.edu> Author: efriedma Date: Thu May 7 19:22:04 2009 New Revision: 71199 URL: http://llvm.org/viewvc/llvm-project?rev=71199&view=rev Log: PR4123: don't crash when inlining a call which uses its own result. Added: llvm/trunk/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=71199&r1=71198&r2=71199&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Thu May 7 19:22:04 2009 @@ -516,7 +516,10 @@ // uses of the returned value. if (!TheCall->use_empty()) { ReturnInst *R = Returns[0]; - TheCall->replaceAllUsesWith(R->getReturnValue()); + if (TheCall == R->getReturnValue()) + TheCall->replaceAllUsesWith(UndefValue::get(TheCall->getType())); + else + TheCall->replaceAllUsesWith(R->getReturnValue()); } // Since we are now done with the Call/Invoke, we can delete it. TheCall->eraseFromParent(); @@ -605,8 +608,12 @@ } else if (!Returns.empty()) { // Otherwise, if there is exactly one return value, just replace anything // using the return value of the call with the computed value. - if (!TheCall->use_empty()) - TheCall->replaceAllUsesWith(Returns[0]->getReturnValue()); + if (!TheCall->use_empty()) { + if (TheCall == Returns[0]->getReturnValue()) + TheCall->replaceAllUsesWith(UndefValue::get(TheCall->getType())); + else + TheCall->replaceAllUsesWith(Returns[0]->getReturnValue()); + } // Splice the code from the return block into the block that it will return // to, which contains the code that was after the call. Added: llvm/trunk/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll?rev=71199&view=auto ============================================================================== --- llvm/trunk/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll (added) +++ llvm/trunk/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll Thu May 7 19:22:04 2009 @@ -0,0 +1,20 @@ +; RUN: llvm-as < %s | opt -inline -disable-output +; PR4123 + %struct.S0 = type <{ i32 }> + %struct.S1 = type <{ i8, i8, i8, i8, %struct.S0 }> + %struct.S2 = type <{ %struct.S1, i32 }> + +define void @func_113(%struct.S1* noalias nocapture sret %agg.result, i8 signext %p_114) noreturn nounwind { +entry: + unreachable + +for.inc: ; preds = %for.inc + %call48 = call fastcc signext i8 @safe_sub_func_uint8_t_u_u(i8 signext %call48) ; [#uses=1] + br label %for.inc +} + +define fastcc signext i8 @safe_sub_func_uint8_t_u_u(i8 signext %_ui1) nounwind readnone { +entry: + ret i8 %_ui1 +} + From akyrtzi at gmail.com Thu May 7 19:40:45 2009 From: akyrtzi at gmail.com (Argiris Kirtzidis) Date: Fri, 08 May 2009 03:40:45 +0300 Subject: [llvm-commits] Add scope info in DebugLoc Message-ID: <4A037F8D.90001@gmail.com> The attached patch introduces 'DebugScope' which gets embedded in DebugLoc. This allows scope info to be readily available (along with line info) for each machine instruction, and will pull the DwarfWriter out of the instruction selectors. Please review and let me know what you think! -Argiris -------------- next part -------------- A non-text attachment was scrubbed... Name: debugscope.patch Type: text/x-diff Size: 20365 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090508/43f172ae/attachment.bin From evan.cheng at apple.com Thu May 7 21:03:27 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 7 May 2009 19:03:27 -0700 Subject: [llvm-commits] [llvm] r71196 - in /llvm/trunk: lib/CodeGen/RegAllocLocal.cpp test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll In-Reply-To: <200905072347.n47Nl4Pu006476@zion.cs.uiuc.edu> References: <200905072347.n47Nl4Pu006476@zion.cs.uiuc.edu> Message-ID: <1CE45B3C-A585-4DE0-AD45-E7CD30307725@apple.com> This is fine for local regalloc since performance is not critical. Thanks. Evan On May 7, 2009, at 4:47 PM, Bob Wilson wrote: > Author: bwilson > Date: Thu May 7 18:47:03 2009 > New Revision: 71196 > > URL: http://llvm.org/viewvc/llvm-project?rev=71196&view=rev > Log: > Fix pr4100. Do not remove no-op copies when they are dead. The > register > scavenger gets confused about register liveness if it doesn't see > them. > I'm not thrilled with this solution, but it only comes up when there > are dead > copies in the code, which is something that hopefully doesn't happen > much. > > Here is what happens in pr4100: As shown in the following excerpt > from the > debug output of llc, the source of a move gets reloaded from the > stack, > inserting a new load instruction before the move. Since that source > operand > is a kill, the physical register is free to be reused for the > destination > of the move. The move ends up being a no-op, copying R3 to R3, so > it is > deleted. But, it leaves behind the load to reload %reg1028 into R3, > and > that load is not updated to show that it's destination operand (R3) > is dead. > The scavenger gets confused by that load because it thinks that R3 > is live. > > Starting RegAlloc of: %reg1025 = MOVr %reg1028, 14, > %reg0, %reg0 > Regs have values: > Reloading %reg1028 into R3 > Last use of R3[%reg1028], removing it from live set > Assigning R3 to %reg1025 > Register R3 [%reg1025] is never used, removing it from live set > > Alternative solutions might be either marking the load as dead, or > zapping > the load along with the no-op copy. I couldn't see an easy way to do > either of those, though. > > Added: > llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll > Modified: > llvm/trunk/lib/CodeGen/RegAllocLocal.cpp > > Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=71196&r1=71195&r2=71196&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original) > +++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Thu May 7 18:47:03 2009 > @@ -981,10 +981,12 @@ > } > } > > - // Finally, if this is a noop copy instruction, zap it. > + // Finally, if this is a noop copy instruction, zap it. > (Except that if > + // the copy is dead, it must be kept to avoid messing up > liveness info for > + // the register scavenger. See pr4100.) > unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; > if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && > - SrcReg == DstReg) > + SrcReg == DstReg && DeadDefs.empty()) > MBB.erase(MI); > } > > > Added: llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll?rev=71196&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll (added) > +++ llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll Thu May > 7 18:47:03 2009 > @@ -0,0 +1,12 @@ > +; RUN: llvm-as < %s | llc -mtriple=armv5-unknown-linux-gnueabi -O0 - > regalloc=local > +; PR4100 > + at .str = external constant [30 x i8] ; <[30 x i8]*> [#uses=1] > + > +define i16 @fn16(i16 %arg0.0, <2 x i16> %arg1, i16 %arg2.0) > nounwind { > +entry: > + store <2 x i16> %arg1, <2 x i16>* null > + %0 = call i32 (i8*, ...)* @printf(i8* getelementptr ([30 x i8]* > @.str, i32 0, i32 0), i32 0) nounwind ; [#uses=0] > + ret i16 0 > +} > + > +declare i32 @printf(i8*, ...) nounwind > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Thu May 7 21:09:45 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 7 May 2009 19:09:45 -0700 Subject: [llvm-commits] [llvm] r71196 - in /llvm/trunk: lib/CodeGen/RegAllocLocal.cpp test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll In-Reply-To: <1CE45B3C-A585-4DE0-AD45-E7CD30307725@apple.com> References: <200905072347.n47Nl4Pu006476@zion.cs.uiuc.edu> <1CE45B3C-A585-4DE0-AD45-E7CD30307725@apple.com> Message-ID: Well, I can think of an alternative solution. Why not inhibit reloading of reg1028? It's easy to tell since the only use is a copy (use is killed right away) and its def is dead. Evan On May 7, 2009, at 7:03 PM, Evan Cheng wrote: > This is fine for local regalloc since performance is not critical. > Thanks. > > Evan > > On May 7, 2009, at 4:47 PM, Bob Wilson wrote: > >> Author: bwilson >> Date: Thu May 7 18:47:03 2009 >> New Revision: 71196 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=71196&view=rev >> Log: >> Fix pr4100. Do not remove no-op copies when they are dead. The >> register >> scavenger gets confused about register liveness if it doesn't see >> them. >> I'm not thrilled with this solution, but it only comes up when there >> are dead >> copies in the code, which is something that hopefully doesn't happen >> much. >> >> Here is what happens in pr4100: As shown in the following excerpt >> from the >> debug output of llc, the source of a move gets reloaded from the >> stack, >> inserting a new load instruction before the move. Since that source >> operand >> is a kill, the physical register is free to be reused for the >> destination >> of the move. The move ends up being a no-op, copying R3 to R3, so >> it is >> deleted. But, it leaves behind the load to reload %reg1028 into R3, >> and >> that load is not updated to show that it's destination operand (R3) >> is dead. >> The scavenger gets confused by that load because it thinks that R3 >> is live. >> >> Starting RegAlloc of: %reg1025 = MOVr %reg1028, 14, >> %reg0, %reg0 >> Regs have values: >> Reloading %reg1028 into R3 >> Last use of R3[%reg1028], removing it from live set >> Assigning R3 to %reg1025 >> Register R3 [%reg1025] is never used, removing it from live set >> >> Alternative solutions might be either marking the load as dead, or >> zapping >> the load along with the no-op copy. I couldn't see an easy way to do >> either of those, though. >> >> Added: >> llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll >> Modified: >> llvm/trunk/lib/CodeGen/RegAllocLocal.cpp >> >> Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=71196&r1=71195&r2=71196&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original) >> +++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Thu May 7 18:47:03 2009 >> @@ -981,10 +981,12 @@ >> } >> } >> >> - // Finally, if this is a noop copy instruction, zap it. >> + // Finally, if this is a noop copy instruction, zap it. >> (Except that if >> + // the copy is dead, it must be kept to avoid messing up >> liveness info for >> + // the register scavenger. See pr4100.) >> unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; >> if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && >> - SrcReg == DstReg) >> + SrcReg == DstReg && DeadDefs.empty()) >> MBB.erase(MI); >> } >> >> >> Added: llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll?rev=71196&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll (added) >> +++ llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll Thu May >> 7 18:47:03 2009 >> @@ -0,0 +1,12 @@ >> +; RUN: llvm-as < %s | llc -mtriple=armv5-unknown-linux-gnueabi -O0 - >> regalloc=local >> +; PR4100 >> + at .str = external constant [30 x i8] ; <[30 x i8]*> [#uses=1] >> + >> +define i16 @fn16(i16 %arg0.0, <2 x i16> %arg1, i16 %arg2.0) >> nounwind { >> +entry: >> + store <2 x i16> %arg1, <2 x i16>* null >> + %0 = call i32 (i8*, ...)* @printf(i8* getelementptr ([30 x i8]* >> @.str, i32 0, i32 0), i32 0) nounwind ; [#uses=0] >> + ret i16 0 >> +} >> + >> +declare i32 @printf(i8*, ...) nounwind >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sanjiv.gupta at microchip.com Thu May 7 23:50:15 2009 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Fri, 08 May 2009 04:50:15 -0000 Subject: [llvm-commits] [llvm] r71207 - in /llvm/trunk/lib/Target/PIC16: PIC16.h PIC16MemSelOpt.cpp PIC16TargetAsmInfo.cpp Message-ID: <200905080450.n484oFPm015026@zion.cs.uiuc.edu> Author: sgupta Date: Thu May 7 23:50:14 2009 New Revision: 71207 URL: http://llvm.org/viewvc/llvm-project?rev=71207&view=rev Log: Moved pic16 naming functions to correct place. No functionality change. Modified: llvm/trunk/lib/Target/PIC16/PIC16.h llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp Modified: llvm/trunk/lib/Target/PIC16/PIC16.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16.h?rev=71207&r1=71206&r2=71207&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16.h Thu May 7 23:50:14 2009 @@ -87,46 +87,93 @@ FRAME_SECTION, AUTOS_SECTION - }; + }; - }; + inline static const char *getIDName(IDs id) { + switch (id) { + default: assert(0 && "Unknown id"); + case PREFIX_SYMBOL: return "@"; + case FUNC_AUTOS: return ".auto."; + case FUNC_FRAME: return ".frame."; + case FUNC_TEMPS: return ".temp."; + case FUNC_ARGS: return ".args."; + case FUNC_RET: return ".ret."; + case FRAME_SECTION: return "fpdata"; + case AUTOS_SECTION: return "fadata"; + } + } + + inline static IDs getID(const std::string &Sym) { + if (Sym.find(getIDName(FUNC_TEMPS))) + return FUNC_TEMPS; + + if (Sym.find(getIDName(FUNC_FRAME))) + return FUNC_FRAME; + + if (Sym.find(getIDName(FUNC_RET))) + return FUNC_RET; + + if (Sym.find(getIDName(FUNC_ARGS))) + return FUNC_ARGS; + + if (Sym.find(getIDName(FUNC_AUTOS))) + return FUNC_AUTOS; - inline static const char *getIDName(PIC16ABINames::IDs id) { - switch (id) { - default: assert(0 && "Unknown id"); - case PIC16ABINames::PREFIX_SYMBOL: return "@"; - case PIC16ABINames::FUNC_AUTOS: return ".auto."; - case PIC16ABINames::FUNC_FRAME: return ".frame."; - case PIC16ABINames::FUNC_TEMPS: return ".temp."; - case PIC16ABINames::FUNC_ARGS: return ".args."; - case PIC16ABINames::FUNC_RET: return ".ret."; - case PIC16ABINames::FRAME_SECTION: return "fpdata"; - case PIC16ABINames::AUTOS_SECTION: return "fadata"; + if (Sym.find(getIDName(LIBCALL))) + return LIBCALL; + + // It does not have any ID. So its a global. + assert (0 && "Could not determine ID symbol type"); } - } - inline static PIC16ABINames::IDs getID(const std::string &Sym) { - if (Sym.find(getIDName(PIC16ABINames::FUNC_TEMPS))) - return PIC16ABINames::FUNC_TEMPS; + // Get func name from a mangled name. + // In all cases func name is the first component before a '.'. + static inline std::string getFuncNameForSym(const std::string &Sym) { + const char *prefix = getIDName (PREFIX_SYMBOL); + + // If this name has a prefix, func name start after prfix in that case. + size_t func_name_start = 0; + if (Sym.find(prefix, 0, strlen(prefix)) != std::string::npos) + func_name_start = strlen(prefix); - if (Sym.find(getIDName(PIC16ABINames::FUNC_FRAME))) - return PIC16ABINames::FUNC_FRAME; + // Position of the . after func name. That's where func name ends. + size_t func_name_end = Sym.find ('.', func_name_start); - if (Sym.find(getIDName(PIC16ABINames::FUNC_RET))) - return PIC16ABINames::FUNC_RET; + return Sym.substr (func_name_start, func_name_end); + } - if (Sym.find(getIDName(PIC16ABINames::FUNC_ARGS))) - return PIC16ABINames::FUNC_ARGS; + // Form a section name given the section type and func name. + static std::string + getSectionNameForFunc (const std::string &Fname, const IDs sec_id) { + std::string sec_id_string = getIDName(sec_id); + return sec_id_string + "." + Fname + ".#"; + } - if (Sym.find(getIDName(PIC16ABINames::FUNC_AUTOS))) - return PIC16ABINames::FUNC_AUTOS; + // Get the section for the given external symbol names. + // This tries to find the type (ID) of the symbol from its mangled name + // and return appropriate section name for it. + static inline std::string getSectionNameForSym(const std::string &Sym) { + std::string SectionName; + + IDs id = getID (Sym); + std::string Fname = getFuncNameForSym (Sym); + + switch (id) { + default : assert (0 && "Could not determine external symbol type"); + case FUNC_FRAME: + case FUNC_RET: + case FUNC_TEMPS: + case FUNC_ARGS: { + return getSectionNameForFunc (Fname, FRAME_SECTION); + } + case FUNC_AUTOS: { + return getSectionNameForFunc (Fname, AUTOS_SECTION); + } + } + } + }; // class PIC16ABINames. - if (Sym.find(getIDName(PIC16ABINames::LIBCALL))) - return PIC16ABINames::LIBCALL; - // It does not have any ID. So its a global. - assert (0 && "Could not determine ID symbol type"); - } inline static const char *PIC16CondCodeToString(PIC16CC::CondCodes CC) { Modified: llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp?rev=71207&r1=71206&r2=71207&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp Thu May 7 23:50:14 2009 @@ -145,7 +145,7 @@ // External Symbol is generated for temp data and arguments. They are // in fpdata..# section. std::string Sym = Op.getSymbolName(); - NewBank = getSectionNameForSym(Sym); + NewBank = PIC16ABINames::getSectionNameForSym(Sym); } // If the previous and new section names are same, we don't need to Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp?rev=71207&r1=71206&r2=71207&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp Thu May 7 23:50:14 2009 @@ -192,7 +192,7 @@ // variable and should not be printed in global data section. std::string name = I->getName(); if (name.find(".auto.") != std::string::npos - || name.find(".arg.") != std::string::npos) + || name.find(".args.") != std::string::npos) continue; int AddrSpace = I->getType()->getAddressSpace(); @@ -202,58 +202,6 @@ } -// Helper routine. -// Func name starts after prefix and followed by a . -static std::string getFuncNameForSym(const std::string &Sym, - PIC16ABINames::IDs PrefixType) { - - const char *prefix = getIDName (PIC16ABINames::PREFIX_SYMBOL); - - // This name may or may not start with prefix; - // Func names start after prfix in that case. - size_t func_name_start = 0; - if (Sym.find(prefix, 0, strlen(prefix)) != std::string::npos) - func_name_start = strlen(prefix); - - // Position of the . after func name. - size_t func_name_end = Sym.find ('.', func_name_start); - - return Sym.substr (func_name_start, func_name_end); -} - -// Helper routine to create a section name given the section prefix -// and func name. -static std::string -getSectionNameForFunc (const std::string &Fname, - const PIC16ABINames::IDs sec_id) { - std::string sec_id_string = getIDName (sec_id); - return sec_id_string + "." + Fname + ".#"; -} - - -// Get the section for the given external symbol names. -// This function is meant for only mangled external symbol names. -std::string -llvm::getSectionNameForSym(const std::string &Sym) { - std::string SectionName; - - PIC16ABINames::IDs id = getID (Sym); - std::string Fname = getFuncNameForSym (Sym, id); - - switch (id) { - default : assert (0 && "Could not determine external symbol type"); - case PIC16ABINames::FUNC_FRAME: - case PIC16ABINames::FUNC_RET: - case PIC16ABINames::FUNC_TEMPS: - case PIC16ABINames::FUNC_ARGS: { - return getSectionNameForFunc (Fname, PIC16ABINames::FRAME_SECTION); - } - case PIC16ABINames::FUNC_AUTOS: { - return getSectionNameForFunc (Fname, PIC16ABINames::AUTOS_SECTION); - } - } -} - PIC16TargetAsmInfo::~PIC16TargetAsmInfo() { for (unsigned i = 0; i < BSSSections.size(); i++) { From nicholas at mxc.ca Fri May 8 01:05:01 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 07 May 2009 23:05:01 -0700 Subject: [llvm-commits] [PATCH] TargetData::getIntPtrType() to return IntegerType In-Reply-To: References: Message-ID: <4A03CB8D.10003@mxc.ca> Jay Foad wrote: > The attached patch lets me avoid some casts to IntegerType in some > code I'm working on. Thoughts? It passes regression tests and cfe and > llvm-gcc still build. > > It's a bit unfortunate that TargetData.h has to include > DerivedTypes.h, but otherwise this would break code like: > > const Type *Ty = TD->getIntPtrType(); > > which now needs to know that IntegerType is derived from Type. Your patch looks good to me. You could declare "class IntegerType;" and require that users of getIntPtrType who want to write code like the above need to #include DerivedTypes.h themselves, but I'm not sure that's really an improvement. Nick From nicholas at mxc.ca Fri May 8 01:22:26 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Fri, 08 May 2009 06:22:26 -0000 Subject: [llvm-commits] [llvm] r71208 - /llvm/trunk/lib/Target/PIC16/PIC16.h Message-ID: <200905080622.n486MQp5017536@zion.cs.uiuc.edu> Author: nicholas Date: Fri May 8 01:22:25 2009 New Revision: 71208 URL: http://llvm.org/viewvc/llvm-project?rev=71208&view=rev Log: Add missing #include for "strlen" which is used inline in this header. Fixes build under gcc 4.3. Modified: llvm/trunk/lib/Target/PIC16/PIC16.h Modified: llvm/trunk/lib/Target/PIC16/PIC16.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16.h?rev=71208&r1=71207&r2=71208&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16.h Fri May 8 01:22:25 2009 @@ -18,6 +18,7 @@ #include "llvm/Target/TargetMachine.h" #include #include +#include #include namespace llvm { From evan.cheng at apple.com Fri May 8 01:34:09 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 08 May 2009 06:34:09 -0000 Subject: [llvm-commits] [llvm] r71209 - in /llvm/trunk: lib/CodeGen/CodePlacementOpt.cpp lib/Target/X86/X86InstrInfo.cpp test/CodeGen/X86/code_placement.ll Message-ID: <200905080634.n486Y9Sn017828@zion.cs.uiuc.edu> Author: evancheng Date: Fri May 8 01:34:09 2009 New Revision: 71209 URL: http://llvm.org/viewvc/llvm-project?rev=71209&view=rev Log: Optimize code placement in loop to eliminate unconditional branches or move unconditional branch to the outside of the loop. e.g. /// A: /// ... /// /// /// B: --> loop header /// ... /// jcc C, [exit] /// /// C: /// ... /// jmp B /// /// ==> /// /// A: /// ... /// jmp B /// /// C: --> new loop header /// ... /// /// /// B: /// ... /// jcc C, [exit] Added: llvm/trunk/test/CodeGen/X86/code_placement.ll Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp?rev=71209&r1=71208&r2=71209&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp (original) +++ llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Fri May 8 01:34:09 2009 @@ -16,15 +16,40 @@ #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/ADT/Statistic.h" using namespace llvm; +static cl::opt +OptLoopBBPlacement("opt-loop-bb-placement", + cl::init(false), cl::Hidden, + cl::desc("Optimize block placements in loops")); + +STATISTIC(NumHeaderAligned, "Number of loop header aligned"); +STATISTIC(NumIntraElim, "Number of intra loop branches eliminated"); +STATISTIC(NumIntraMoved, "Number of intra loop branches moved"); + namespace { class CodePlacementOpt : public MachineFunctionPass { const MachineLoopInfo *MLI; + const TargetInstrInfo *TII; + const TargetLowering *TLI; + + /// ChangedMBBs - BBs which are modified by OptimizeIntraLoopEdges. + SmallPtrSet ChangedMBBs; + + /// UncondJmpMBBs - A list of BBs which are in loops and end with + /// unconditional branches. + SmallVector, 4> + UncondJmpMBBs; + + /// LoopHeaders - A list of BBs which are loop headers. + SmallVector LoopHeaders; public: static char ID; @@ -37,12 +62,12 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); - AU.addPreserved(); AU.addPreservedID(MachineDominatorsID); MachineFunctionPass::getAnalysisUsage(AU); } private: + bool OptimizeIntraLoopEdges(); bool AlignLoops(MachineFunction &MF); }; @@ -53,32 +78,199 @@ return new CodePlacementOpt(); } +/// OptimizeBackEdges - Place loop back edges to move unconditional branches +/// out of the loop. +/// +/// A: +/// ... +/// +/// +/// B: --> loop header +/// ... +/// jcc C, [exit] +/// +/// C: +/// ... +/// jmp B +/// +/// ==> +/// +/// A: +/// ... +/// jmp B +/// +/// C: --> new loop header +/// ... +/// +/// +/// B: +/// ... +/// jcc C, [exit] +/// +bool CodePlacementOpt::OptimizeIntraLoopEdges() { + if (!OptLoopBBPlacement) + return false; + + bool Changed = false; + for (unsigned i = 0, e = UncondJmpMBBs.size(); i != e; ++i) { + MachineBasicBlock *MBB = UncondJmpMBBs[i].first; + MachineBasicBlock *SuccMBB = UncondJmpMBBs[i].second; + MachineLoop *L = MLI->getLoopFor(MBB); + assert(L && "BB is expected to be in a loop!"); + + if (ChangedMBBs.count(MBB)) { + // BB has been modified, re-analyze. + MachineBasicBlock *TBB = 0, *FBB = 0; + SmallVector Cond; + if (TII->AnalyzeBranch(*MBB, TBB, FBB, Cond) || !Cond.empty()) + continue; + if (MLI->getLoopFor(TBB) != L || TBB->isLandingPad()) + continue; + SuccMBB = TBB; + } else { + assert(MLI->getLoopFor(SuccMBB) == L && + "Successor is not in the same loop!"); + } + + if (MBB->isLayoutSuccessor(SuccMBB)) { + // Successor is right after MBB, just eliminate the unconditional jmp. + // Can this happen? + TII->RemoveBranch(*MBB); + ChangedMBBs.insert(MBB); + ++NumIntraElim; + continue; + } + + // Now check if the predecessor is fallthrough from any BB. If there is, + // that BB should be from outside the loop since edge will become a jmp. + bool OkToMove = true; + MachineBasicBlock *FtMBB = 0, *FtTBB = 0, *FtFBB = 0; + SmallVector FtCond; + for (MachineBasicBlock::pred_iterator PI = SuccMBB->pred_begin(), + PE = SuccMBB->pred_end(); PI != PE; ++PI) { + MachineBasicBlock *PredMBB = *PI; + if (PredMBB->isLayoutSuccessor(SuccMBB)) { + if (TII->AnalyzeBranch(*PredMBB, FtTBB, FtFBB, FtCond)) { + OkToMove = false; + break; + } + if (!FtTBB) + FtTBB = SuccMBB; + else if (!FtFBB) { + assert(FtFBB != SuccMBB && "Unexpected control flow!"); + FtFBB = SuccMBB; + } + + // A fallthrough. + FtMBB = PredMBB; + MachineLoop *PL = MLI->getLoopFor(PredMBB); + if (PL && (PL == L || PL->getLoopDepth() >= L->getLoopDepth())) { + OkToMove = false; + break; + } + } + } + + if (!OkToMove) + continue; + + // Is it profitable? If SuccMBB can fallthrough itself, that can be changed + // into a jmp. + MachineBasicBlock *TBB = 0, *FBB = 0; + SmallVector Cond; + if (TII->AnalyzeBranch(*SuccMBB, TBB, FBB, Cond)) + continue; + if (!TBB && Cond.empty()) + TBB = next(MachineFunction::iterator(SuccMBB)); + else if (!FBB && !Cond.empty()) + FBB = next(MachineFunction::iterator(SuccMBB)); + + // This calculate the cost of the transformation. Also, it finds the *only* + // intra-loop edge if there is one. + int Cost = 0; + bool HasOneIntraSucc = true; + MachineBasicBlock *IntraSucc = 0; + for (MachineBasicBlock::succ_iterator SI = SuccMBB->succ_begin(), + SE = SuccMBB->succ_end(); SI != SE; ++SI) { + MachineBasicBlock *SSMBB = *SI; + if (MLI->getLoopFor(SSMBB) == L) { + if (!IntraSucc) + IntraSucc = SSMBB; + else + HasOneIntraSucc = false; + } + + if (SuccMBB->isLayoutSuccessor(SSMBB)) + // This will become a jmp. + ++Cost; + else if (MBB->isLayoutSuccessor(SSMBB)) + // One of the successor will become the new fallthrough. + if (SSMBB == FBB) { + FBB = 0; + --Cost; + } else if (!FBB && SSMBB == TBB && Cond.empty()) { + TBB = 0; + --Cost; + } else if (!TII->ReverseBranchCondition(Cond)) { + TBB = FBB; + FBB = 0; + --Cost; + } + } + if (Cost) + continue; + + // Now, let's move the successor to below the BB to eliminate the jmp. + SuccMBB->moveAfter(MBB); + TII->RemoveBranch(*MBB); + TII->RemoveBranch(*SuccMBB); + if (TBB) + TII->InsertBranch(*SuccMBB, TBB, FBB, Cond); + ChangedMBBs.insert(MBB); + ChangedMBBs.insert(SuccMBB); + if (FtMBB) { + TII->RemoveBranch(*FtMBB); + TII->InsertBranch(*FtMBB, FtTBB, FtFBB, FtCond); + ChangedMBBs.insert(FtMBB); + } + + // If BB is the loop latch, we may have a new loop headr. + if (MBB == L->getLoopLatch()) { + assert(MLI->isLoopHeader(SuccMBB) && + "Only succ of loop latch is not the header?"); + if (HasOneIntraSucc && IntraSucc) + std::replace(LoopHeaders.begin(),LoopHeaders.end(), SuccMBB, IntraSucc); + } + } + + ++NumIntraMoved; + return Changed; +} + /// AlignLoops - Align loop headers to target preferred alignments. /// bool CodePlacementOpt::AlignLoops(MachineFunction &MF) { - const TargetLowering *TLI = MF.getTarget().getTargetLowering(); - if (!TLI) + const Function *F = MF.getFunction(); + if (F->hasFnAttr(Attribute::OptimizeForSize)) return false; unsigned Align = TLI->getPrefLoopAlignment(); if (!Align) return false; // Don't care about loop alignment. - const Function *F = MF.getFunction(); - if (F->hasFnAttr(Attribute::OptimizeForSize)) - return false; + // Make sure blocks are numbered in order + MF.RenumberBlocks(); bool Changed = false; - for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { - MachineBasicBlock *MBB = I; - if (MLI->isLoopHeader(MBB)) { - MachineBasicBlock *PredBB = prior(I); - if (MLI->getLoopFor(MBB) == MLI->getLoopFor(PredBB)) - // If previously BB is in the same loop, don't align this BB. We want - // to prevent adding noop's inside a loop. - continue; - MBB->setAlignment(Align); + for (unsigned i = 0, e = LoopHeaders.size(); i != e; ++i) { + MachineBasicBlock *HeaderMBB = LoopHeaders[i]; + MachineBasicBlock *PredMBB = prior(MachineFunction::iterator(HeaderMBB)); + if (MLI->getLoopFor(HeaderMBB) != MLI->getLoopFor(PredMBB)) { + // If previously BB is in the same loop, don't align this BB. We want + // to prevent adding noop's inside a loop. + HeaderMBB->setAlignment(Align); Changed = true; + ++NumHeaderAligned; } } @@ -90,8 +282,36 @@ if (MLI->empty()) return false; // No loops. - bool Changed = false; + TLI = MF.getTarget().getTargetLowering(); + TII = MF.getTarget().getInstrInfo(); + + // Analyze the BBs first and keep track of loop headers and BBs that + // end with an unconditional jmp to another block in the same loop. + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { + MachineBasicBlock *MBB = I; + if (MBB->isLandingPad()) + continue; + MachineLoop *L = MLI->getLoopFor(MBB); + if (!L) + continue; + if (MLI->isLoopHeader(MBB)) + LoopHeaders.push_back(MBB); + + MachineBasicBlock *TBB = 0, *FBB = 0; + SmallVector Cond; + if (TII->AnalyzeBranch(*MBB, TBB, FBB, Cond) || !Cond.empty()) + continue; + if (MLI->getLoopFor(TBB) == L && !TBB->isLandingPad()) + UncondJmpMBBs.push_back(std::make_pair(MBB, TBB)); + } + + bool Changed = OptimizeIntraLoopEdges(); + Changed |= AlignLoops(MF); + ChangedMBBs.clear(); + UncondJmpMBBs.clear(); + LoopHeaders.clear(); + return Changed; } Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=71209&r1=71208&r2=71209&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Fri May 8 01:34:09 2009 @@ -1508,7 +1508,7 @@ if (I->getOpcode() == X86::JMP) { if (!AllowModify) { TBB = I->getOperand(0).getMBB(); - return false; + continue; } // If the block has any instructions after a JMP, delete them. Added: llvm/trunk/test/CodeGen/X86/code_placement.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/code_placement.ll?rev=71209&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/code_placement.ll (added) +++ llvm/trunk/test/CodeGen/X86/code_placement.ll Fri May 8 01:34:09 2009 @@ -0,0 +1,134 @@ +; RUN: llvm-as < %s | llc -march=x86 -opt-loop-bb-placement | %prcontext jmp 1 | grep align + + at Te0 = external global [256 x i32] ; <[256 x i32]*> [#uses=5] + at Te1 = external global [256 x i32] ; <[256 x i32]*> [#uses=4] + at Te3 = external global [256 x i32] ; <[256 x i32]*> [#uses=2] + +define void @t(i8* nocapture %in, i8* nocapture %out, i32* nocapture %rk, i32 %r) nounwind ssp { +entry: + %0 = load i32* %rk, align 4 ; [#uses=1] + %1 = getelementptr i32* %rk, i64 1 ; [#uses=1] + %2 = load i32* %1, align 4 ; [#uses=1] + %tmp15 = add i32 %r, -1 ; [#uses=1] + %tmp.16 = zext i32 %tmp15 to i64 ; [#uses=2] + br label %bb + +bb: ; preds = %bb1, %entry + %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %bb1 ] ; [#uses=3] + %s1.0 = phi i32 [ %2, %entry ], [ %56, %bb1 ] ; [#uses=2] + %s0.0 = phi i32 [ %0, %entry ], [ %43, %bb1 ] ; [#uses=2] + %tmp18 = shl i64 %indvar, 4 ; [#uses=4] + %rk26 = bitcast i32* %rk to i8* ; [#uses=6] + %3 = lshr i32 %s0.0, 24 ; [#uses=1] + %4 = zext i32 %3 to i64 ; [#uses=1] + %5 = getelementptr [256 x i32]* @Te0, i64 0, i64 %4 ; [#uses=1] + %6 = load i32* %5, align 4 ; [#uses=1] + %7 = lshr i32 %s1.0, 16 ; [#uses=1] + %8 = and i32 %7, 255 ; [#uses=1] + %9 = zext i32 %8 to i64 ; [#uses=1] + %10 = getelementptr [256 x i32]* @Te1, i64 0, i64 %9 ; [#uses=1] + %11 = load i32* %10, align 4 ; [#uses=1] + %ctg2.sum2728 = or i64 %tmp18, 8 ; [#uses=1] + %12 = getelementptr i8* %rk26, i64 %ctg2.sum2728 ; [#uses=1] + %13 = bitcast i8* %12 to i32* ; [#uses=1] + %14 = load i32* %13, align 4 ; [#uses=1] + %15 = xor i32 %11, %6 ; [#uses=1] + %16 = xor i32 %15, %14 ; [#uses=3] + %17 = lshr i32 %s1.0, 24 ; [#uses=1] + %18 = zext i32 %17 to i64 ; [#uses=1] + %19 = getelementptr [256 x i32]* @Te0, i64 0, i64 %18 ; [#uses=1] + %20 = load i32* %19, align 4 ; [#uses=1] + %21 = and i32 %s0.0, 255 ; [#uses=1] + %22 = zext i32 %21 to i64 ; [#uses=1] + %23 = getelementptr [256 x i32]* @Te3, i64 0, i64 %22 ; [#uses=1] + %24 = load i32* %23, align 4 ; [#uses=1] + %ctg2.sum2930 = or i64 %tmp18, 12 ; [#uses=1] + %25 = getelementptr i8* %rk26, i64 %ctg2.sum2930 ; [#uses=1] + %26 = bitcast i8* %25 to i32* ; [#uses=1] + %27 = load i32* %26, align 4 ; [#uses=1] + %28 = xor i32 %24, %20 ; [#uses=1] + %29 = xor i32 %28, %27 ; [#uses=4] + %30 = lshr i32 %16, 24 ; [#uses=1] + %31 = zext i32 %30 to i64 ; [#uses=1] + %32 = getelementptr [256 x i32]* @Te0, i64 0, i64 %31 ; [#uses=1] + %33 = load i32* %32, align 4 ; [#uses=2] + %exitcond = icmp eq i64 %indvar, %tmp.16 ; [#uses=1] + br i1 %exitcond, label %bb2, label %bb1 + +bb1: ; preds = %bb + %ctg2.sum31 = add i64 %tmp18, 16 ; [#uses=1] + %34 = getelementptr i8* %rk26, i64 %ctg2.sum31 ; [#uses=1] + %35 = bitcast i8* %34 to i32* ; [#uses=1] + %36 = lshr i32 %29, 16 ; [#uses=1] + %37 = and i32 %36, 255 ; [#uses=1] + %38 = zext i32 %37 to i64 ; [#uses=1] + %39 = getelementptr [256 x i32]* @Te1, i64 0, i64 %38 ; [#uses=1] + %40 = load i32* %39, align 4 ; [#uses=1] + %41 = load i32* %35, align 4 ; [#uses=1] + %42 = xor i32 %40, %33 ; [#uses=1] + %43 = xor i32 %42, %41 ; [#uses=1] + %44 = lshr i32 %29, 24 ; [#uses=1] + %45 = zext i32 %44 to i64 ; [#uses=1] + %46 = getelementptr [256 x i32]* @Te0, i64 0, i64 %45 ; [#uses=1] + %47 = load i32* %46, align 4 ; [#uses=1] + %48 = and i32 %16, 255 ; [#uses=1] + %49 = zext i32 %48 to i64 ; [#uses=1] + %50 = getelementptr [256 x i32]* @Te3, i64 0, i64 %49 ; [#uses=1] + %51 = load i32* %50, align 4 ; [#uses=1] + %ctg2.sum32 = add i64 %tmp18, 20 ; [#uses=1] + %52 = getelementptr i8* %rk26, i64 %ctg2.sum32 ; [#uses=1] + %53 = bitcast i8* %52 to i32* ; [#uses=1] + %54 = load i32* %53, align 4 ; [#uses=1] + %55 = xor i32 %51, %47 ; [#uses=1] + %56 = xor i32 %55, %54 ; [#uses=1] + %indvar.next = add i64 %indvar, 1 ; [#uses=1] + br label %bb + +bb2: ; preds = %bb + %tmp10 = shl i64 %tmp.16, 4 ; [#uses=2] + %ctg2.sum = add i64 %tmp10, 16 ; [#uses=1] + %tmp1213 = getelementptr i8* %rk26, i64 %ctg2.sum ; [#uses=1] + %57 = bitcast i8* %tmp1213 to i32* ; [#uses=1] + %58 = and i32 %33, -16777216 ; [#uses=1] + %59 = lshr i32 %29, 16 ; [#uses=1] + %60 = and i32 %59, 255 ; [#uses=1] + %61 = zext i32 %60 to i64 ; [#uses=1] + %62 = getelementptr [256 x i32]* @Te1, i64 0, i64 %61 ; [#uses=1] + %63 = load i32* %62, align 4 ; [#uses=1] + %64 = and i32 %63, 16711680 ; [#uses=1] + %65 = or i32 %64, %58 ; [#uses=1] + %66 = load i32* %57, align 4 ; [#uses=1] + %67 = xor i32 %65, %66 ; [#uses=2] + %68 = lshr i32 %29, 8 ; [#uses=1] + %69 = zext i32 %68 to i64 ; [#uses=1] + %70 = getelementptr [256 x i32]* @Te0, i64 0, i64 %69 ; [#uses=1] + %71 = load i32* %70, align 4 ; [#uses=1] + %72 = and i32 %71, -16777216 ; [#uses=1] + %73 = and i32 %16, 255 ; [#uses=1] + %74 = zext i32 %73 to i64 ; [#uses=1] + %75 = getelementptr [256 x i32]* @Te1, i64 0, i64 %74 ; [#uses=1] + %76 = load i32* %75, align 4 ; [#uses=1] + %77 = and i32 %76, 16711680 ; [#uses=1] + %78 = or i32 %77, %72 ; [#uses=1] + %ctg2.sum25 = add i64 %tmp10, 20 ; [#uses=1] + %79 = getelementptr i8* %rk26, i64 %ctg2.sum25 ; [#uses=1] + %80 = bitcast i8* %79 to i32* ; [#uses=1] + %81 = load i32* %80, align 4 ; [#uses=1] + %82 = xor i32 %78, %81 ; [#uses=2] + %83 = lshr i32 %67, 24 ; [#uses=1] + %84 = trunc i32 %83 to i8 ; [#uses=1] + store i8 %84, i8* %out, align 1 + %85 = lshr i32 %67, 16 ; [#uses=1] + %86 = trunc i32 %85 to i8 ; [#uses=1] + %87 = getelementptr i8* %out, i64 1 ; [#uses=1] + store i8 %86, i8* %87, align 1 + %88 = getelementptr i8* %out, i64 4 ; [#uses=1] + %89 = lshr i32 %82, 24 ; [#uses=1] + %90 = trunc i32 %89 to i8 ; [#uses=1] + store i8 %90, i8* %88, align 1 + %91 = lshr i32 %82, 16 ; [#uses=1] + %92 = trunc i32 %91 to i8 ; [#uses=1] + %93 = getelementptr i8* %out, i64 5 ; [#uses=1] + store i8 %92, i8* %93, align 1 + ret void +} From nicholas at mxc.ca Fri May 8 01:47:37 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Fri, 08 May 2009 06:47:37 -0000 Subject: [llvm-commits] [llvm] r71210 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200905080647.n486lbo6018160@zion.cs.uiuc.edu> Author: nicholas Date: Fri May 8 01:47:37 2009 New Revision: 71210 URL: http://llvm.org/viewvc/llvm-project?rev=71210&view=rev Log: This transform requires valid TargetData info. Wrap it in 'if (TD)' in preparation for the day we use null TargetData when no target is specified. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=71210&r1=71209&r2=71210&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Fri May 8 01:47:37 2009 @@ -11196,34 +11196,36 @@ User *CI = cast(LI.getOperand(0)); Value *CastOp = CI->getOperand(0); - if (ConstantExpr *CE = dyn_cast(CI)) { - // Instead of loading constant c string, use corresponding integer value - // directly if string length is small enough. - std::string Str; - if (GetConstantStringInfo(CE->getOperand(0), Str) && !Str.empty()) { - unsigned len = Str.length(); - const Type *Ty = cast(CE->getType())->getElementType(); - unsigned numBits = Ty->getPrimitiveSizeInBits(); - // Replace LI with immediate integer store. - if ((numBits >> 3) == len + 1) { - APInt StrVal(numBits, 0); - APInt SingleChar(numBits, 0); - if (TD->isLittleEndian()) { - for (signed i = len-1; i >= 0; i--) { - SingleChar = (uint64_t) Str[i] & UCHAR_MAX; - StrVal = (StrVal << 8) | SingleChar; - } - } else { - for (unsigned i = 0; i < len; i++) { - SingleChar = (uint64_t) Str[i] & UCHAR_MAX; + if (TD) { + if (ConstantExpr *CE = dyn_cast(CI)) { + // Instead of loading constant c string, use corresponding integer value + // directly if string length is small enough. + std::string Str; + if (GetConstantStringInfo(CE->getOperand(0), Str) && !Str.empty()) { + unsigned len = Str.length(); + const Type *Ty = cast(CE->getType())->getElementType(); + unsigned numBits = Ty->getPrimitiveSizeInBits(); + // Replace LI with immediate integer store. + if ((numBits >> 3) == len + 1) { + APInt StrVal(numBits, 0); + APInt SingleChar(numBits, 0); + if (TD->isLittleEndian()) { + for (signed i = len-1; i >= 0; i--) { + SingleChar = (uint64_t) Str[i] & UCHAR_MAX; + StrVal = (StrVal << 8) | SingleChar; + } + } else { + for (unsigned i = 0; i < len; i++) { + SingleChar = (uint64_t) Str[i] & UCHAR_MAX; + StrVal = (StrVal << 8) | SingleChar; + } + // Append NULL at the end. + SingleChar = 0; StrVal = (StrVal << 8) | SingleChar; } - // Append NULL at the end. - SingleChar = 0; - StrVal = (StrVal << 8) | SingleChar; + Value *NL = ConstantInt::get(StrVal); + return IC.ReplaceInstUsesWith(LI, NL); } - Value *NL = ConstantInt::get(StrVal); - return IC.ReplaceInstUsesWith(LI, NL); } } } From nicholas at mxc.ca Fri May 8 01:57:42 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Fri, 08 May 2009 06:57:42 -0000 Subject: [llvm-commits] [llvm] r71211 - /llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Message-ID: <200905080657.n486vhoZ018421@zion.cs.uiuc.edu> Author: nicholas Date: Fri May 8 01:57:41 2009 New Revision: 71211 URL: http://llvm.org/viewvc/llvm-project?rev=71211&view=rev Log: Add explicit braces to disambiguate nested if/else. Removes a warning. Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp?rev=71211&r1=71210&r2=71211&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp (original) +++ llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Fri May 8 01:57:41 2009 @@ -203,7 +203,7 @@ if (SuccMBB->isLayoutSuccessor(SSMBB)) // This will become a jmp. ++Cost; - else if (MBB->isLayoutSuccessor(SSMBB)) + else if (MBB->isLayoutSuccessor(SSMBB)) { // One of the successor will become the new fallthrough. if (SSMBB == FBB) { FBB = 0; @@ -216,6 +216,7 @@ FBB = 0; --Cost; } + } } if (Cost) continue; From baldrick at free.fr Fri May 8 02:26:58 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 8 May 2009 09:26:58 +0200 Subject: [llvm-commits] [llvm] r71199 - in /llvm/trunk: lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll In-Reply-To: <200905080022.n480M5KM007428@zion.cs.uiuc.edu> References: <200905080022.n480M5KM007428@zion.cs.uiuc.edu> Message-ID: <200905080926.58344.baldrick@free.fr> Hi Eli, > PR4123: don't crash when inlining a call which uses its own result. > +define void @func_113(%struct.S1* noalias nocapture sret %agg.result, i8 signext %p_114) noreturn nounwind { > +entry: > + unreachable > + > +for.inc: ; preds = %for.inc > + %call48 = call fastcc signext i8 @safe_sub_func_uint8_t_u_u(i8 signext %call48) ; [#uses=1] > + br label %for.inc > +} is this really valid IR? Maybe this is more a question of fixing the verifier... Ciao, Duncan. From evan.cheng at apple.com Fri May 8 04:36:06 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 08 May 2009 09:36:06 -0000 Subject: [llvm-commits] [llvm] r71214 - /llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Message-ID: <200905080936.n489a7he001791@zion.cs.uiuc.edu> Author: evancheng Date: Fri May 8 04:35:53 2009 New Revision: 71214 URL: http://llvm.org/viewvc/llvm-project?rev=71214&view=rev Log: Reverse branch condition only when there is a conditional branch. Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp?rev=71214&r1=71213&r2=71214&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp (original) +++ llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Fri May 8 04:35:53 2009 @@ -211,7 +211,8 @@ } else if (!FBB && SSMBB == TBB && Cond.empty()) { TBB = 0; --Cost; - } else if (!TII->ReverseBranchCondition(Cond)) { + } else if (!Cond.empty() && !TII->ReverseBranchCondition(Cond)) { + assert(SSMBB == TBB); TBB = FBB; FBB = 0; --Cost; From sabre at nondot.org Fri May 8 10:54:54 2009 From: sabre at nondot.org (Chris Lattner) Date: Fri, 08 May 2009 15:54:54 -0000 Subject: [llvm-commits] [llvm] r71224 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/2009-05-08-I1Crash.ll Message-ID: <200905081554.n48Fssnt014289@zion.cs.uiuc.edu> Author: lattner Date: Fri May 8 10:54:41 2009 New Revision: 71224 URL: http://llvm.org/viewvc/llvm-project?rev=71224&view=rev Log: fix RewriteStoreUserOfWholeAlloca to use the correct type size method, fixing a crash on PR4146. While the store will ultimately overwrite the "padded size" number of bits in memory, the stored value may be a subset of this size. This function only wants to handle the case where all bits are stored. Added: llvm/trunk/test/Transforms/ScalarRepl/2009-05-08-I1Crash.ll Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=71224&r1=71223&r2=71224&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Fri May 8 10:54:41 2009 @@ -903,9 +903,10 @@ // If this isn't a store of an integer to the whole alloca, it may be a store // to the first element. Just ignore the store in this case and normal SROA - // will handle it. + // will handle it. We don't handle types here that have tail padding, like + // an alloca of type {i1}. if (!isa(SrcVal->getType()) || - TD->getTypePaddedSizeInBits(SrcVal->getType()) != AllocaSizeBits) + TD->getTypeSizeInBits(SrcVal->getType()) != AllocaSizeBits) return; DOUT << "PROMOTING STORE TO WHOLE ALLOCA: " << *AI << *SI; @@ -1015,9 +1016,10 @@ // If this isn't a load of the whole alloca to an integer, it may be a load // of the first element. Just ignore the load in this case and normal SROA - // will handle it. + // will handle it. We don't handle types here that have tail padding, like + // an alloca of type {i1}. if (!isa(LI->getType()) || - TD->getTypePaddedSizeInBits(LI->getType()) != AllocaSizeBits) + TD->getTypeSizeInBits(LI->getType()) != AllocaSizeBits) return; DOUT << "PROMOTING LOAD OF WHOLE ALLOCA: " << *AI << *LI; Added: llvm/trunk/test/Transforms/ScalarRepl/2009-05-08-I1Crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/2009-05-08-I1Crash.ll?rev=71224&view=auto ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/2009-05-08-I1Crash.ll (added) +++ llvm/trunk/test/Transforms/ScalarRepl/2009-05-08-I1Crash.ll Fri May 8 10:54:41 2009 @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis +; PR4146 + + %wrapper = type { i1 } + +define void @f() { +entry: + %w = alloca %wrapper, align 8 ; <%wrapper*> [#uses=1] + %0 = getelementptr %wrapper* %w, i64 0, i32 0 ; + store i1 true, i1* %0 + ret void +} From clattner at apple.com Fri May 8 11:12:32 2009 From: clattner at apple.com (Chris Lattner) Date: Fri, 8 May 2009 09:12:32 -0700 Subject: [llvm-commits] [llvm] r71199 - in /llvm/trunk: lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll In-Reply-To: <200905080926.58344.baldrick@free.fr> References: <200905080022.n480M5KM007428@zion.cs.uiuc.edu> <200905080926.58344.baldrick@free.fr> Message-ID: <038C388C-34A9-4131-8AF5-594D1EA9D748@apple.com> On May 8, 2009, at 12:26 AM, Duncan Sands wrote: > Hi Eli, >> PR4123: don't crash when inlining a call which uses its own result. >> +define void @func_113(%struct.S1* noalias nocapture sret >> %agg.result, i8 signext %p_114) noreturn nounwind { >> +entry: >> + unreachable >> + >> +for.inc: ; preds = %for.inc >> + %call48 = call fastcc signext i8 @safe_sub_func_uint8_t_u_u(i8 >> signext %call48) ; [#uses=1] >> + br label %for.inc >> +} > > is this really valid IR? Maybe this is more a question of > fixing the verifier... Code in dead blocks is allowed to violate some ssa constraints, this one in particular. -Chris From brukman at gmail.com Fri May 8 11:13:29 2009 From: brukman at gmail.com (Misha Brukman) Date: Fri, 8 May 2009 12:13:29 -0400 Subject: [llvm-commits] [llvm] r71210 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <200905080647.n486lbo6018160@zion.cs.uiuc.edu> References: <200905080647.n486lbo6018160@zion.cs.uiuc.edu> Message-ID: On Fri, May 8, 2009 at 2:47 AM, Nick Lewycky wrote: > Author: nicholas > Date: Fri May 8 01:47:37 2009 > New Revision: 71210 > > URL: http://llvm.org/viewvc/llvm-project?rev=71210&view=rev > Log: > This transform requires valid TargetData info. Wrap it in 'if (TD)' in > preparation for the day we use null TargetData when no target is specified. > Instead of adding an extra indent level, how about adding: if (!TD) { return; } before the TargetData-dependent code? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090508/97456b50/attachment.html From sabre at nondot.org Fri May 8 11:25:43 2009 From: sabre at nondot.org (Chris Lattner) Date: Fri, 8 May 2009 11:25:43 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2009-05-EnsuringCorrectnessOfCompiledCode.html Message-ID: <200905081625.n48GPhkb015514@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2009-05-EnsuringCorrectnessOfCompiledCode.html updated: 1.1 -> 1.2 --- Log message: improve formatting --- Diffs of the changes: (+2 -0) 2009-05-EnsuringCorrectnessOfCompiledCode.html | 2 ++ 1 files changed, 2 insertions(+) Index: llvm-www/pubs/2009-05-EnsuringCorrectnessOfCompiledCode.html diff -u llvm-www/pubs/2009-05-EnsuringCorrectnessOfCompiledCode.html:1.1 llvm-www/pubs/2009-05-EnsuringCorrectnessOfCompiledCode.html:1.2 --- llvm-www/pubs/2009-05-EnsuringCorrectnessOfCompiledCode.html:1.1 Fri May 8 11:23:04 2009 +++ llvm-www/pubs/2009-05-EnsuringCorrectnessOfCompiledCode.html Fri May 8 11:24:44 2009 @@ -78,6 +78,7 @@

    BibTeX Entry:

    +
     @PhdThesis{GZAKS:PHD,
        author  = {Ganna Zaks},
        title   = "{Ensuring Correctness of Compiled Code}",
    @@ -86,6 +87,7 @@
        address = {New York, NY},
        month   = {May}
     }
    +
    From sabre at nondot.org Fri May 8 11:25:52 2009 From: sabre at nondot.org (Chris Lattner) Date: Fri, 8 May 2009 11:25:52 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2009-05-EnsuringCorrectnessOfCompiledCode.html 2009-05-EnsuringCorrectnessOfCompiledCode.pdf 2009-05-EnsuringCorrectnessOfCompiledCode.ps.gz pubs.js Message-ID: <200905081625.n48GPqeJ015529@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2009-05-EnsuringCorrectnessOfCompiledCode.html added (r1.1) 2009-05-EnsuringCorrectnessOfCompiledCode.pdf added (r1.1) 2009-05-EnsuringCorrectnessOfCompiledCode.ps.gz added (r1.1) pubs.js updated: 1.12 -> 1.13 --- Log message: Add Anna Zaks' Ph.D. thesis, "Ensuring Correctness of Compiled Code" --- Diffs of the changes: (+100 -0) 2009-05-EnsuringCorrectnessOfCompiledCode.html | 92 ++++++++++++++++++++++++ 2009-05-EnsuringCorrectnessOfCompiledCode.pdf | 0 2009-05-EnsuringCorrectnessOfCompiledCode.ps.gz | 0 pubs.js | 8 ++ 4 files changed, 100 insertions(+) Index: llvm-www/pubs/2009-05-EnsuringCorrectnessOfCompiledCode.html diff -c /dev/null llvm-www/pubs/2009-05-EnsuringCorrectnessOfCompiledCode.html:1.1 *** /dev/null Fri May 8 11:23:16 2009 --- llvm-www/pubs/2009-05-EnsuringCorrectnessOfCompiledCode.html Fri May 8 11:23:04 2009 *************** *** 0 **** --- 1,92 ---- + + + + + + Ensuring Correctness of Compiled Code + + + +
    + Ensuring Correctness of Compiled Code +
    +
    + Ganna Zaks, Ph.D. thesis +
    + +

    Abstract:

    +
    +

    + Traditionally, the verification effort is applied to the abstract + algorithmic descriptions of the underlining software. However, even + well understood protocols such as Peterson???s protocol for mutual + exclusion, whose algorithmic description takes only half a page, have + published implementations that are erroneous. Furthermore, the + semantics of the implementations can be altered by optimizing + compilers, which are very large applications and, consequently, are + bound to have bugs. Thus, it is highly desirable to ensure the + correctness of the compiled code especially in safety critical and + high-assurance software. This dissertation describes two alternative + approaches that bring us closer to solving the problem.

    + +

    First, we present Compiler Validation via Analysis of the + Cross-Product (CoVaC) - a deductive framework for proving program + equivalence and its application to automatic verification of + transformations performed by optimizing compilers. To leverage the + existing program analysis techniques, we reduce the equivalence + checking problem to analysis of one system - a cross-product of the + two input programs. We show how the approach can be effectively used + for checking equivalence of single-threaded programs that are + structurally similar. Unlike the existing frameworks, our approach + accommodates absence of compiler annotations and handles most of the + classical intraprocedural optimizations such as constant folding, + reassociation, common subexpression elimination, code motion, branch + optimizations, and others. In addition, we have developed rules for + translation validation of interprocedural optimizations, which can be + applied when compiler annotations are available.

    + +

    + The second contribution is the pancam framework for model checking + multi-threaded C programs. pancam first compiles a multi-threaded C + program into optimized bytecode format. The framework relies on Spin, + an existing explicit state model checker, to orchestrate the program's + state space search. However, the program transitions and states are + computed by the pancam bytecode interpreter. A feature of our approach + is that not only pancam checks the actual implementation, but it can + also check the code after compiler optimizations. Pancam addresses the + state space explosion problem by allowing users to define data + abstraction functions and to constrain the number of allowed context + switches. We also describe a partial order reduction method that + reduces context switches using dynamic knowledge computed on-the-fly, + while being sound for both safety and liveness properties. +

    + +
    + +

    Published:

    +
    + "Ensuring Correctness of Compiled Code", Ganna Zaks,
    + Ph.D. Thesis, Computer Science Dept., New York University, New York, NY, May 2009.
    +
    + +

    Download Presentation:

    + + +

    BibTeX Entry:

    + +
    + @PhdThesis{GZAKS:PHD, + author = {Ganna Zaks}, + title = "{Ensuring Correctness of Compiled Code}", + school = "{Computer Science Dept., New York University}", + year = {2009}, + address = {New York, NY}, + month = {May} + } +
    + + + Index: llvm-www/pubs/2009-05-EnsuringCorrectnessOfCompiledCode.pdf Index: llvm-www/pubs/2009-05-EnsuringCorrectnessOfCompiledCode.ps.gz Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.12 llvm-www/pubs/pubs.js:1.13 --- llvm-www/pubs/pubs.js:1.12 Wed Mar 25 00:57:52 2009 +++ llvm-www/pubs/pubs.js Fri May 8 11:23:05 2009 @@ -1,6 +1,14 @@ // The array should be sorted reverse-chronologically, and will be displayed on // the page in the order listed. var PUBS = [ + {url: '2009-05-EnsuringCorrectnessOfCompiledCode.html', + title: 'Ensuring Correctness of Compiled Code', + author: 'Ganna Zaks', + published: "Ph.D. Thesis, Computer Science Dept., New York University", + location: "New York, NY", + month: 5, + year: 2009}, + {url: '2009-03-CGO-ESoftCheck.html', title: 'ESoftCheck: Removal of Non-vital Checks for Fault Tolerance', author: 'Jing Yu, Maria Jesus Garzaran, Marc Snir', From clattner at apple.com Fri May 8 12:06:37 2009 From: clattner at apple.com (Chris Lattner) Date: Fri, 8 May 2009 10:06:37 -0700 Subject: [llvm-commits] [llvm] r71077 - in /llvm/trunk: lib/Transforms/IPO/FunctionAttrs.cpp test/Transforms/FunctionAttrs/2009-05-06-Malloc.ll In-Reply-To: <200905071909.33340.baldrick@free.fr> References: <200905060842.n468g7cX013662@zion.cs.uiuc.edu> <200905071845.04149.baldrick@free.fr> <26E7B419-0070-4F9C-8106-D7402197F1DF@mac.com> <200905071909.33340.baldrick@free.fr> Message-ID: On May 7, 2009, at 10:09 AM, Duncan Sands wrote: > Hi Owen, > >> We don't do much in the way of optimization of MallocInst anyways. >> The only thing that this helps is that it prevents a call to malloc() >> from clobbering results of a memory dependence query. As I've >> advocated on IRC, I think we should just add LibCallAA support for >> saying that malloc() clobbers no known pointers, just like we can use >> it to say that libm functions only clobber errno. This seems like >> the >> "right" way to go to me. > > "malloc" is already marked as returning a "noalias" result IIRC. > Thus there is nothing to be done for malloc: it has already been > done! MallocInst is different to malloc, and should just be > removed from LLVM. The only problem I see with this is how to > autoupgrade existing llvm that uses the malloc instruction. Some > trick (GEP?) will be needed to get the size of the object being > allocated. Gep should work fine. There is also no need to handle this with libcallaa, basicaa can handle "call malloc" directly. -Chris From clattner at apple.com Fri May 8 12:08:14 2009 From: clattner at apple.com (Chris Lattner) Date: Fri, 8 May 2009 10:08:14 -0700 Subject: [llvm-commits] [PATCH] optimise constant arguments in LowerIntrinsicCall() In-Reply-To: References: Message-ID: <719ECD03-5A8A-4628-9981-93A5F9071656@apple.com> On May 7, 2009, at 6:28 AM, Jay Foad wrote: > Given this source: > > void f(int *p) { > p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = p[8] = > p[9] = 0; > } > > if I compile with optimisation and then run it through the C backend: Looks good to me, please apply. Thanks Jay, -Chris > > > $ .../llvm-gcc4.2-2.5-x86-linux-RHEL4/bin/llvm-gcc -emit-llvm -O2 -c > m.c > $ llc -march=c -o - m.o > > I get: > > void f(unsigned int *llvm_cbe_p) { > unsigned char *ltmp_0_1; > > *llvm_cbe_p = 0u; > ltmp_0_1 = memset((((unsigned char *)((&llvm_cbe_p[((signed int > )1u)])))), (((unsigned int )(unsigned char )((unsigned char )0))), > (((unsigned int )36ull))); > return; > } > > The second and third arguments in the call to memset() involve > unnecessary casts of a constant value. This happens because > LowerIntrinsicCall() turns: > > call void @llvm.memset.i64(i8* %1, i8 0, i64 36, i32 4) > > into: > > %2 = trunc i64 36 to i32 ; [#uses=1] > %3 = zext i8 0 to i32 ; [#uses=1] > %4 = call i8* @memset(i8* %1, i32 %3, i32 %2) ; > > and nothing later constant-folds the trunc and zext instructions. > > The attached patch addresses this, by optimising LowerIntrinsicCall() > for the case of constant arguments. With this patch applied, the C > backend produces: > > ltmp_0_1 = memset((((unsigned char *)((&llvm_cbe_p[((signed int > )1u)])))), 0u, 36u); > > The patch passes "make check". > > Alternatively, maybe some other optimisation pass could be scheduled > that constant-folds the trunc and zext instructions, but this seems > like overkill to me. > > Incidentally, it seems a bit odd that llvm-gcc generates > llvm.memset.i64 instead of llvm.memset.i32 in the first place, but I > haven't investigated why this happens. > > Thanks, > Jay. > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Fri May 8 12:11:13 2009 From: clattner at apple.com (Chris Lattner) Date: Fri, 8 May 2009 10:11:13 -0700 Subject: [llvm-commits] [PATCH] TargetData::getIntPtrType() to return IntegerType In-Reply-To: <4A03CB8D.10003@mxc.ca> References: <4A03CB8D.10003@mxc.ca> Message-ID: On May 7, 2009, at 11:05 PM, Nick Lewycky wrote: > Jay Foad wrote: >> The attached patch lets me avoid some casts to IntegerType in some >> code I'm working on. Thoughts? It passes regression tests and cfe and >> llvm-gcc still build. >> >> It's a bit unfortunate that TargetData.h has to include >> DerivedTypes.h, but otherwise this would break code like: >> >> const Type *Ty = TD->getIntPtrType(); >> >> which now needs to know that IntegerType is derived from Type. > > Your patch looks good to me. Me too, thanks Jay, -Chris From clattner at apple.com Fri May 8 12:13:04 2009 From: clattner at apple.com (Chris Lattner) Date: Fri, 8 May 2009 10:13:04 -0700 Subject: [llvm-commits] [PATCH] Added TCE target to llvm-gcc In-Reply-To: <4A02943D.9010108@tut.fi> References: <49CB688D.8070606@tut.fi> <200903261405.48884.baldrick@free.fr> <49CB8AC9.80308@tut.fi> <4A02943D.9010108@tut.fi> Message-ID: <83AF3DAA-E4AC-4BDA-8B2F-2BBF5C6336E0@apple.com> On May 7, 2009, at 12:56 AM, Mikael Lepist? wrote: > Any news if this patch could be applied and which modifications it > would need? I attached the latest version of the patch which is made > towards llvm-gcc trunk with "svn diff -x -u". > > This patch would help greatly our users to be able to use llvm-gcc > sources gotten directly from llvm, instead using our patched > version. Also it would help a bit maintaining llvm trunk > synchronized branch of the tce toolset. Hi Mikael, The patch looks reasonable to me, but we need to have "LLVM LOCAL" markers on the changes, so that they don't get lost in a merge. Can you please add these to the files? -Chris From evan.cheng at apple.com Fri May 8 12:25:39 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 8 May 2009 10:25:39 -0700 Subject: [llvm-commits] Add scope info in DebugLoc In-Reply-To: <4A037F8D.90001@gmail.com> References: <4A037F8D.90001@gmail.com> Message-ID: Hi Argiris, Eventually we'd like to move scoping information to the llvm IR level. But this seems like a good interim step. Bill can you review this when you have some time? Thanks, Evan On May 7, 2009, at 5:40 PM, Argiris Kirtzidis wrote: > The attached patch introduces 'DebugScope' which gets embedded in > DebugLoc. > This allows scope info to be readily available (along with line > info) for each machine instruction, and will pull the DwarfWriter > out of the instruction selectors. > > Please review and let me know what you think! > > -Argiris > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Fri May 8 12:32:47 2009 From: sabre at nondot.org (Chris Lattner) Date: Fri, 08 May 2009 17:32:47 -0000 Subject: [llvm-commits] [llvm] r71226 - in /llvm/trunk: Makefile utils/TableGen/Makefile utils/unittest/googletest/Makefile Message-ID: <200905081732.n48HWmYh018476@zion.cs.uiuc.edu> Author: lattner Date: Fri May 8 12:32:47 2009 New Revision: 71226 URL: http://llvm.org/viewvc/llvm-project?rev=71226&view=rev Log: Change 'make install' to install tblgen, for better support of out-of-tree targets, patch by Mikael Lepist?! Modified: llvm/trunk/Makefile llvm/trunk/utils/TableGen/Makefile llvm/trunk/utils/unittest/googletest/Makefile Modified: llvm/trunk/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile?rev=71226&r1=71225&r2=71226&view=diff ============================================================================== --- llvm/trunk/Makefile (original) +++ llvm/trunk/Makefile Fri May 8 12:32:47 2009 @@ -71,10 +71,9 @@ OPTIONAL_DIRS := endif -# Don't install utils, examples, or projects they are only used to -# build LLVM. +# Use NO_INSTALL define of the Makefile of each directory for deciding +# if the directory is installed or not ifeq ($(MAKECMDGOALS),install) - DIRS := $(filter-out utils, $(DIRS)) OPTIONAL_DIRS := $(filter bindings, $(OPTIONAL_DIRS)) endif Modified: llvm/trunk/utils/TableGen/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Makefile?rev=71226&r1=71225&r2=71226&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/Makefile (original) +++ llvm/trunk/utils/TableGen/Makefile Fri May 8 12:32:47 2009 @@ -9,7 +9,6 @@ LEVEL = ../.. TOOLNAME = tblgen -NO_INSTALL = 1; USEDLIBS = LLVMSupport.a LLVMSystem.a REQUIRES_EH := 1 REQUIRES_RTTI := 1 Modified: llvm/trunk/utils/unittest/googletest/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/Makefile?rev=71226&r1=71225&r2=71226&view=diff ============================================================================== --- llvm/trunk/utils/unittest/googletest/Makefile (original) +++ llvm/trunk/utils/unittest/googletest/Makefile Fri May 8 12:32:47 2009 @@ -22,4 +22,6 @@ CPP.Flags += -DGTEST_OS_WINDOWS=1 endif +NO_INSTALL = 1 + include $(LEVEL)/Makefile.common From baldrick at free.fr Fri May 8 12:36:33 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 8 May 2009 19:36:33 +0200 Subject: [llvm-commits] [llvm] r71224 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/2009-05-08-I1Crash.ll In-Reply-To: <200905081554.n48Fssnt014289@zion.cs.uiuc.edu> References: <200905081554.n48Fssnt014289@zion.cs.uiuc.edu> Message-ID: <200905081936.34245.baldrick@free.fr> Hi Chris, > fix RewriteStoreUserOfWholeAlloca to use the correct type size > method, fixing a crash on PR4146. While the store will > ultimately overwrite the "padded size" number of bits in memory, > the stored value may be a subset of this size. This function > only wants to handle the case where all bits are stored. I think you mean StoreSize, not PaddedSize. StoreSize is the number of bits overwritten, PaddedSize is what gets allocated by alloca etc. Ciao, Duncan. From clattner at apple.com Fri May 8 12:40:00 2009 From: clattner at apple.com (Chris Lattner) Date: Fri, 8 May 2009 10:40:00 -0700 Subject: [llvm-commits] [llvm] r71224 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/2009-05-08-I1Crash.ll In-Reply-To: <200905081936.34245.baldrick@free.fr> References: <200905081554.n48Fssnt014289@zion.cs.uiuc.edu> <200905081936.34245.baldrick@free.fr> Message-ID: On May 8, 2009, at 10:36 AM, Duncan Sands wrote: > Hi Chris, > >> fix RewriteStoreUserOfWholeAlloca to use the correct type size >> method, fixing a crash on PR4146. While the store will >> ultimately overwrite the "padded size" number of bits in memory, >> the stored value may be a subset of this size. This function >> only wants to handle the case where all bits are stored. > > I think you mean StoreSize, not PaddedSize. StoreSize is the > number of bits overwritten, PaddedSize is what gets allocated > by alloca etc. Now it doesn't use either of them :) -Chris From wendling at apple.com Fri May 8 12:45:42 2009 From: wendling at apple.com (Bill Wendling) Date: Fri, 8 May 2009 10:45:42 -0700 Subject: [llvm-commits] Add scope info in DebugLoc In-Reply-To: References: <4A037F8D.90001@gmail.com> Message-ID: <393945CD-2B44-4EBC-95FA-11017C2F813A@apple.com> Yes. It's on my list of things to do. :-) Probably this week-end? -bw On May 8, 2009, at 10:25 AM, Evan Cheng wrote: > Hi Argiris, > > Eventually we'd like to move scoping information to the llvm IR > level. But this seems like a good interim step. Bill can you review > this when you have some time? > > Thanks, > > Evan > > On May 7, 2009, at 5:40 PM, Argiris Kirtzidis wrote: > >> The attached patch introduces 'DebugScope' which gets embedded in >> DebugLoc. >> This allows scope info to be readily available (along with line >> info) for each machine instruction, and will pull the DwarfWriter >> out of the instruction selectors. >> >> Please review and let me know what you think! >> >> -Argiris >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From clattner at apple.com Fri May 8 12:47:11 2009 From: clattner at apple.com (Chris Lattner) Date: Fri, 8 May 2009 10:47:11 -0700 Subject: [llvm-commits] patch: use CallbackVH for metadata In-Reply-To: <4A012B04.9060101@mxc.ca> References: <4A012B04.9060101@mxc.ca> Message-ID: On May 5, 2009, at 11:15 PM, Nick Lewycky wrote: > This patch switches MDNode to using CallbackVH and adds a special > typeless "null" keyword that means "(Value*)0" within a metadata > node. Also change MDNode construction to accept Value* even though > we don't really permit non-Constant values yet. Looks nice. Please split MDNode (and the VH.h #include) out to a new MDNode.h file. In ElementVH, what is the right behavior when RAUW and delete are called? Shouldn't these go back through to be recursively uniqued, like what happens for Constants? -Chris From baldrick at free.fr Fri May 8 12:49:49 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 08 May 2009 17:49:49 -0000 Subject: [llvm-commits] [llvm] r71230 - /llvm/trunk/include/llvm/Target/TargetData.h Message-ID: <200905081749.n48Hnn8Z019283@zion.cs.uiuc.edu> Author: baldrick Date: Fri May 8 12:49:48 2009 New Revision: 71230 URL: http://llvm.org/viewvc/llvm-project?rev=71230&view=rev Log: Add some examples to show the difference between the various notions of type size used in LLVM. Modified: llvm/trunk/include/llvm/Target/TargetData.h Modified: llvm/trunk/include/llvm/Target/TargetData.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetData.h?rev=71230&r1=71229&r2=71230&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetData.h (original) +++ llvm/trunk/include/llvm/Target/TargetData.h Fri May 8 12:49:48 2009 @@ -155,6 +155,23 @@ /// Target pointer size, in bits unsigned char getPointerSizeInBits() const { return 8*PointerMemSize; } + /// Size examples: + /// + /// Type SizeInBits StoreSizeInBits PaddedSizeInBits[*] + /// ---- ---------- --------------- ---------------- + /// i1 1 8 8 + /// i8 8 8 8 + /// i19 19 24 32 + /// i32 32 32 32 + /// i100 100 104 128 + /// i128 128 128 128 + /// Float 32 32 32 + /// Double 64 64 64 + /// X86_FP80 80 80 96 + /// + /// [*] The padded size depends on the alignment, and thus on the target. + /// These values are for x86-32 linux. + /// getTypeSizeInBits - Return the number of bits necessary to hold the /// specified type. For example, returns 36 for i36 and 80 for x86_fp80. uint64_t getTypeSizeInBits(const Type* Ty) const; From daniel at zuster.org Fri May 8 13:02:40 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Fri, 08 May 2009 18:02:40 -0000 Subject: [llvm-commits] [klee] r71231 - /klee/trunk/www/index.html Message-ID: <200905081802.n48I2hKS019706@zion.cs.uiuc.edu> Author: ddunbar Date: Fri May 8 13:02:24 2009 New Revision: 71231 URL: http://llvm.org/viewvc/llvm-project?rev=71231&view=rev Log: More or less a test commit. Modified: klee/trunk/www/index.html Modified: klee/trunk/www/index.html URL: http://llvm.org/viewvc/llvm-project/klee/trunk/www/index.html?rev=71231&r1=71230&r2=71231&view=diff ============================================================================== --- klee/trunk/www/index.html (original) +++ klee/trunk/www/index.html Fri May 8 13:02:24 2009 @@ -15,8 +15,8 @@

    The klee Symbolic Virtual Machine

    -

    klee is a symbolic virtual machine built on top of the LLVM - compiler infrastructure.

    +

    klee is a symbolic virtual machine built on top of + the LLVM compiler infrastructure.

    Stay tuned for more information on public availability. For now, there is some information available on From sabre at nondot.org Fri May 8 13:23:15 2009 From: sabre at nondot.org (Chris Lattner) Date: Fri, 08 May 2009 18:23:15 -0000 Subject: [llvm-commits] [llvm] r71232 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/2009-05-08-InlineAsmIOffset.ll Message-ID: <200905081823.n48INFhA020679@zion.cs.uiuc.edu> Author: lattner Date: Fri May 8 13:23:14 2009 New Revision: 71232 URL: http://llvm.org/viewvc/llvm-project?rev=71232&view=rev Log: Fix PR4152: asm constraint validation happens before dag combine, so we need to work a bit to combine things like (x+c1+c2) into x+c3. Added: llvm/trunk/test/CodeGen/X86/2009-05-08-InlineAsmIOffset.ll Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=71232&r1=71231&r2=71232&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri May 8 13:23:14 2009 @@ -8519,40 +8519,39 @@ // If we are in non-pic codegen mode, we allow the address of a global (with // an optional displacement) to be used with 'i'. - GlobalAddressSDNode *GA = dyn_cast(Op); + GlobalAddressSDNode *GA = 0; int64_t Offset = 0; - // Match either (GA) or (GA+C) - if (GA) { - Offset = GA->getOffset(); - } else if (Op.getOpcode() == ISD::ADD) { - ConstantSDNode *C = dyn_cast(Op.getOperand(1)); - GA = dyn_cast(Op.getOperand(0)); - if (C && GA) { - Offset = GA->getOffset()+C->getZExtValue(); - } else { - C = dyn_cast(Op.getOperand(1)); - GA = dyn_cast(Op.getOperand(0)); - if (C && GA) - Offset = GA->getOffset()+C->getZExtValue(); - else - C = 0, GA = 0; + // Match either (GA), (GA+C), (GA+C1+C2), etc. + while (1) { + if ((GA = dyn_cast(Op))) { + Offset += GA->getOffset(); + break; + } else if (Op.getOpcode() == ISD::ADD) { + if (ConstantSDNode *C = dyn_cast(Op.getOperand(1))) { + Offset += C->getZExtValue(); + Op = Op.getOperand(0); + continue; + } + } else if (Op.getOpcode() == ISD::SUB) { + if (ConstantSDNode *C = dyn_cast(Op.getOperand(1))) { + Offset += -C->getZExtValue(); + Op = Op.getOperand(0); + continue; + } } + + // Otherwise, this isn't something we can handle, reject it. + return; } - if (GA) { - if (hasMemory) - Op = LowerGlobalAddress(GA->getGlobal(), Op.getDebugLoc(), - Offset, DAG); - else - Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0), - Offset); - Result = Op; - break; - } - - // Otherwise, not valid for this mode. - return; + if (hasMemory) + Op = LowerGlobalAddress(GA->getGlobal(), Op.getDebugLoc(), Offset, DAG); + else + Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0), + Offset); + Result = Op; + break; } } Added: llvm/trunk/test/CodeGen/X86/2009-05-08-InlineAsmIOffset.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-05-08-InlineAsmIOffset.ll?rev=71232&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-05-08-InlineAsmIOffset.ll (added) +++ llvm/trunk/test/CodeGen/X86/2009-05-08-InlineAsmIOffset.ll Fri May 8 13:23:14 2009 @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | llc -relocation-model=static > %t +; RUN: grep "1: ._pv_cpu_ops+8" %t +; RUN: grep "2: ._G" %t +; PR4152 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin9.6" + %struct.pv_cpu_ops = type { i32, [2 x i32] } + at pv_cpu_ops = external global %struct.pv_cpu_ops ; <%struct.pv_cpu_ops*> [#uses=1] + at G = external global i32 ; [#uses=1] + +define void @x() nounwind { +entry: + tail call void asm sideeffect "1: $0", "i,~{dirflag},~{fpsr},~{flags}"(i32* getelementptr (%struct.pv_cpu_ops* @pv_cpu_ops, i32 0, i32 1, i32 1)) nounwind + tail call void asm sideeffect "2: $0", "i,~{dirflag},~{fpsr},~{flags}"(i32* @G) nounwind + ret void +} From asl at math.spbu.ru Fri May 8 13:50:26 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Fri, 08 May 2009 18:50:26 -0000 Subject: [llvm-commits] [llvm] r71235 - /llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td Message-ID: <200905081850.n48IoQfu021839@zion.cs.uiuc.edu> Author: asl Date: Fri May 8 13:50:26 2009 New Revision: 71235 URL: http://llvm.org/viewvc/llvm-project?rev=71235&view=rev Log: Add 8 bit select Modified: llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td Modified: llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td?rev=71235&r1=71234&r2=71235&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td Fri May 8 13:50:26 2009 @@ -107,6 +107,10 @@ } let usesCustomDAGSchedInserter = 1 in { + def Select8 : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2, i8imm:$cc), + "# Select8 PSEUDO", + [(set GR8:$dst, + (MSP430selectcc GR8:$src1, GR8:$src2, imm:$cc))]>; def Select16 : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2, i8imm:$cc), "# Select16 PSEUDO", [(set GR16:$dst, From asl at math.spbu.ru Fri May 8 13:50:41 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Fri, 08 May 2009 18:50:41 -0000 Subject: [llvm-commits] [llvm] r71236 - /llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp Message-ID: <200905081850.n48Iof3s021862@zion.cs.uiuc.edu> Author: asl Date: Fri May 8 13:50:41 2009 New Revision: 71236 URL: http://llvm.org/viewvc/llvm-project?rev=71236&view=rev Log: Expand UREM / SREM into libcalls Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp?rev=71236&r1=71235&r2=71236&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp Fri May 8 13:50:41 2009 @@ -98,8 +98,10 @@ setOperationAction(ISD::UDIV, MVT::i16, Expand); setOperationAction(ISD::UDIVREM, MVT::i16, Expand); + setOperationAction(ISD::UREM, MVT::i16, Expand); setOperationAction(ISD::SDIV, MVT::i16, Expand); setOperationAction(ISD::SDIVREM, MVT::i16, Expand); + setOperationAction(ISD::SREM, MVT::i16, Expand); } SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { From asl at math.spbu.ru Fri May 8 13:50:55 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Fri, 08 May 2009 18:50:55 -0000 Subject: [llvm-commits] [llvm] r71237 - /llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Message-ID: <200905081850.n48Iot4O021888@zion.cs.uiuc.edu> Author: asl Date: Fri May 8 13:50:54 2009 New Revision: 71237 URL: http://llvm.org/viewvc/llvm-project?rev=71237&view=rev Log: Typo Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=71237&r1=71236&r2=71237&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Fri May 8 13:50:54 2009 @@ -71,7 +71,7 @@ Names[RTLIB::SDIV_I32] = "__divsi3"; Names[RTLIB::SDIV_I64] = "__divdi3"; Names[RTLIB::SDIV_I128] = "__divti3"; - Names[RTLIB::UDIV_I32] = "__udivhi3"; + Names[RTLIB::UDIV_I16] = "__udivhi3"; Names[RTLIB::UDIV_I32] = "__udivsi3"; Names[RTLIB::UDIV_I64] = "__udivdi3"; Names[RTLIB::UDIV_I128] = "__udivti3"; From asl at math.spbu.ru Fri May 8 13:51:08 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Fri, 08 May 2009 18:51:08 -0000 Subject: [llvm-commits] [llvm] r71238 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200905081851.n48Ip8PN021912@zion.cs.uiuc.edu> Author: asl Date: Fri May 8 13:51:08 2009 New Revision: 71238 URL: http://llvm.org/viewvc/llvm-project?rev=71238&view=rev Log: Properly expand libcalls for urem / srem. Also make code more straightforward. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=71238&r1=71237&r2=71238&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri May 8 13:51:08 2009 @@ -3564,36 +3564,47 @@ break; } - if (VT.isInteger()) { - if (TLI.getOperationAction(DivOpc, VT) == - TargetLowering::Legal) { - // X % Y -> X-X/Y*Y - Result = DAG.getNode(DivOpc, dl, VT, Tmp1, Tmp2); - Result = DAG.getNode(ISD::MUL, dl, VT, Result, Tmp2); - Result = DAG.getNode(ISD::SUB, dl, VT, Tmp1, Result); - } else if (VT.isVector()) { - Result = LegalizeOp(UnrollVectorOp(Op)); - } else { - assert(VT == MVT::i32 && - "Cannot expand this binary operator!"); - RTLIB::Libcall LC = Node->getOpcode() == ISD::UREM - ? RTLIB::UREM_I32 : RTLIB::SREM_I32; - SDValue Dummy; - Result = ExpandLibCall(LC, Node, isSigned, Dummy); - } - } else { - assert(VT.isFloatingPoint() && - "remainder op must have integer or floating-point type"); - if (VT.isVector()) { - Result = LegalizeOp(UnrollVectorOp(Op)); - } else { - // Floating point mod -> fmod libcall. - RTLIB::Libcall LC = GetFPLibCall(VT, RTLIB::REM_F32, RTLIB::REM_F64, - RTLIB::REM_F80, RTLIB::REM_PPCF128); - SDValue Dummy; - Result = ExpandLibCall(LC, Node, false/*sign irrelevant*/, Dummy); - } + if (VT.isInteger() && + TLI.getOperationAction(DivOpc, VT) == TargetLowering::Legal) { + // X % Y -> X-X/Y*Y + Result = DAG.getNode(DivOpc, dl, VT, Tmp1, Tmp2); + Result = DAG.getNode(ISD::MUL, dl, VT, Result, Tmp2); + Result = DAG.getNode(ISD::SUB, dl, VT, Tmp1, Result); + break; + } + + // Check to see if we have a libcall for this operator. + RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; + switch (Node->getOpcode()) { + default: break; + case ISD::UREM: + case ISD::SREM: + if (VT == MVT::i16) + LC = (isSigned ? RTLIB::SREM_I16 : RTLIB::UREM_I16); + else if (VT == MVT::i32) + LC = (isSigned ? RTLIB::SREM_I32 : RTLIB::UREM_I32); + else if (VT == MVT::i64) + LC = (isSigned ? RTLIB::SREM_I64 : RTLIB::UREM_I64); + else if (VT == MVT::i128) + LC = (isSigned ? RTLIB::SREM_I128 : RTLIB::UREM_I128); + break; + case ISD::FREM: + // Floating point mod -> fmod libcall. + LC = GetFPLibCall(VT, RTLIB::REM_F32, RTLIB::REM_F64, + RTLIB::REM_F80, RTLIB::REM_PPCF128); + break; + } + + if (LC != RTLIB::UNKNOWN_LIBCALL) { + SDValue Dummy; + Result = ExpandLibCall(LC, Node, isSigned, Dummy); + break; } + + assert(VT.isVector() && + "Cannot expand this binary operator!"); + // Expand the operation into a bunch of nasty scalar code. + Result = LegalizeOp(UnrollVectorOp(Op)); break; } } From asl at math.spbu.ru Fri May 8 13:51:21 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Fri, 08 May 2009 18:51:21 -0000 Subject: [llvm-commits] [llvm] r71239 - /llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp Message-ID: <200905081851.n48IpLW5021930@zion.cs.uiuc.edu> Author: asl Date: Fri May 8 13:51:21 2009 New Revision: 71239 URL: http://llvm.org/viewvc/llvm-project?rev=71239&view=rev Log: Allow 8 bit select in custom inserter Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp?rev=71239&r1=71238&r2=71239&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp Fri May 8 13:51:21 2009 @@ -610,7 +610,8 @@ MachineBasicBlock *BB) const { const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); DebugLoc dl = MI->getDebugLoc(); - assert((MI->getOpcode() == MSP430::Select16) && + assert((MI->getOpcode() == MSP430::Select16 || + MI->getOpcode() == MSP430::Select8) && "Unexpected instr type to insert"); // To "insert" a SELECT instruction, we actually have to insert the diamond From asl at math.spbu.ru Fri May 8 13:51:35 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Fri, 08 May 2009 18:51:35 -0000 Subject: [llvm-commits] [llvm] r71240 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200905081851.n48IpZVU021986@zion.cs.uiuc.edu> Author: asl Date: Fri May 8 13:51:34 2009 New Revision: 71240 URL: http://llvm.org/viewvc/llvm-project?rev=71240&view=rev Log: Do not emit bit tests if target does not support natively left shift Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=71240&r1=71239&r2=71240&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Fri May 8 13:51:34 2009 @@ -1923,6 +1923,10 @@ // inserting any additional MBBs necessary to represent the switch. MachineFunction *CurMF = CurMBB->getParent(); + // If target does not have legal shift left, do not emit bit tests at all. + if (!TLI.isOperationLegal(ISD::SHL, TLI.getPointerTy())) + return false; + size_t numCmps = 0; for (CaseItr I = CR.Range.first, E = CR.Range.second; I!=E; ++I) { From asl at math.spbu.ru Fri May 8 13:51:58 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Fri, 08 May 2009 18:51:58 -0000 Subject: [llvm-commits] [llvm] r71241 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGISel.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200905081851.n48IpwCg022028@zion.cs.uiuc.edu> Author: asl Date: Fri May 8 13:51:58 2009 New Revision: 71241 URL: http://llvm.org/viewvc/llvm-project?rev=71241&view=rev Log: Factor out cycle-finder code and make it generic. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h?rev=71241&r1=71240&r2=71241&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h Fri May 8 13:51:58 2009 @@ -88,10 +88,8 @@ /// U can be folded during instruction selection that starts at Root and /// folding N is profitable. virtual - bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const { - return true; - } - + bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const; + /// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer /// to use for this target when scheduling the DAG. virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer(); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=71241&r1=71240&r2=71241&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri May 8 13:51:58 2009 @@ -1203,4 +1203,120 @@ Ops.push_back(InOps.back()); } +/// findFlagUse - Return use of MVT::Flag value produced by the specified +/// SDNode. +/// +static SDNode *findFlagUse(SDNode *N) { + unsigned FlagResNo = N->getNumValues()-1; + for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) { + SDUse &Use = I.getUse(); + if (Use.getResNo() == FlagResNo) + return Use.getUser(); + } + return NULL; +} + +/// findNonImmUse - Return true if "Use" is a non-immediate use of "Def". +/// This function recursively traverses up the operand chain, ignoring +/// certain nodes. +static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse, + SDNode *Root, + SmallPtrSet &Visited) { + if (Use->getNodeId() < Def->getNodeId() || + !Visited.insert(Use)) + return false; + + for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) { + SDNode *N = Use->getOperand(i).getNode(); + if (N == Def) { + if (Use == ImmedUse || Use == Root) + continue; // We are not looking for immediate use. + assert(N != Root); + return true; + } + + // Traverse up the operand chain. + if (findNonImmUse(N, Def, ImmedUse, Root, Visited)) + return true; + } + return false; +} + +/// isNonImmUse - Start searching from Root up the DAG to check is Def can +/// be reached. Return true if that's the case. However, ignore direct uses +/// by ImmedUse (which would be U in the example illustrated in +/// IsLegalAndProfitableToFold) and by Root (which can happen in the store +/// case). +/// FIXME: to be really generic, we should allow direct use by any node +/// that is being folded. But realisticly since we only fold loads which +/// have one non-chain use, we only need to watch out for load/op/store +/// and load/op/cmp case where the root (store / cmp) may reach the load via +/// its chain operand. +static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse) { + SmallPtrSet Visited; + return findNonImmUse(Root, Def, ImmedUse, Root, Visited); +} + +/// IsLegalAndProfitableToFold - Returns true if the specific operand node N of +/// U can be folded during instruction selection that starts at Root and +/// folding N is profitable. +bool SelectionDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U, + SDNode *Root) const { + if (OptLevel == CodeGenOpt::None) return false; + + // If Root use can somehow reach N through a path that that doesn't contain + // U then folding N would create a cycle. e.g. In the following + // diagram, Root can reach N through X. If N is folded into into Root, then + // X is both a predecessor and a successor of U. + // + // [N*] // + // ^ ^ // + // / \ // + // [U*] [X]? // + // ^ ^ // + // \ / // + // \ / // + // [Root*] // + // + // * indicates nodes to be folded together. + // + // If Root produces a flag, then it gets (even more) interesting. Since it + // will be "glued" together with its flag use in the scheduler, we need to + // check if it might reach N. + // + // [N*] // + // ^ ^ // + // / \ // + // [U*] [X]? // + // ^ ^ // + // \ \ // + // \ | // + // [Root*] | // + // ^ | // + // f | // + // | / // + // [Y] / // + // ^ / // + // f / // + // | / // + // [FU] // + // + // If FU (flag use) indirectly reaches N (the load), and Root folds N + // (call it Fold), then X is a predecessor of FU and a successor of + // Fold. But since Fold and FU are flagged together, this will create + // a cycle in the scheduling graph. + + MVT VT = Root->getValueType(Root->getNumValues()-1); + while (VT == MVT::Flag) { + SDNode *FU = findFlagUse(Root); + if (FU == NULL) + break; + Root = FU; + VT = Root->getValueType(Root->getNumValues()-1); + } + + return !isNonImmUse(Root, N, U); +} + + char SelectionDAGISel::ID = 0; Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=71241&r1=71240&r2=71241&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Fri May 8 13:51:58 2009 @@ -249,60 +249,6 @@ }; } -/// findFlagUse - Return use of MVT::Flag value produced by the specified -/// SDNode. -/// -static SDNode *findFlagUse(SDNode *N) { - unsigned FlagResNo = N->getNumValues()-1; - for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) { - SDUse &Use = I.getUse(); - if (Use.getResNo() == FlagResNo) - return Use.getUser(); - } - return NULL; -} - -/// findNonImmUse - Return true if "Use" is a non-immediate use of "Def". -/// This function recursively traverses up the operand chain, ignoring -/// certain nodes. -static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse, - SDNode *Root, - SmallPtrSet &Visited) { - if (Use->getNodeId() < Def->getNodeId() || - !Visited.insert(Use)) - return false; - - for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) { - SDNode *N = Use->getOperand(i).getNode(); - if (N == Def) { - if (Use == ImmedUse || Use == Root) - continue; // We are not looking for immediate use. - assert(N != Root); - return true; - } - - // Traverse up the operand chain. - if (findNonImmUse(N, Def, ImmedUse, Root, Visited)) - return true; - } - return false; -} - -/// isNonImmUse - Start searching from Root up the DAG to check is Def can -/// be reached. Return true if that's the case. However, ignore direct uses -/// by ImmedUse (which would be U in the example illustrated in -/// IsLegalAndProfitableToFold) and by Root (which can happen in the store -/// case). -/// FIXME: to be really generic, we should allow direct use by any node -/// that is being folded. But realisticly since we only fold loads which -/// have one non-chain use, we only need to watch out for load/op/store -/// and load/op/cmp case where the root (store / cmp) may reach the load via -/// its chain operand. -static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse) { - SmallPtrSet Visited; - return findNonImmUse(Root, Def, ImmedUse, Root, Visited); -} - bool X86DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const { @@ -351,58 +297,8 @@ } } - // If Root use can somehow reach N through a path that that doesn't contain - // U then folding N would create a cycle. e.g. In the following - // diagram, Root can reach N through X. If N is folded into into Root, then - // X is both a predecessor and a successor of U. - // - // [N*] // - // ^ ^ // - // / \ // - // [U*] [X]? // - // ^ ^ // - // \ / // - // \ / // - // [Root*] // - // - // * indicates nodes to be folded together. - // - // If Root produces a flag, then it gets (even more) interesting. Since it - // will be "glued" together with its flag use in the scheduler, we need to - // check if it might reach N. - // - // [N*] // - // ^ ^ // - // / \ // - // [U*] [X]? // - // ^ ^ // - // \ \ // - // \ | // - // [Root*] | // - // ^ | // - // f | // - // | / // - // [Y] / // - // ^ / // - // f / // - // | / // - // [FU] // - // - // If FU (flag use) indirectly reaches N (the load), and Root folds N - // (call it Fold), then X is a predecessor of FU and a successor of - // Fold. But since Fold and FU are flagged together, this will create - // a cycle in the scheduling graph. - - MVT VT = Root->getValueType(Root->getNumValues()-1); - while (VT == MVT::Flag) { - SDNode *FU = findFlagUse(Root); - if (FU == NULL) - break; - Root = FU; - VT = Root->getValueType(Root->getNumValues()-1); - } - - return !isNonImmUse(Root, N, U); + // Proceed to 'generic' cycle finder code + return SelectionDAGISel::IsLegalAndProfitableToFold(N, U, Root); } /// MoveBelowTokenFactor - Replace TokenFactor operand with load's chain operand From evan.cheng at apple.com Fri May 8 14:01:44 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 08 May 2009 19:01:44 -0000 Subject: [llvm-commits] [llvm] r71242 - /llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Message-ID: <200905081901.n48J1iLM022345@zion.cs.uiuc.edu> Author: evancheng Date: Fri May 8 14:01:44 2009 New Revision: 71242 URL: http://llvm.org/viewvc/llvm-project?rev=71242&view=rev Log: Don't align loop header unless the loop back edge is below the header. Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp?rev=71242&r1=71241&r2=71242&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp (original) +++ llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Fri May 8 14:01:44 2009 @@ -249,6 +249,20 @@ return Changed; } +/// HeaderShouldBeAligned - Return true if the specified loop header block +/// should be aligned. For now, we will not align it if all the predcessors +/// (i.e. loop back edges) are laid out above the header. FIXME: Do not +/// align small loops. +static bool HeaderShouldBeAligned(MachineBasicBlock *MBB) { + for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), + PE = MBB->pred_end(); PI != PE; ++PI) { + MachineBasicBlock *PredMBB = *PI; + if (PredMBB->getNumber() > MBB->getNumber()) + return true; + } + return false; +} + /// AlignLoops - Align loop headers to target preferred alignments. /// bool CodePlacementOpt::AlignLoops(MachineFunction &MF) { @@ -267,9 +281,11 @@ for (unsigned i = 0, e = LoopHeaders.size(); i != e; ++i) { MachineBasicBlock *HeaderMBB = LoopHeaders[i]; MachineBasicBlock *PredMBB = prior(MachineFunction::iterator(HeaderMBB)); - if (MLI->getLoopFor(HeaderMBB) != MLI->getLoopFor(PredMBB)) { + if (MLI->getLoopFor(HeaderMBB) == MLI->getLoopFor(PredMBB)) // If previously BB is in the same loop, don't align this BB. We want // to prevent adding noop's inside a loop. + continue; + if (HeaderShouldBeAligned(HeaderMBB)) { HeaderMBB->setAlignment(Align); Changed = true; ++NumHeaderAligned; From akyrtzi at gmail.com Fri May 8 14:17:16 2009 From: akyrtzi at gmail.com (Argiris Kirtzidis) Date: Fri, 08 May 2009 22:17:16 +0300 Subject: [llvm-commits] Add scope info in DebugLoc In-Reply-To: References: <4A037F8D.90001@gmail.com> Message-ID: <4A04853C.8010406@gmail.com> Evan Cheng wrote: > Eventually we'd like to move scoping information to the llvm IR level. > IR support would be ideal. Will it support line info as well ? -Argiris From stefanus.dutoit at rapidmind.com Fri May 8 14:20:51 2009 From: stefanus.dutoit at rapidmind.com (Stefanus Du Toit) Date: Fri, 8 May 2009 15:20:51 -0400 Subject: [llvm-commits] Add scope info in DebugLoc In-Reply-To: References: <4A037F8D.90001@gmail.com> Message-ID: <93F848A1-C3AE-4B6A-8358-A3AFD599C9B9@rapidmind.com> On 8-May-09, at 1:25 PM, Evan Cheng wrote: > Eventually we'd like to move scoping information to the llvm IR level. > But this seems like a good interim step. Bill can you review this when > you have some time? Just curious, is this purely for debugging/profiling, or do you intend to use scope information to assist optimizations in some way? -- Stefanus Du Toit RapidMind Inc. phone: +1 519 885 5455 x116 -- fax: +1 519 885 1463 From isanbard at gmail.com Fri May 8 14:50:16 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 8 May 2009 12:50:16 -0700 Subject: [llvm-commits] Add scope info in DebugLoc In-Reply-To: <93F848A1-C3AE-4B6A-8358-A3AFD599C9B9@rapidmind.com> References: <4A037F8D.90001@gmail.com> <93F848A1-C3AE-4B6A-8358-A3AFD599C9B9@rapidmind.com> Message-ID: <16e5fdf90905081250j1be44edajd5a3fd800ce7362a@mail.gmail.com> On Fri, May 8, 2009 at 12:20 PM, Stefanus Du Toit wrote: > On 8-May-09, at 1:25 PM, Evan Cheng wrote: >> Eventually we'd like to move scoping information to the llvm IR level. >> But this seems like a good interim step. Bill can you review this when >> you have some time? > > Just curious, is this purely for debugging/profiling, or do you intend > to use scope information to assist optimizations in some way? > The former. I don't think that there are any plans to do this for optimizations. -bw From isanbard at gmail.com Fri May 8 14:50:44 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 8 May 2009 12:50:44 -0700 Subject: [llvm-commits] Add scope info in DebugLoc In-Reply-To: <4A04853C.8010406@gmail.com> References: <4A037F8D.90001@gmail.com> <4A04853C.8010406@gmail.com> Message-ID: <16e5fdf90905081250n18b8487bkd13edff0f370e3ab@mail.gmail.com> On Fri, May 8, 2009 at 12:17 PM, Argiris Kirtzidis wrote: > Evan Cheng wrote: >> Eventually we'd like to move scoping information to the llvm IR level. >> > > IR support would be ideal. Will it support line info as well ? > I believe that that's the goal. -bw From clattner at apple.com Fri May 8 14:52:43 2009 From: clattner at apple.com (Chris Lattner) Date: Fri, 8 May 2009 12:52:43 -0700 Subject: [llvm-commits] Add scope info in DebugLoc In-Reply-To: <93F848A1-C3AE-4B6A-8358-A3AFD599C9B9@rapidmind.com> References: <4A037F8D.90001@gmail.com> <93F848A1-C3AE-4B6A-8358-A3AFD599C9B9@rapidmind.com> Message-ID: <43560E69-29A6-4BCA-82A0-AA88BCEEB6A1@apple.com> > IR support would be ideal. Will it support line info as well ? The goal is to move DebugLoc into the Instruction class (like it is in MachineInstr), and encode into the 32-bit cookie information about line numbers and scopes (regionstart/end info). This information should include inline function information as well. The thought is that this will make the debug information much easier to reconstruct in the front-end and also makes it easy to preserve through the optimizer. The outstanding question is how to encode debugloc in 32- bit and retain this information. Something like the clang SourceLocation approach should work, though I haven't had time to think much about it. On May 8, 2009, at 12:20 PM, Stefanus Du Toit wrote: > On 8-May-09, at 1:25 PM, Evan Cheng wrote: >> Eventually we'd like to move scoping information to the llvm IR >> level. >> But this seems like a good interim step. Bill can you review this >> when >> you have some time? > > Just curious, is this purely for debugging/profiling, or do you intend > to use scope information to assist optimizations in some way? This is metadata, so it should only be used for debug info, diagnostics, etc. I'm also interested in adding explicit intrinsics for "this memory location is dead/live here" but that will be an explicit thing in the IR. -Chris From gohman at apple.com Fri May 8 15:07:23 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 08 May 2009 20:07:23 -0000 Subject: [llvm-commits] [llvm] r71245 - /llvm/trunk/include/llvm/Analysis/LoopInfo.h Message-ID: <200905082007.n48K7Ngw024622@zion.cs.uiuc.edu> Author: djg Date: Fri May 8 15:07:23 2009 New Revision: 71245 URL: http://llvm.org/viewvc/llvm-project?rev=71245&view=rev Log: Add a getExitBlock utility function to LoopInfo which returns the exit block of a loop, if there is exactly one, similar to getExitingBlock. Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=71245&r1=71244&r2=71245&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Fri May 8 15:07:23 2009 @@ -213,6 +213,16 @@ ExitBlocks.push_back(*I); } + /// getExitBlock - If getExitBlocks would return exactly one block, + /// return that block. Otherwise return null. + BlockT *getExitBlock() const { + SmallVector ExitBlocks; + getExitBlocks(ExitBlocks); + if (ExitBlocks.size() == 1) + return ExitBlocks[0]; + return 0; + } + /// getUniqueExitBlocks - Return all unique successor blocks of this loop. /// These are the blocks _outside of the current loop_ which are branched to. /// This assumes that loop is in canonical form. From gohman at apple.com Fri May 8 15:18:49 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 08 May 2009 20:18:49 -0000 Subject: [llvm-commits] [llvm] r71247 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200905082018.n48KIn9w024967@zion.cs.uiuc.edu> Author: djg Date: Fri May 8 15:18:49 2009 New Revision: 71247 URL: http://llvm.org/viewvc/llvm-project?rev=71247&view=rev Log: Implement several new SCEV folding rules for UDiv SCEVs. This fixes an old FIXME, and is needed by some upcoming changes. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71247&r1=71246&r2=71247&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May 8 15:18:49 2009 @@ -1306,7 +1306,61 @@ if (const SCEVConstant *RHSC = dyn_cast(RHS)) { if (RHSC->getValue()->equalsInt(1)) return LHS; // X udiv 1 --> x + if (RHSC->isZero()) + return getIntegerSCEV(0, LHS->getType()); // value is undefined + // Determine if the division can be folded into the operands of + // its operands. + // TODO: Generalize this to non-constants by using known-bits information. + const Type *Ty = LHS->getType(); + unsigned LZ = RHSC->getValue()->getValue().countLeadingZeros(); + unsigned MaxShiftAmt = getTypeSizeInBits(Ty) - LZ; + // For non-power-of-two values, effectively round the value up to the + // nearest power of two. + if (!RHSC->getValue()->getValue().isPowerOf2()) + ++MaxShiftAmt; + const IntegerType *ExtTy = + IntegerType::get(getTypeSizeInBits(Ty) + MaxShiftAmt); + // {X,+,N}/C --> {X/C,+,N/C} if safe and N/C can be folded. + if (const SCEVAddRecExpr *AR = dyn_cast(LHS)) + if (const SCEVConstant *Step = + dyn_cast(AR->getStepRecurrence(*this))) + if (!Step->getValue()->getValue() + .urem(RHSC->getValue()->getValue()) && + getTruncateExpr(getZeroExtendExpr(AR, ExtTy), Ty) == AR) { + std::vector Operands; + for (unsigned i = 0, e = AR->getNumOperands(); i != e; ++i) + Operands.push_back(getUDivExpr(AR->getOperand(i), RHS)); + return getAddRecExpr(Operands, AR->getLoop()); + } + // (A*B)/C --> A*(B/C) if safe and B/C can be folded. + if (const SCEVMulExpr *M = dyn_cast(LHS)) + if (getTruncateExpr(getZeroExtendExpr(M, ExtTy), Ty) == M) + // Find an operand that's safely divisible. + for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i) { + SCEVHandle Op = M->getOperand(i); + SCEVHandle Div = getUDivExpr(Op, RHSC); + if (!isa(Div) && getMulExpr(Div, RHSC) == Op) { + std::vector Operands = M->getOperands(); + Operands[i] = Div; + return getMulExpr(Operands); + } + } + // (A+B)/C --> (A/C + B/C) if safe and A/C and B/C can be folded. + if (const SCEVAddRecExpr *A = dyn_cast(LHS)) + if (getTruncateExpr(getZeroExtendExpr(A, ExtTy), Ty) == A) { + std::vector Operands; + for (unsigned i = 0, e = A->getNumOperands(); i != e; ++i) { + SCEVHandle Op = getUDivExpr(A->getOperand(i), RHS); + if (isa(Op) || getMulExpr(Op, RHS) != A->getOperand(i)) + break; + Operands.push_back(Op); + } + if (Operands.size() == A->getNumOperands()) + return getAddExpr(Operands); + } + + // Fold if both operands are constant. if (const SCEVConstant *LHSC = dyn_cast(LHS)) { Constant *LHSCV = LHSC->getValue(); Constant *RHSCV = RHSC->getValue(); @@ -1314,8 +1368,6 @@ } } - // FIXME: implement folding of (X*4)/4 when we know X*4 doesn't overflow. - SCEVUDivExpr *&Result = (*SCEVUDivs)[std::make_pair(LHS, RHS)]; if (Result == 0) Result = new SCEVUDivExpr(LHS, RHS); return Result; From isanbard at gmail.com Fri May 8 15:20:58 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 08 May 2009 20:20:58 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r71249 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <200905082020.n48KKwTa025097@zion.cs.uiuc.edu> Author: void Date: Fri May 8 15:20:57 2009 New Revision: 71249 URL: http://llvm.org/viewvc/llvm-project?rev=71249&view=rev Log: Conditionalize checking for ObjC prefix on whether this is an ObjC program. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp 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=71249&r1=71248&r2=71249&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Fri May 8 15:20:57 2009 @@ -1395,8 +1395,9 @@ const char LPrefix[] = "\01L_OBJC_"; const char lPrefix[] = "\01l_OBJC_"; - if (strncmp(Name, LPrefix, sizeof(LPrefix) - 1) != 0 && - strncmp(Name, lPrefix, sizeof(lPrefix) - 1) != 0) + if (flag_objc_abi == -1 || flag_objc_abi == 0 || + (strncmp(Name, LPrefix, sizeof(LPrefix) - 1) != 0 && + strncmp(Name, lPrefix, sizeof(lPrefix) - 1) != 0)) TheDebugInfo->EmitGlobalVariable(GV, decl); } From gohman at apple.com Fri May 8 15:26:56 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 08 May 2009 20:26:56 -0000 Subject: [llvm-commits] [llvm] r71252 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp Message-ID: <200905082026.n48KQum8025389@zion.cs.uiuc.edu> Author: djg Date: Fri May 8 15:26:55 2009 New Revision: 71252 URL: http://llvm.org/viewvc/llvm-project?rev=71252&view=rev Log: Factor out the code for creating SCEVs for GEPs into a separate function. Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=71252&r1=71251&r2=71252&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Fri May 8 15:26:55 2009 @@ -279,6 +279,10 @@ /// SCEVs. SCEVHandle createNodeForPHI(PHINode *PN); + /// createNodeForGEP - Provide the special handling we need to analyze GEP + /// SCEVs. + SCEVHandle createNodeForGEP(GetElementPtrInst *GEP); + /// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value /// for the specified instruction and replaces any references to the /// symbolic value SymName with the specified value. This is used during Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71252&r1=71251&r2=71252&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May 8 15:26:55 2009 @@ -1863,6 +1863,44 @@ return getUnknown(PN); } +/// createNodeForGEP - Expand GEP instructions into add and multiply +/// operations. This allows them to be analyzed by regular SCEV code. +/// +SCEVHandle ScalarEvolution::createNodeForGEP(GetElementPtrInst *GEP) { + + const Type *IntPtrTy = TD->getIntPtrType(); + Value *Base = U->getOperand(0); + SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy); + gep_type_iterator GTI = gep_type_begin(U); + for (GetElementPtrInst::op_iterator I = next(U->op_begin()), + E = U->op_end(); + I != E; ++I) { + Value *Index = *I; + // Compute the (potentially symbolic) offset in bytes for this index. + if (const StructType *STy = dyn_cast(*GTI++)) { + // For a struct, add the member offset. + const StructLayout &SL = *TD->getStructLayout(STy); + unsigned FieldNo = cast(Index)->getZExtValue(); + uint64_t Offset = SL.getElementOffset(FieldNo); + TotalOffset = getAddExpr(TotalOffset, + getIntegerSCEV(Offset, IntPtrTy)); + } else { + // For an array, add the element offset, explicitly scaled. + SCEVHandle LocalOffset = getSCEV(Index); + if (!isa(LocalOffset->getType())) + // Getelementptr indicies are signed. + LocalOffset = getTruncateOrSignExtend(LocalOffset, + IntPtrTy); + LocalOffset = + getMulExpr(LocalOffset, + getIntegerSCEV(TD->getTypePaddedSize(*GTI), + IntPtrTy)); + TotalOffset = getAddExpr(TotalOffset, LocalOffset); + } + } + return getAddExpr(getSCEV(Base), TotalOffset); +} + /// GetMinTrailingZeros - Determine the minimum number of zero bits that S is /// guaranteed to end in (at every loop iteration). It is, at the same time, /// the minimum number of times S is divisible by 2. For example, given {4,+,8} @@ -2073,40 +2111,9 @@ return getTruncateOrZeroExtend(getSCEV(U->getOperand(0)), U->getType()); - case Instruction::GetElementPtr: { + case Instruction::GetElementPtr: if (!TD) break; // Without TD we can't analyze pointers. - const Type *IntPtrTy = TD->getIntPtrType(); - Value *Base = U->getOperand(0); - SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy); - gep_type_iterator GTI = gep_type_begin(U); - for (GetElementPtrInst::op_iterator I = next(U->op_begin()), - E = U->op_end(); - I != E; ++I) { - Value *Index = *I; - // Compute the (potentially symbolic) offset in bytes for this index. - if (const StructType *STy = dyn_cast(*GTI++)) { - // For a struct, add the member offset. - const StructLayout &SL = *TD->getStructLayout(STy); - unsigned FieldNo = cast(Index)->getZExtValue(); - uint64_t Offset = SL.getElementOffset(FieldNo); - TotalOffset = getAddExpr(TotalOffset, - getIntegerSCEV(Offset, IntPtrTy)); - } else { - // For an array, add the element offset, explicitly scaled. - SCEVHandle LocalOffset = getSCEV(Index); - if (!isa(LocalOffset->getType())) - // Getelementptr indicies are signed. - LocalOffset = getTruncateOrSignExtend(LocalOffset, - IntPtrTy); - LocalOffset = - getMulExpr(LocalOffset, - getIntegerSCEV(TD->getTypePaddedSize(*GTI), - IntPtrTy)); - TotalOffset = getAddExpr(TotalOffset, LocalOffset); - } - } - return getAddExpr(getSCEV(Base), TotalOffset); - } + return createNodeForGEP(cast(U)); case Instruction::PHI: return createNodeForPHI(cast(U)); From isanbard at gmail.com Fri May 8 15:28:06 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 08 May 2009 20:28:06 -0000 Subject: [llvm-commits] [llvm] r71253 - /llvm/trunk/lib/Analysis/DebugInfo.cpp Message-ID: <200905082028.n48KS6YD025448@zion.cs.uiuc.edu> Author: void Date: Fri May 8 15:28:06 2009 New Revision: 71253 URL: http://llvm.org/viewvc/llvm-project?rev=71253&view=rev Log: Print out nicer dump info for DIDescriptor. Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=71253&r1=71252&r2=71253&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Fri May 8 15:28:06 2009 @@ -983,7 +983,8 @@ /// dump - print descriptor. void DIDescriptor::dump() const { - cerr << " [" << dwarf::TagString(getTag()) << "]\n"; + cerr << "[" << dwarf::TagString(getTag()) << "] "; + cerr << std::hex << "[GV:" << GV << "]" << std::dec; } /// dump - print compile unit. From isanbard at gmail.com Fri May 8 15:35:32 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 8 May 2009 13:35:32 -0700 Subject: [llvm-commits] [llvm] r71252 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp In-Reply-To: <200905082026.n48KQum8025389@zion.cs.uiuc.edu> References: <200905082026.n48KQum8025389@zion.cs.uiuc.edu> Message-ID: <16e5fdf90905081335n507b88e9kcd3c7d9b42dbda3d@mail.gmail.com> Hi Dan, I'm getting these errors with this patch: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/lib/Analysis/ScalarEvolution.cpp: In member function 'llvm::SCEVHandle llvm::ScalarEvolution::createNodeForGEP(llvm::GetElementPtrInst*)': /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/lib/Analysis/ScalarEvolution.cpp:1872: error: 'U' was not declared in this scope /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/lib/Analysis/ScalarEvolution.cpp:1874: error: no matching function for call to 'gep_type_begin()' /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/include/llvm/Support/GetElementPtrTypeIterator.h:84: note: candidates are: llvm::gep_type_iterator llvm::gep_type_begin(const llvm::User*) /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/include/llvm/Support/GetElementPtrTypeIterator.h:91: note: llvm::gep_type_iterator llvm::gep_type_begin(const llvm::User&) On Fri, May 8, 2009 at 1:26 PM, Dan Gohman wrote: > Author: djg > Date: Fri May ?8 15:26:55 2009 > New Revision: 71252 > > URL: http://llvm.org/viewvc/llvm-project?rev=71252&view=rev > Log: > Factor out the code for creating SCEVs for GEPs into a > separate function. > > Modified: > ? ?llvm/trunk/include/llvm/Analysis/ScalarEvolution.h > ? ?llvm/trunk/lib/Analysis/ScalarEvolution.cpp > > Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=71252&r1=71251&r2=71252&view=diff > > ============================================================================== > --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) > +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Fri May ?8 15:26:55 2009 > @@ -279,6 +279,10 @@ > ? ? /// SCEVs. > ? ? SCEVHandle createNodeForPHI(PHINode *PN); > > + ? ?/// createNodeForGEP - Provide the special handling we need to analyze GEP > + ? ?/// SCEVs. > + ? ?SCEVHandle createNodeForGEP(GetElementPtrInst *GEP); > + > ? ? /// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value > ? ? /// for the specified instruction and replaces any references to the > ? ? /// symbolic value SymName with the specified value. ?This is used during > > Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71252&r1=71251&r2=71252&view=diff > > ============================================================================== > --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) > +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May ?8 15:26:55 2009 > @@ -1863,6 +1863,44 @@ > ? return getUnknown(PN); > ?} > > +/// createNodeForGEP - Expand GEP instructions into add and multiply > +/// operations. This allows them to be analyzed by regular SCEV code. > +/// > +SCEVHandle ScalarEvolution::createNodeForGEP(GetElementPtrInst *GEP) { > + > + ?const Type *IntPtrTy = TD->getIntPtrType(); > + ?Value *Base = U->getOperand(0); > + ?SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy); > + ?gep_type_iterator GTI = gep_type_begin(U); > + ?for (GetElementPtrInst::op_iterator I = next(U->op_begin()), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?E = U->op_end(); > + ? ? ? I != E; ++I) { > + ? ?Value *Index = *I; > + ? ?// Compute the (potentially symbolic) offset in bytes for this index. > + ? ?if (const StructType *STy = dyn_cast(*GTI++)) { > + ? ? ?// For a struct, add the member offset. > + ? ? ?const StructLayout &SL = *TD->getStructLayout(STy); > + ? ? ?unsigned FieldNo = cast(Index)->getZExtValue(); > + ? ? ?uint64_t Offset = SL.getElementOffset(FieldNo); > + ? ? ?TotalOffset = getAddExpr(TotalOffset, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?getIntegerSCEV(Offset, IntPtrTy)); > + ? ?} else { > + ? ? ?// For an array, add the element offset, explicitly scaled. > + ? ? ?SCEVHandle LocalOffset = getSCEV(Index); > + ? ? ?if (!isa(LocalOffset->getType())) > + ? ? ? ?// Getelementptr indicies are signed. > + ? ? ? ?LocalOffset = getTruncateOrSignExtend(LocalOffset, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IntPtrTy); > + ? ? ?LocalOffset = > + ? ? ? ?getMulExpr(LocalOffset, > + ? ? ? ? ? ? ? ? ? getIntegerSCEV(TD->getTypePaddedSize(*GTI), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IntPtrTy)); > + ? ? ?TotalOffset = getAddExpr(TotalOffset, LocalOffset); > + ? ?} > + ?} > + ?return getAddExpr(getSCEV(Base), TotalOffset); > +} > + > ?/// GetMinTrailingZeros - Determine the minimum number of zero bits that S is > ?/// guaranteed to end in (at every loop iteration). ?It is, at the same time, > ?/// the minimum number of times S is divisible by 2. ?For example, given {4,+,8} > @@ -2073,40 +2111,9 @@ > ? ? return getTruncateOrZeroExtend(getSCEV(U->getOperand(0)), > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?U->getType()); > > - ?case Instruction::GetElementPtr: { > + ?case Instruction::GetElementPtr: > ? ? if (!TD) break; // Without TD we can't analyze pointers. > - ? ?const Type *IntPtrTy = TD->getIntPtrType(); > - ? ?Value *Base = U->getOperand(0); > - ? ?SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy); > - ? ?gep_type_iterator GTI = gep_type_begin(U); > - ? ?for (GetElementPtrInst::op_iterator I = next(U->op_begin()), > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?E = U->op_end(); > - ? ? ? ? I != E; ++I) { > - ? ? ?Value *Index = *I; > - ? ? ?// Compute the (potentially symbolic) offset in bytes for this index. > - ? ? ?if (const StructType *STy = dyn_cast(*GTI++)) { > - ? ? ? ?// For a struct, add the member offset. > - ? ? ? ?const StructLayout &SL = *TD->getStructLayout(STy); > - ? ? ? ?unsigned FieldNo = cast(Index)->getZExtValue(); > - ? ? ? ?uint64_t Offset = SL.getElementOffset(FieldNo); > - ? ? ? ?TotalOffset = getAddExpr(TotalOffset, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?getIntegerSCEV(Offset, IntPtrTy)); > - ? ? ?} else { > - ? ? ? ?// For an array, add the element offset, explicitly scaled. > - ? ? ? ?SCEVHandle LocalOffset = getSCEV(Index); > - ? ? ? ?if (!isa(LocalOffset->getType())) > - ? ? ? ? ?// Getelementptr indicies are signed. > - ? ? ? ? ?LocalOffset = getTruncateOrSignExtend(LocalOffset, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IntPtrTy); > - ? ? ? ?LocalOffset = > - ? ? ? ? ?getMulExpr(LocalOffset, > - ? ? ? ? ? ? ? ? ? ? getIntegerSCEV(TD->getTypePaddedSize(*GTI), > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IntPtrTy)); > - ? ? ? ?TotalOffset = getAddExpr(TotalOffset, LocalOffset); > - ? ? ?} > - ? ?} > - ? ?return getAddExpr(getSCEV(Base), TotalOffset); > - ?} > + ? ?return createNodeForGEP(cast(U)); > > ? case Instruction::PHI: > ? ? return createNodeForPHI(cast(U)); > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From gohman at apple.com Fri May 8 15:36:47 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 08 May 2009 20:36:47 -0000 Subject: [llvm-commits] [llvm] r71255 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200905082036.n48Kalrg025775@zion.cs.uiuc.edu> Author: djg Date: Fri May 8 15:36:47 2009 New Revision: 71255 URL: http://llvm.org/viewvc/llvm-project?rev=71255&view=rev Log: Fix an error from r71252. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71255&r1=71254&r2=71255&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May 8 15:36:47 2009 @@ -1869,11 +1869,11 @@ SCEVHandle ScalarEvolution::createNodeForGEP(GetElementPtrInst *GEP) { const Type *IntPtrTy = TD->getIntPtrType(); - Value *Base = U->getOperand(0); + Value *Base = GEP->getOperand(0); SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy); - gep_type_iterator GTI = gep_type_begin(U); - for (GetElementPtrInst::op_iterator I = next(U->op_begin()), - E = U->op_end(); + gep_type_iterator GTI = gep_type_begin(GEP); + for (GetElementPtrInst::op_iterator I = next(GEP->op_begin()), + E = GEP->op_end(); I != E; ++I) { Value *Index = *I; // Compute the (potentially symbolic) offset in bytes for this index. From isanbard at gmail.com Fri May 8 15:38:03 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 08 May 2009 20:38:03 -0000 Subject: [llvm-commits] [llvm] r71256 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Message-ID: <200905082038.n48Kc3qd025851@zion.cs.uiuc.edu> Author: void Date: Fri May 8 15:38:02 2009 New Revision: 71256 URL: http://llvm.org/viewvc/llvm-project?rev=71256&view=rev Log: Minor clean ups. No functionality change. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=71256&r1=71255&r2=71256&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Fri May 8 15:38:02 2009 @@ -224,7 +224,7 @@ public: explicit DIE(unsigned Tag) - : Abbrev(Tag, DW_CHILDREN_no), Offset(0), Size(0), Children(), Values() {} + : Abbrev(Tag, DW_CHILDREN_no), Offset(0), Size(0) {} virtual ~DIE(); // Accessors. @@ -594,6 +594,7 @@ public: explicit DIEntry(DIE *E) : DIEValue(isEntry), Entry(E) {} + DIE *getEntry() const { return Entry; } void setEntry(DIE *E) { Entry = E; } // Implement isa/cast/dyncast. @@ -1116,7 +1117,7 @@ SmallVector Variables;// Variables declared in scope. public: DbgScope(DbgScope *P, DIDescriptor D) - : Parent(P), Desc(D), StartLabelID(0), EndLabelID(0), Scopes(), Variables() + : Parent(P), Desc(D), StartLabelID(0), EndLabelID(0) {} virtual ~DbgScope() { for (unsigned i = 0, N = Scopes.size(); i < N; ++i) delete Scopes[i]; @@ -2211,7 +2212,6 @@ // with their unmangled counterparts. See PR2885. Don't do this assert. assert(0 && "Couldn't find DIE for machine function!"); #endif - return; } /// EmitInitial - Emit initial Dwarf declarations. This is necessary for cc @@ -2302,9 +2302,8 @@ if (Abbrev->getChildrenFlag() == DW_CHILDREN_yes) { const std::vector &Children = Die->getChildren(); - for (unsigned j = 0, M = Children.size(); j < M; ++j) { + for (unsigned j = 0, M = Children.size(); j < M; ++j) EmitDIE(Children[j]); - } Asm->EmitInt8(0); Asm->EOL("End Of Children Mark"); } From gohman at apple.com Fri May 8 15:38:54 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 08 May 2009 20:38:54 -0000 Subject: [llvm-commits] [llvm] r71258 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp Message-ID: <200905082038.n48Kct4V025909@zion.cs.uiuc.edu> Author: djg Date: Fri May 8 15:38:54 2009 New Revision: 71258 URL: http://llvm.org/viewvc/llvm-project?rev=71258&view=rev Log: Make the SCEV* form of getSCEVAtScope public, to allow ScalarEvolution clients to use it. Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=71258&r1=71257&r2=71258&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Fri May 8 15:38:54 2009 @@ -345,11 +345,6 @@ Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& BEs, const Loop *L); - /// getSCEVAtScope - Compute the value of the specified expression within - /// the indicated loop (which may be null to indicate in no loop). If the - /// expression cannot be evaluated, return UnknownValue itself. - SCEVHandle getSCEVAtScope(const SCEV *S, const Loop *L); - /// forgetLoopPHIs - Delete the memoized SCEVs associated with the /// PHI nodes in the given loop. This is used when the trip count of /// the loop may have changed. @@ -468,6 +463,10 @@ /// /// If this value is not computable at this scope, a SCEVCouldNotCompute /// object is returned. + SCEVHandle getSCEVAtScope(const SCEV *S, const Loop *L); + + /// getSCEVAtScope - This is a convenience function which does + /// getSCEVAtScope(getSCEV(V), L). SCEVHandle getSCEVAtScope(Value *V, const Loop *L); /// isLoopGuardedByCond - Test whether entry to the loop is protected by Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71258&r1=71257&r2=71258&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May 8 15:38:54 2009 @@ -2721,9 +2721,16 @@ return UnknownValue; } -/// getSCEVAtScope - Compute the value of the specified expression within the -/// indicated loop (which may be null to indicate in no loop). If the -/// expression cannot be evaluated, return UnknownValue. +/// getSCEVAtScope - Return a SCEV expression handle for the specified value +/// at the specified scope in the program. The L value specifies a loop +/// nest to evaluate the expression at, where null is the top-level or a +/// specified loop is immediately inside of the loop. +/// +/// This method can be used to compute the exit value for a variable defined +/// in a loop by querying what the value will hold in the parent loop. +/// +/// If this value is not computable at this scope, a SCEVCouldNotCompute +/// object is returned. SCEVHandle ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) { // FIXME: this should be turned into a virtual method on SCEV! @@ -2897,16 +2904,8 @@ assert(0 && "Unknown SCEV type!"); } -/// getSCEVAtScope - Return a SCEV expression handle for the specified value -/// at the specified scope in the program. The L value specifies a loop -/// nest to evaluate the expression at, where null is the top-level or a -/// specified loop is immediately inside of the loop. -/// -/// This method can be used to compute the exit value for a variable defined -/// in a loop by querying what the value will hold in the parent loop. -/// -/// If this value is not computable at this scope, a SCEVCouldNotCompute -/// object is returned. +/// getSCEVAtScope - This is a convenience function which does +/// getSCEVAtScope(getSCEV(V), L). SCEVHandle ScalarEvolution::getSCEVAtScope(Value *V, const Loop *L) { return getSCEVAtScope(getSCEV(V), L); } From gohman at apple.com Fri May 8 15:47:34 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 08 May 2009 20:47:34 -0000 Subject: [llvm-commits] [llvm] r71259 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp Message-ID: <200905082047.n48KlZjP026299@zion.cs.uiuc.edu> Author: djg Date: Fri May 8 15:47:27 2009 New Revision: 71259 URL: http://llvm.org/viewvc/llvm-project?rev=71259&view=rev Log: Add memoization for getSCEVAtScope results for instructions which are not analyzed with SCEV techniques, which can require brute-forcing through a large number of instructions. This fixes a massive compile-time issue on 400.perlbench (in particular, the loop in MD5Transform). Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=71259&r1=71258&r2=71259&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Fri May 8 15:47:27 2009 @@ -271,6 +271,11 @@ /// exit value. std::map ConstantEvolutionLoopExitValue; + /// ValuesAtScopes - This map contains entries for all the instructions + /// that we attempt to compute getSCEVAtScope information for without + /// using SCEV techniques, which can be expensive. + std::map > ValuesAtScopes; + /// createSCEV - We know that there is no SCEV for the specified value. /// Analyze the expression. SCEVHandle createSCEV(Value *V); Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71259&r1=71258&r2=71259&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May 8 15:47:27 2009 @@ -2766,6 +2766,13 @@ // the arguments into constants, and if so, try to constant propagate the // result. This is particularly useful for computing loop exit values. if (CanConstantFold(I)) { + // Check to see if we've folded this instruction at this loop before. + std::map &Values = ValuesAtScopes[I]; + std::pair::iterator, bool> Pair = + Values.insert(std::make_pair(L, static_cast(0))); + if (!Pair.second) + return Pair.first->second ? &*getUnknown(Pair.first->second) : V; + std::vector Operands; Operands.reserve(I->getNumOperands()); for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { @@ -2812,6 +2819,7 @@ else C = ConstantFoldInstOperands(I->getOpcode(), I->getType(), &Operands[0], Operands.size()); + Pair.first->second = C; return getUnknown(C); } } @@ -3473,6 +3481,8 @@ assert(SE && "SCEVCallbackVH called with a non-null ScalarEvolution!"); if (PHINode *PN = dyn_cast(getValPtr())) SE->ConstantEvolutionLoopExitValue.erase(PN); + if (Instruction *I = dyn_cast(getValPtr())) + SE->ValuesAtScopes.erase(I); SE->Scalars.erase(getValPtr()); // this now dangles! } @@ -3499,6 +3509,8 @@ } if (PHINode *PN = dyn_cast(U)) SE->ConstantEvolutionLoopExitValue.erase(PN); + if (Instruction *I = dyn_cast(U)) + SE->ValuesAtScopes.erase(I); if (SE->Scalars.erase(U)) for (Value::use_iterator UI = U->use_begin(), UE = U->use_end(); UI != UE; ++UI) @@ -3507,6 +3519,8 @@ if (DeleteOld) { if (PHINode *PN = dyn_cast(Old)) SE->ConstantEvolutionLoopExitValue.erase(PN); + if (Instruction *I = dyn_cast(Old)) + SE->ValuesAtScopes.erase(I); SE->Scalars.erase(Old); // this now dangles! } @@ -3535,6 +3549,7 @@ Scalars.clear(); BackedgeTakenCounts.clear(); ConstantEvolutionLoopExitValue.clear(); + ValuesAtScopes.clear(); } void ScalarEvolution::getAnalysisUsage(AnalysisUsage &AU) const { From isanbard at gmail.com Fri May 8 15:49:39 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 08 May 2009 20:49:39 -0000 Subject: [llvm-commits] [llvm] r71260 - /llvm/trunk/docs/LangRef.html Message-ID: <200905082049.n48Kne9X026498@zion.cs.uiuc.edu> Author: void Date: Fri May 8 15:49:29 2009 New Revision: 71260 URL: http://llvm.org/viewvc/llvm-project?rev=71260&view=rev Log: Fix typo. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=71260&r1=71259&r2=71260&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Fri May 8 15:49:29 2009 @@ -3492,7 +3492,7 @@

    Semantics:
    -

    Memory is allocated; a pointer is returned. The operation is undefiend if +

    Memory is allocated; a pointer is returned. The operation is undefined if there is insufficient stack space for the allocation. 'alloca'd memory is automatically released when the function returns. The 'alloca' instruction is commonly used to represent automatic variables that must From gohman at apple.com Fri May 8 15:58:39 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 08 May 2009 20:58:39 -0000 Subject: [llvm-commits] [llvm] r71262 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp Message-ID: <200905082058.n48KwdGu026892@zion.cs.uiuc.edu> Author: djg Date: Fri May 8 15:58:38 2009 New Revision: 71262 URL: http://llvm.org/viewvc/llvm-project?rev=71262&view=rev Log: Fix another bug in r71252. This code supports GetElementPtr constant exprs as well as instructions. Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=71262&r1=71261&r2=71262&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Fri May 8 15:58:38 2009 @@ -286,7 +286,7 @@ /// createNodeForGEP - Provide the special handling we need to analyze GEP /// SCEVs. - SCEVHandle createNodeForGEP(GetElementPtrInst *GEP); + SCEVHandle createNodeForGEP(User *GEP); /// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value /// for the specified instruction and replaces any references to the Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71262&r1=71261&r2=71262&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May 8 15:58:38 2009 @@ -1866,7 +1866,7 @@ /// createNodeForGEP - Expand GEP instructions into add and multiply /// operations. This allows them to be analyzed by regular SCEV code. /// -SCEVHandle ScalarEvolution::createNodeForGEP(GetElementPtrInst *GEP) { +SCEVHandle ScalarEvolution::createNodeForGEP(User *GEP) { const Type *IntPtrTy = TD->getIntPtrType(); Value *Base = GEP->getOperand(0); @@ -2113,7 +2113,7 @@ case Instruction::GetElementPtr: if (!TD) break; // Without TD we can't analyze pointers. - return createNodeForGEP(cast(U)); + return createNodeForGEP(U); case Instruction::PHI: return createNodeForPHI(cast(U)); From gohman at apple.com Fri May 8 15:59:43 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 8 May 2009 13:59:43 -0700 Subject: [llvm-commits] [llvm] r71252 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp In-Reply-To: <16e5fdf90905081335n507b88e9kcd3c7d9b42dbda3d@mail.gmail.com> References: <200905082026.n48KQum8025389@zion.cs.uiuc.edu> <16e5fdf90905081335n507b88e9kcd3c7d9b42dbda3d@mail.gmail.com> Message-ID: Hi, these are fixed now. Sorry for the breakage. Dan On May 8, 2009, at 1:35 PM, Bill Wendling wrote: > Hi Dan, > > I'm getting these errors with this patch: > > /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/lib/Analysis/ > ScalarEvolution.cpp: > In member function 'llvm::SCEVHandle > llvm::ScalarEvolution::createNodeForGEP(llvm::GetElementPtrInst*)': > /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/lib/Analysis/ > ScalarEvolution.cpp:1872: > error: 'U' was not declared in this scope > /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/lib/Analysis/ > ScalarEvolution.cpp:1874: > error: no matching function for call to 'gep_type_begin()' > /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/include/llvm/ > Support/GetElementPtrTypeIterator.h:84: > note: candidates are: llvm::gep_type_iterator > llvm::gep_type_begin(const llvm::User*) > /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/include/llvm/ > Support/GetElementPtrTypeIterator.h:91: > note: llvm::gep_type_iterator > llvm::gep_type_begin(const llvm::User&) > > > On Fri, May 8, 2009 at 1:26 PM, Dan Gohman wrote: >> Author: djg >> Date: Fri May 8 15:26:55 2009 >> New Revision: 71252 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=71252&view=rev >> Log: >> Factor out the code for creating SCEVs for GEPs into a >> separate function. >> >> Modified: >> llvm/trunk/include/llvm/Analysis/ScalarEvolution.h >> llvm/trunk/lib/Analysis/ScalarEvolution.cpp >> >> Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=71252&r1=71251&r2=71252&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) >> +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Fri May 8 >> 15:26:55 2009 >> @@ -279,6 +279,10 @@ >> /// SCEVs. >> SCEVHandle createNodeForPHI(PHINode *PN); >> >> + /// createNodeForGEP - Provide the special handling we need to >> analyze GEP >> + /// SCEVs. >> + SCEVHandle createNodeForGEP(GetElementPtrInst *GEP); >> + >> /// ReplaceSymbolicValueWithConcrete - This looks up the >> computed SCEV value >> /// for the specified instruction and replaces any references >> to the >> /// symbolic value SymName with the specified value. This is >> used during >> >> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71252&r1=71251&r2=71252&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) >> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May 8 15:26:55 >> 2009 >> @@ -1863,6 +1863,44 @@ >> return getUnknown(PN); >> } >> >> +/// createNodeForGEP - Expand GEP instructions into add and multiply >> +/// operations. This allows them to be analyzed by regular SCEV >> code. >> +/// >> +SCEVHandle ScalarEvolution::createNodeForGEP(GetElementPtrInst >> *GEP) { >> + >> + const Type *IntPtrTy = TD->getIntPtrType(); >> + Value *Base = U->getOperand(0); >> + SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy); >> + gep_type_iterator GTI = gep_type_begin(U); >> + for (GetElementPtrInst::op_iterator I = next(U->op_begin()), >> + E = U->op_end(); >> + I != E; ++I) { >> + Value *Index = *I; >> + // Compute the (potentially symbolic) offset in bytes for this >> index. >> + if (const StructType *STy = dyn_cast(*GTI++)) { >> + // For a struct, add the member offset. >> + const StructLayout &SL = *TD->getStructLayout(STy); >> + unsigned FieldNo = cast(Index)->getZExtValue(); >> + uint64_t Offset = SL.getElementOffset(FieldNo); >> + TotalOffset = getAddExpr(TotalOffset, >> + getIntegerSCEV(Offset, IntPtrTy)); >> + } else { >> + // For an array, add the element offset, explicitly scaled. >> + SCEVHandle LocalOffset = getSCEV(Index); >> + if (!isa(LocalOffset->getType())) >> + // Getelementptr indicies are signed. >> + LocalOffset = getTruncateOrSignExtend(LocalOffset, >> + IntPtrTy); >> + LocalOffset = >> + getMulExpr(LocalOffset, >> + getIntegerSCEV(TD->getTypePaddedSize(*GTI), >> + IntPtrTy)); >> + TotalOffset = getAddExpr(TotalOffset, LocalOffset); >> + } >> + } >> + return getAddExpr(getSCEV(Base), TotalOffset); >> +} >> + >> /// GetMinTrailingZeros - Determine the minimum number of zero >> bits that S is >> /// guaranteed to end in (at every loop iteration). It is, at the >> same time, >> /// the minimum number of times S is divisible by 2. For example, >> given {4,+,8} >> @@ -2073,40 +2111,9 @@ >> return getTruncateOrZeroExtend(getSCEV(U->getOperand(0)), >> U->getType()); >> >> - case Instruction::GetElementPtr: { >> + case Instruction::GetElementPtr: >> if (!TD) break; // Without TD we can't analyze pointers. >> - const Type *IntPtrTy = TD->getIntPtrType(); >> - Value *Base = U->getOperand(0); >> - SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy); >> - gep_type_iterator GTI = gep_type_begin(U); >> - for (GetElementPtrInst::op_iterator I = next(U->op_begin()), >> - E = U->op_end(); >> - I != E; ++I) { >> - Value *Index = *I; >> - // Compute the (potentially symbolic) offset in bytes for >> this index. >> - if (const StructType *STy = dyn_cast(*GTI++)) { >> - // For a struct, add the member offset. >> - const StructLayout &SL = *TD->getStructLayout(STy); >> - unsigned FieldNo = cast(Index)->getZExtValue(); >> - uint64_t Offset = SL.getElementOffset(FieldNo); >> - TotalOffset = getAddExpr(TotalOffset, >> - getIntegerSCEV(Offset, >> IntPtrTy)); >> - } else { >> - // For an array, add the element offset, explicitly scaled. >> - SCEVHandle LocalOffset = getSCEV(Index); >> - if (!isa(LocalOffset->getType())) >> - // Getelementptr indicies are signed. >> - LocalOffset = getTruncateOrSignExtend(LocalOffset, >> - IntPtrTy); >> - LocalOffset = >> - getMulExpr(LocalOffset, >> - getIntegerSCEV(TD->getTypePaddedSize(*GTI), >> - IntPtrTy)); >> - TotalOffset = getAddExpr(TotalOffset, LocalOffset); >> - } >> - } >> - return getAddExpr(getSCEV(Base), TotalOffset); >> - } >> + return createNodeForGEP(cast(U)); >> >> case Instruction::PHI: >> return createNodeForPHI(cast(U)); >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From jay.foad at gmail.com Fri May 8 04:57:09 2009 From: jay.foad at gmail.com (Jay Foad) Date: Fri, 8 May 2009 10:57:09 +0100 Subject: [llvm-commits] [PATCH] TargetData::getIntPtrType() to return IntegerType Message-ID: Nick Lewycky wrote: > Your patch looks good to me. You could declare "class IntegerType;" and > require that users of getIntPtrType who want to write code like the > above need to #include DerivedTypes.h themselves, but I'm not sure > that's really an improvement. Here's the patch to do it that way. It passes regression tests and cfe and llvm-gcc still build. Can I commit either of them? Thanks, Jay. -------------- next part -------------- A non-text attachment was scrubbed... Name: patch.intptr2 Type: application/octet-stream Size: 1704 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090508/b83c589c/attachment.obj From isanbard at gmail.com Fri May 8 16:01:00 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 8 May 2009 14:01:00 -0700 Subject: [llvm-commits] [llvm] r71252 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp In-Reply-To: References: <200905082026.n48KQum8025389@zion.cs.uiuc.edu> <16e5fdf90905081335n507b88e9kcd3c7d9b42dbda3d@mail.gmail.com> Message-ID: <16e5fdf90905081401h2f329112lee7a94a2524467eb@mail.gmail.com> Thanks! :-) -bw On Fri, May 8, 2009 at 1:59 PM, Dan Gohman wrote: > Hi, these are fixed now. Sorry for the breakage. > > Dan > > On May 8, 2009, at 1:35 PM, Bill Wendling wrote: > >> Hi Dan, >> >> I'm getting these errors with this patch: >> >> /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/lib/Analysis/ >> ScalarEvolution.cpp: >> In member function 'llvm::SCEVHandle >> llvm::ScalarEvolution::createNodeForGEP(llvm::GetElementPtrInst*)': >> /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/lib/Analysis/ >> ScalarEvolution.cpp:1872: >> error: 'U' was not declared in this scope >> /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/lib/Analysis/ >> ScalarEvolution.cpp:1874: >> error: no matching function for call to 'gep_type_begin()' >> /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/include/llvm/ >> Support/GetElementPtrTypeIterator.h:84: >> note: candidates are: llvm::gep_type_iterator >> llvm::gep_type_begin(const llvm::User*) >> /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/include/llvm/ >> Support/GetElementPtrTypeIterator.h:91: >> note: ? ? ? ? ? ? ? ? llvm::gep_type_iterator >> llvm::gep_type_begin(const llvm::User&) >> >> >> On Fri, May 8, 2009 at 1:26 PM, Dan Gohman wrote: >>> Author: djg >>> Date: Fri May ?8 15:26:55 2009 >>> New Revision: 71252 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=71252&view=rev >>> Log: >>> Factor out the code for creating SCEVs for GEPs into a >>> separate function. >>> >>> Modified: >>> ? ?llvm/trunk/include/llvm/Analysis/ScalarEvolution.h >>> ? ?llvm/trunk/lib/Analysis/ScalarEvolution.cpp >>> >>> Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=71252&r1=71251&r2=71252&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ===================================================================== >>> --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) >>> +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Fri May ?8 >>> 15:26:55 2009 >>> @@ -279,6 +279,10 @@ >>> ? ? /// SCEVs. >>> ? ? SCEVHandle createNodeForPHI(PHINode *PN); >>> >>> + ? ?/// createNodeForGEP - Provide the special handling we need to >>> analyze GEP >>> + ? ?/// SCEVs. >>> + ? ?SCEVHandle createNodeForGEP(GetElementPtrInst *GEP); >>> + >>> ? ? /// ReplaceSymbolicValueWithConcrete - This looks up the >>> computed SCEV value >>> ? ? /// for the specified instruction and replaces any references >>> to the >>> ? ? /// symbolic value SymName with the specified value. ?This is >>> used during >>> >>> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71252&r1=71251&r2=71252&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ===================================================================== >>> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) >>> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May ?8 15:26:55 >>> 2009 >>> @@ -1863,6 +1863,44 @@ >>> ? return getUnknown(PN); >>> ?} >>> >>> +/// createNodeForGEP - Expand GEP instructions into add and multiply >>> +/// operations. This allows them to be analyzed by regular SCEV >>> code. >>> +/// >>> +SCEVHandle ScalarEvolution::createNodeForGEP(GetElementPtrInst >>> *GEP) { >>> + >>> + ?const Type *IntPtrTy = TD->getIntPtrType(); >>> + ?Value *Base = U->getOperand(0); >>> + ?SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy); >>> + ?gep_type_iterator GTI = gep_type_begin(U); >>> + ?for (GetElementPtrInst::op_iterator I = next(U->op_begin()), >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?E = U->op_end(); >>> + ? ? ? I != E; ++I) { >>> + ? ?Value *Index = *I; >>> + ? ?// Compute the (potentially symbolic) offset in bytes for this >>> index. >>> + ? ?if (const StructType *STy = dyn_cast(*GTI++)) { >>> + ? ? ?// For a struct, add the member offset. >>> + ? ? ?const StructLayout &SL = *TD->getStructLayout(STy); >>> + ? ? ?unsigned FieldNo = cast(Index)->getZExtValue(); >>> + ? ? ?uint64_t Offset = SL.getElementOffset(FieldNo); >>> + ? ? ?TotalOffset = getAddExpr(TotalOffset, >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?getIntegerSCEV(Offset, IntPtrTy)); >>> + ? ?} else { >>> + ? ? ?// For an array, add the element offset, explicitly scaled. >>> + ? ? ?SCEVHandle LocalOffset = getSCEV(Index); >>> + ? ? ?if (!isa(LocalOffset->getType())) >>> + ? ? ? ?// Getelementptr indicies are signed. >>> + ? ? ? ?LocalOffset = getTruncateOrSignExtend(LocalOffset, >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IntPtrTy); >>> + ? ? ?LocalOffset = >>> + ? ? ? ?getMulExpr(LocalOffset, >>> + ? ? ? ? ? ? ? ? ? getIntegerSCEV(TD->getTypePaddedSize(*GTI), >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IntPtrTy)); >>> + ? ? ?TotalOffset = getAddExpr(TotalOffset, LocalOffset); >>> + ? ?} >>> + ?} >>> + ?return getAddExpr(getSCEV(Base), TotalOffset); >>> +} >>> + >>> ?/// GetMinTrailingZeros - Determine the minimum number of zero >>> bits that S is >>> ?/// guaranteed to end in (at every loop iteration). ?It is, at the >>> same time, >>> ?/// the minimum number of times S is divisible by 2. ?For example, >>> given {4,+,8} >>> @@ -2073,40 +2111,9 @@ >>> ? ? return getTruncateOrZeroExtend(getSCEV(U->getOperand(0)), >>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?U->getType()); >>> >>> - ?case Instruction::GetElementPtr: { >>> + ?case Instruction::GetElementPtr: >>> ? ? if (!TD) break; // Without TD we can't analyze pointers. >>> - ? ?const Type *IntPtrTy = TD->getIntPtrType(); >>> - ? ?Value *Base = U->getOperand(0); >>> - ? ?SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy); >>> - ? ?gep_type_iterator GTI = gep_type_begin(U); >>> - ? ?for (GetElementPtrInst::op_iterator I = next(U->op_begin()), >>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?E = U->op_end(); >>> - ? ? ? ? I != E; ++I) { >>> - ? ? ?Value *Index = *I; >>> - ? ? ?// Compute the (potentially symbolic) offset in bytes for >>> this index. >>> - ? ? ?if (const StructType *STy = dyn_cast(*GTI++)) { >>> - ? ? ? ?// For a struct, add the member offset. >>> - ? ? ? ?const StructLayout &SL = *TD->getStructLayout(STy); >>> - ? ? ? ?unsigned FieldNo = cast(Index)->getZExtValue(); >>> - ? ? ? ?uint64_t Offset = SL.getElementOffset(FieldNo); >>> - ? ? ? ?TotalOffset = getAddExpr(TotalOffset, >>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?getIntegerSCEV(Offset, >>> IntPtrTy)); >>> - ? ? ?} else { >>> - ? ? ? ?// For an array, add the element offset, explicitly scaled. >>> - ? ? ? ?SCEVHandle LocalOffset = getSCEV(Index); >>> - ? ? ? ?if (!isa(LocalOffset->getType())) >>> - ? ? ? ? ?// Getelementptr indicies are signed. >>> - ? ? ? ? ?LocalOffset = getTruncateOrSignExtend(LocalOffset, >>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IntPtrTy); >>> - ? ? ? ?LocalOffset = >>> - ? ? ? ? ?getMulExpr(LocalOffset, >>> - ? ? ? ? ? ? ? ? ? ? getIntegerSCEV(TD->getTypePaddedSize(*GTI), >>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IntPtrTy)); >>> - ? ? ? ?TotalOffset = getAddExpr(TotalOffset, LocalOffset); >>> - ? ? ?} >>> - ? ?} >>> - ? ?return getAddExpr(getSCEV(Base), TotalOffset); >>> - ?} >>> + ? ?return createNodeForGEP(cast(U)); >>> >>> ? case Instruction::PHI: >>> ? ? return createNodeForPHI(cast(U)); >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From isanbard at gmail.com Fri May 8 16:03:15 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 08 May 2009 21:03:15 -0000 Subject: [llvm-commits] [llvm] r71263 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Message-ID: <200905082103.n48L3GGD027063@zion.cs.uiuc.edu> Author: void Date: Fri May 8 16:03:15 2009 New Revision: 71263 URL: http://llvm.org/viewvc/llvm-project?rev=71263&view=rev Log: Compute the offsets of the compile units. We need this so that when we emit a concrete instance of an inlined function, we can get the actual address of the abstract instance inside of the compile unit. This isn't currently used, but will be by a future check-in. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=71263&r1=71262&r2=71263&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Fri May 8 16:03:15 2009 @@ -1289,6 +1289,11 @@ /// variables. DenseMap InlinedVariableScopes; + /// CompileUnitOffsets - A vector of the offsets of the compile units. This is + /// used when calculating the "origin" of a concrete instance of an inlined + /// function. + DenseMap CompileUnitOffsets; + /// DebugTimer - Timer for the Dwarf debug writer. Timer *DebugTimer; @@ -2360,24 +2365,28 @@ /// SizeAndOffsets - Compute the size and offset of all the DIEs. /// void SizeAndOffsets() { + // Compute size of compile unit header. + static unsigned Offset = + sizeof(int32_t) + // Length of Compilation Unit Info + sizeof(int16_t) + // DWARF version number + sizeof(int32_t) + // Offset Into Abbrev. Section + sizeof(int8_t); // Pointer Size (in bytes) + // Process base compile unit. if (MainCU) { - // Compute size of compile unit header - unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info - sizeof(int16_t) + // DWARF version number - sizeof(int32_t) + // Offset Into Abbrev. Section - sizeof(int8_t); // Pointer Size (in bytes) SizeAndOffsetDie(MainCU->getDie(), Offset, true); + CompileUnitOffsets[MainCU] = 0; return; } + + // Process all compile units. + unsigned PrevOffset = 0; + for (unsigned i = 0, e = CompileUnits.size(); i != e; ++i) { CompileUnit *Unit = CompileUnits[i]; - // Compute size of compile unit header - unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info - sizeof(int16_t) + // DWARF version number - sizeof(int32_t) + // Offset Into Abbrev. Section - sizeof(int8_t); // Pointer Size (in bytes) - SizeAndOffsetDie(Unit->getDie(), Offset, true); + CompileUnitOffsets[Unit] = PrevOffset; + PrevOffset += SizeAndOffsetDie(Unit->getDie(), Offset, true) + + sizeof(int32_t); // FIXME - extra pad for gdb bug. } } From gohman at apple.com Fri May 8 16:03:19 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 08 May 2009 21:03:19 -0000 Subject: [llvm-commits] [llvm] r71264 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/trip-count4.ll Message-ID: <200905082103.n48L3JdM027077@zion.cs.uiuc.edu> Author: djg Date: Fri May 8 16:03:19 2009 New Revision: 71264 URL: http://llvm.org/viewvc/llvm-project?rev=71264&view=rev Log: Fold trunc casts into add-recurrence expressions, allowing the add-recurrence to be exposed. Add a new SCEV folding rule to help simplify expressions in the presence of these extra truncs. Added: llvm/trunk/test/Analysis/ScalarEvolution/trip-count4.ll Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71264&r1=71263&r2=71264&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May 8 16:03:19 2009 @@ -748,13 +748,8 @@ if (const SCEVAddRecExpr *AddRec = dyn_cast(Op)) { std::vector Operands; for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) - // FIXME: This should allow truncation of other expression types! - if (isa(AddRec->getOperand(i))) - Operands.push_back(getTruncateExpr(AddRec->getOperand(i), Ty)); - else - break; - if (Operands.size() == AddRec->getNumOperands()) - return getAddRecExpr(Operands, AddRec->getLoop()); + Operands.push_back(getTruncateExpr(AddRec->getOperand(i), Ty)); + return getAddRecExpr(Operands, AddRec->getLoop()); } SCEVTruncateExpr *&Result = (*SCEVTruncates)[std::make_pair(Op, Ty)]; @@ -966,7 +961,66 @@ return getAddExpr(Ops); } - // Now we know the first non-constant operand. Skip past any cast SCEVs. + // Check for truncates. If all the operands are truncated from the same + // type, see if factoring out the truncate would permit the result to be + // folded. eg., trunc(x) + m*trunc(n) --> trunc(x + trunc(m)*n) + // if the contents of the resulting outer trunc fold to something simple. + for (; Idx < Ops.size() && isa(Ops[Idx]); ++Idx) { + const SCEVTruncateExpr *Trunc = cast(Ops[Idx]); + const Type *DstType = Trunc->getType(); + const Type *SrcType = Trunc->getOperand()->getType(); + std::vector LargeOps; + bool Ok = true; + // Check all the operands to see if they can be represented in the + // source type of the truncate. + for (unsigned i = 0, e = Ops.size(); i != e; ++i) { + if (const SCEVTruncateExpr *T = dyn_cast(Ops[i])) { + if (T->getOperand()->getType() != SrcType) { + Ok = false; + break; + } + LargeOps.push_back(T->getOperand()); + } else if (const SCEVConstant *C = dyn_cast(Ops[i])) { + // This could be either sign or zero extension, but sign extension + // is much more likely to be foldable here. + LargeOps.push_back(getSignExtendExpr(C, SrcType)); + } else if (const SCEVMulExpr *M = dyn_cast(Ops[i])) { + std::vector LargeMulOps; + for (unsigned j = 0, f = M->getNumOperands(); j != f && Ok; ++j) { + if (const SCEVTruncateExpr *T = + dyn_cast(M->getOperand(j))) { + if (T->getOperand()->getType() != SrcType) { + Ok = false; + break; + } + LargeMulOps.push_back(T->getOperand()); + } else if (const SCEVConstant *C = + dyn_cast(M->getOperand(j))) { + // This could be either sign or zero extension, but sign extension + // is much more likely to be foldable here. + LargeMulOps.push_back(getSignExtendExpr(C, SrcType)); + } else { + Ok = false; + break; + } + } + if (Ok) + LargeOps.push_back(getMulExpr(LargeMulOps)); + } else { + Ok = false; + break; + } + } + if (Ok) { + // Evaluate the expression in the larger type. + SCEVHandle Fold = getAddExpr(LargeOps); + // If it folds to something simple, use it. Otherwise, don't. + if (isa(Fold) || isa(Fold)) + return getTruncateExpr(Fold, DstType); + } + } + + // Skip past any other cast SCEVs. while (Idx < Ops.size() && Ops[Idx]->getSCEVType() < scAddExpr) ++Idx; Added: llvm/trunk/test/Analysis/ScalarEvolution/trip-count4.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/trip-count4.ll?rev=71264&view=auto ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/trip-count4.ll (added) +++ llvm/trunk/test/Analysis/ScalarEvolution/trip-count4.ll Fri May 8 16:03:19 2009 @@ -0,0 +1,24 @@ +; RUN: llvm-as < %s | opt -analyze -scalar-evolution -disable-output \ +; RUN: | grep {sext.*trunc.*Exits: 11} + +; ScalarEvolution should be able to compute a loop exit value for %indvar.i8. + +define void @another_count_down_signed(double* %d, i64 %n) nounwind { +entry: + br label %loop + +loop: ; preds = %loop, %entry + %indvar = phi i64 [ %n, %entry ], [ %indvar.next, %loop ] ; [#uses=4] + %s0 = shl i64 %indvar, 8 ; [#uses=1] + %indvar.i8 = ashr i64 %s0, 8 ; [#uses=1] + %t0 = getelementptr double* %d, i64 %indvar.i8 ; [#uses=2] + %t1 = load double* %t0 ; [#uses=1] + %t2 = mul double %t1, 1.000000e-01 ; [#uses=1] + store double %t2, double* %t0 + %indvar.next = sub i64 %indvar, 1 ; [#uses=2] + %exitcond = icmp eq i64 %indvar.next, 10 ; [#uses=1] + br i1 %exitcond, label %return, label %loop + +return: ; preds = %loop + ret void +} From isanbard at gmail.com Fri May 8 16:14:49 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 08 May 2009 21:14:49 -0000 Subject: [llvm-commits] [llvm] r71268 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200905082114.n48LEngp027587@zion.cs.uiuc.edu> Author: void Date: Fri May 8 16:14:49 2009 New Revision: 71268 URL: http://llvm.org/viewvc/llvm-project?rev=71268&view=rev Log: Mirror how Fast ISel determines if a region.end intrinsic is the end of an inlined function or the end of a function. Before, this was never executing the "inlined" version of the Record method. This will become important once the inlined Dwarf writer patch lands. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=71268&r1=71267&r2=71268&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Fri May 8 16:14:49 2009 @@ -3928,29 +3928,26 @@ DW && DW->ShouldEmitDwarfDebug()) { MachineFunction &MF = DAG.getMachineFunction(); DISubprogram Subprogram(cast(REI.getContext())); - std::string SPName; - Subprogram.getLinkageName(SPName); - if (!SPName.empty() - && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) { - // This is end of inlined function. Debugging information for - // inlined function is not handled yet (only supported by FastISel). + + if (Subprogram.isNull() || Subprogram.describes(MF.getFunction())) { + unsigned LabelID = + DW->RecordRegionEnd(cast(REI.getContext())); + DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), + getRoot(), LabelID)); + } else { + // This is end of inlined function. Debugging information for inlined + // function is not handled yet (only supported by FastISel). if (OptLevel == CodeGenOpt::None) { unsigned ID = DW->RecordInlinedFnEnd(Subprogram); if (ID != 0) // Returned ID is 0 if this is unbalanced "end of inlined - // scope". This could happen if optimizer eats dbg intrinsics - // or "beginning of inlined scope" is not recoginized due to - // missing location info. In such cases, do ignore this region.end. + // scope". This could happen if optimizer eats dbg intrinsics or + // "beginning of inlined scope" is not recoginized due to missing + // location info. In such cases, do ignore this region.end. DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), getRoot(), ID)); } - return 0; } - - unsigned LabelID = - DW->RecordRegionEnd(cast(REI.getContext())); - DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), - getRoot(), LabelID)); } return 0; From bob.wilson at apple.com Fri May 8 16:23:47 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 8 May 2009 14:23:47 -0700 Subject: [llvm-commits] [llvm] r71196 - in /llvm/trunk: lib/CodeGen/RegAllocLocal.cpp test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll In-Reply-To: References: <200905072347.n47Nl4Pu006476@zion.cs.uiuc.edu> <1CE45B3C-A585-4DE0-AD45-E7CD30307725@apple.com> Message-ID: <04C4C9E0-D26B-42A0-9C7A-C1A9EF333722@apple.com> I agree that would be better. After looking at for a while today, though, I think it may be beyond my current understanding of the code to implement that. Maybe I can come back to it later. On May 7, 2009, at 7:09 PM, Evan Cheng wrote: > Well, I can think of an alternative solution. Why not inhibit > reloading of reg1028? It's easy to tell since the only use is a copy > (use is killed right away) and its def is dead. > > Evan > > On May 7, 2009, at 7:03 PM, Evan Cheng wrote: > >> This is fine for local regalloc since performance is not critical. >> Thanks. >> >> Evan >> >> On May 7, 2009, at 4:47 PM, Bob Wilson wrote: >> >>> Author: bwilson >>> Date: Thu May 7 18:47:03 2009 >>> New Revision: 71196 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=71196&view=rev >>> Log: >>> Fix pr4100. Do not remove no-op copies when they are dead. The >>> register >>> scavenger gets confused about register liveness if it doesn't see >>> them. >>> I'm not thrilled with this solution, but it only comes up when there >>> are dead >>> copies in the code, which is something that hopefully doesn't happen >>> much. >>> >>> Here is what happens in pr4100: As shown in the following excerpt >>> from the >>> debug output of llc, the source of a move gets reloaded from the >>> stack, >>> inserting a new load instruction before the move. Since that source >>> operand >>> is a kill, the physical register is free to be reused for the >>> destination >>> of the move. The move ends up being a no-op, copying R3 to R3, so >>> it is >>> deleted. But, it leaves behind the load to reload %reg1028 into R3, >>> and >>> that load is not updated to show that it's destination operand (R3) >>> is dead. >>> The scavenger gets confused by that load because it thinks that R3 >>> is live. >>> >>> Starting RegAlloc of: %reg1025 = MOVr %reg1028, 14, >>> %reg0, %reg0 >>> Regs have values: >>> Reloading %reg1028 into R3 >>> Last use of R3[%reg1028], removing it from live set >>> Assigning R3 to %reg1025 >>> Register R3 [%reg1025] is never used, removing it from live set >>> >>> Alternative solutions might be either marking the load as dead, or >>> zapping >>> the load along with the no-op copy. I couldn't see an easy way to >>> do >>> either of those, though. >>> >>> Added: >>> llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll >>> Modified: >>> llvm/trunk/lib/CodeGen/RegAllocLocal.cpp >>> >>> Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=71196&r1=71195&r2=71196&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original) >>> +++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Thu May 7 18:47:03 >>> 2009 >>> @@ -981,10 +981,12 @@ >>> } >>> } >>> >>> - // Finally, if this is a noop copy instruction, zap it. >>> + // Finally, if this is a noop copy instruction, zap it. >>> (Except that if >>> + // the copy is dead, it must be kept to avoid messing up >>> liveness info for >>> + // the register scavenger. See pr4100.) >>> unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; >>> if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && >>> - SrcReg == DstReg) >>> + SrcReg == DstReg && DeadDefs.empty()) >>> MBB.erase(MI); >>> } >>> >>> >>> Added: llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll?rev=71196&view=auto >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll (added) >>> +++ llvm/trunk/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll Thu May >>> 7 18:47:03 2009 >>> @@ -0,0 +1,12 @@ >>> +; RUN: llvm-as < %s | llc -mtriple=armv5-unknown-linux-gnueabi - >>> O0 - >>> regalloc=local >>> +; PR4100 >>> + at .str = external constant [30 x i8] ; <[30 x i8]*> [#uses=1] >>> + >>> +define i16 @fn16(i16 %arg0.0, <2 x i16> %arg1, i16 %arg2.0) >>> nounwind { >>> +entry: >>> + store <2 x i16> %arg1, <2 x i16>* null >>> + %0 = call i32 (i8*, ...)* @printf(i8* getelementptr ([30 x i8]* >>> @.str, i32 0, i32 0), i32 0) nounwind ; [#uses=0] >>> + ret i16 0 >>> +} >>> + >>> +declare i32 @printf(i8*, ...) nounwind >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From stoklund at 2pi.dk Fri May 8 16:38:32 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Fri, 8 May 2009 23:38:32 +0200 Subject: [llvm-commits] [PATCH] Machine code verifier pass Message-ID: <04F74F5E-5BCA-4F65-8ED5-CAF353E31497@2pi.dk> Hi, The attached patch creates a machine code verifier pass, enabled with - verify-machineinstrs. The verifier pass is run immediately after - print-machineinstrs would run. It verifies the following: Operand counts: All explicit operands must be present. Register classes: All physical and virtual register operands must be compatible with the register class required by the instruction descriptor. Register live intervals: Registers must be defined only once, and must be defined before use. The double-definition checking is disabled until LiveVariables has run. If I have misunderstood something about valid machine code, please let me know. -------------- next part -------------- A non-text attachment was scrubbed... Name: machine-verifier.patch Type: application/octet-stream Size: 23284 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090508/9c3eef4d/attachment.obj -------------- next part -------------- From mrs at apple.com Fri May 8 17:53:06 2009 From: mrs at apple.com (Mike Stump) Date: Fri, 08 May 2009 22:53:06 -0000 Subject: [llvm-commits] [llvm] r71275 - /llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Message-ID: <200905082253.n48Mr6Hr030607@zion.cs.uiuc.edu> Author: mrs Date: Fri May 8 17:53:06 2009 New Revision: 71275 URL: http://llvm.org/viewvc/llvm-project?rev=71275&view=rev Log: Avoid warning in release-asserts build. Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=71275&r1=71274&r2=71275&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp (original) +++ llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Fri May 8 17:53:06 2009 @@ -935,6 +935,7 @@ ++NumReMats; } else { bool Emitted = TII->copyRegToReg(*mbbi, mi, regA, regB, rc, rc); + (void)Emitted; assert(Emitted && "Unable to issue a copy instruction!\n"); } From gohman at apple.com Fri May 8 18:01:28 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 08 May 2009 23:01:28 -0000 Subject: [llvm-commits] [llvm] r71277 - in /llvm/trunk/test/TableGen: DagDefSubst.ll DagDefSubst.td DagIntSubst.ll DagIntSubst.td Message-ID: <200905082301.n48N1Sm3030905@zion.cs.uiuc.edu> Author: djg Date: Fri May 8 18:01:28 2009 New Revision: 71277 URL: http://llvm.org/viewvc/llvm-project?rev=71277&view=rev Log: Use .td for tablegen files, not .ll. Added: llvm/trunk/test/TableGen/DagDefSubst.td (props changed) - copied unchanged from r71271, llvm/trunk/test/TableGen/DagDefSubst.ll llvm/trunk/test/TableGen/DagIntSubst.td (props changed) - copied unchanged from r71271, llvm/trunk/test/TableGen/DagIntSubst.ll Removed: llvm/trunk/test/TableGen/DagDefSubst.ll llvm/trunk/test/TableGen/DagIntSubst.ll Removed: llvm/trunk/test/TableGen/DagDefSubst.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/DagDefSubst.ll?rev=71276&view=auto ============================================================================== --- llvm/trunk/test/TableGen/DagDefSubst.ll (original) +++ llvm/trunk/test/TableGen/DagDefSubst.ll (removed) @@ -1,15 +0,0 @@ -// RUN: tblgen %s | grep {dag d = (X Y)} -// RUN: tblgen %s | grep {dag e = (Y X)} -def X; - -class yclass; -def Y : yclass; - -class C { - dag d = (X N); - dag e = (N X); -} - -def VAL : C; - - Propchange: llvm/trunk/test/TableGen/DagDefSubst.td ------------------------------------------------------------------------------ cvs2svn:cvs-rev = 1.2 Propchange: llvm/trunk/test/TableGen/DagDefSubst.td ------------------------------------------------------------------------------ svn:eol-style = native Propchange: llvm/trunk/test/TableGen/DagDefSubst.td ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: llvm/trunk/test/TableGen/DagDefSubst.td ------------------------------------------------------------------------------ svn:mergeinfo = Removed: llvm/trunk/test/TableGen/DagIntSubst.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/DagIntSubst.ll?rev=71276&view=auto ============================================================================== --- llvm/trunk/test/TableGen/DagIntSubst.ll (original) +++ llvm/trunk/test/TableGen/DagIntSubst.ll (removed) @@ -1,10 +0,0 @@ -// RUN: tblgen %s | grep {dag d = (X 13)} -def X; - -class C { - dag d = (X N); -} - -def VAL : C<13>; - - Propchange: llvm/trunk/test/TableGen/DagIntSubst.td ------------------------------------------------------------------------------ cvs2svn:cvs-rev = 1.2 Propchange: llvm/trunk/test/TableGen/DagIntSubst.td ------------------------------------------------------------------------------ svn:eol-style = native Propchange: llvm/trunk/test/TableGen/DagIntSubst.td ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: llvm/trunk/test/TableGen/DagIntSubst.td ------------------------------------------------------------------------------ svn:mergeinfo = From mrs at apple.com Fri May 8 18:08:58 2009 From: mrs at apple.com (Mike Stump) Date: Fri, 08 May 2009 23:08:58 -0000 Subject: [llvm-commits] [llvm] r71281 - /llvm/trunk/Makefile.rules Message-ID: <200905082308.n48N8wlo031175@zion.cs.uiuc.edu> Author: mrs Date: Fri May 8 18:08:58 2009 New Revision: 71281 URL: http://llvm.org/viewvc/llvm-project?rev=71281&view=rev Log: In non-pic builds, we can use -mdynamic-no-pic for a little more speed. Modified: llvm/trunk/Makefile.rules Modified: llvm/trunk/Makefile.rules URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.rules?rev=71281&r1=71280&r2=71281&view=diff ============================================================================== --- llvm/trunk/Makefile.rules (original) +++ llvm/trunk/Makefile.rules Fri May 8 18:08:58 2009 @@ -338,6 +338,11 @@ C.Flags += -fPIC endif endif +else + ifeq ($(OS),Darwin) + CXX.Flags += -mdynamic-no-pic + C.Flags += -mdynamic-no-pic + endif endif CXX.Flags += $(CXXFLAGS) -Woverloaded-virtual From evan.cheng at apple.com Fri May 8 18:09:25 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 08 May 2009 23:09:25 -0000 Subject: [llvm-commits] [llvm] r71282 - /llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Message-ID: <200905082309.n48N9QJx031198@zion.cs.uiuc.edu> Author: evancheng Date: Fri May 8 18:09:25 2009 New Revision: 71282 URL: http://llvm.org/viewvc/llvm-project?rev=71282&view=rev Log: PPC::B and PPC::BCC's target operand may be an immediate. Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=71282&r1=71281&r2=71282&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Fri May 8 18:09:25 2009 @@ -220,9 +220,13 @@ // If there is only one terminator instruction, process it. if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { if (LastInst->getOpcode() == PPC::B) { + if (!LastInst->getOperand(0).isMBB()) + return true; TBB = LastInst->getOperand(0).getMBB(); return false; } else if (LastInst->getOpcode() == PPC::BCC) { + if (!LastInst->getOperand(2).isMBB()) + return true; // Block ends with fall-through condbranch. TBB = LastInst->getOperand(2).getMBB(); Cond.push_back(LastInst->getOperand(0)); @@ -244,6 +248,9 @@ // If the block ends with PPC::B and PPC:BCC, handle it. if (SecondLastInst->getOpcode() == PPC::BCC && LastInst->getOpcode() == PPC::B) { + if (!SecondLastInst->getOperand(2).isMBB() || + !LastInst->getOperand(0).isMBB()) + return true; TBB = SecondLastInst->getOperand(2).getMBB(); Cond.push_back(SecondLastInst->getOperand(0)); Cond.push_back(SecondLastInst->getOperand(1)); @@ -255,6 +262,8 @@ // executed, so remove it. if (SecondLastInst->getOpcode() == PPC::B && LastInst->getOpcode() == PPC::B) { + if (!SecondLastInst->getOperand(0).isMBB()) + return true; TBB = SecondLastInst->getOperand(0).getMBB(); I = LastInst; if (AllowModify) From gohman at apple.com Fri May 8 18:11:16 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 08 May 2009 23:11:16 -0000 Subject: [llvm-commits] [llvm] r71284 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/div-overflow.ll Message-ID: <200905082311.n48NBG7b031271@zion.cs.uiuc.edu> Author: djg Date: Fri May 8 18:11:16 2009 New Revision: 71284 URL: http://llvm.org/viewvc/llvm-project?rev=71284&view=rev Log: Fix bogus overflow checks by replacing them with actual overflow checks. Added: llvm/trunk/test/Analysis/ScalarEvolution/div-overflow.ll Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71284&r1=71283&r2=71284&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May 8 18:11:16 2009 @@ -1381,29 +1381,39 @@ dyn_cast(AR->getStepRecurrence(*this))) if (!Step->getValue()->getValue() .urem(RHSC->getValue()->getValue()) && - getTruncateExpr(getZeroExtendExpr(AR, ExtTy), Ty) == AR) { + getZeroExtendExpr(AR, ExtTy) == + getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy), + getZeroExtendExpr(Step, ExtTy), + AR->getLoop())) { std::vector Operands; for (unsigned i = 0, e = AR->getNumOperands(); i != e; ++i) Operands.push_back(getUDivExpr(AR->getOperand(i), RHS)); return getAddRecExpr(Operands, AR->getLoop()); } // (A*B)/C --> A*(B/C) if safe and B/C can be folded. - if (const SCEVMulExpr *M = dyn_cast(LHS)) - if (getTruncateExpr(getZeroExtendExpr(M, ExtTy), Ty) == M) + if (const SCEVMulExpr *M = dyn_cast(LHS)) { + std::vector Operands; + for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i) + Operands.push_back(getZeroExtendExpr(M->getOperand(i), ExtTy)); + if (getZeroExtendExpr(M, ExtTy) == getMulExpr(Operands)) // Find an operand that's safely divisible. for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i) { SCEVHandle Op = M->getOperand(i); SCEVHandle Div = getUDivExpr(Op, RHSC); if (!isa(Div) && getMulExpr(Div, RHSC) == Op) { - std::vector Operands = M->getOperands(); + Operands = M->getOperands(); Operands[i] = Div; return getMulExpr(Operands); } } + } // (A+B)/C --> (A/C + B/C) if safe and A/C and B/C can be folded. - if (const SCEVAddRecExpr *A = dyn_cast(LHS)) - if (getTruncateExpr(getZeroExtendExpr(A, ExtTy), Ty) == A) { - std::vector Operands; + if (const SCEVAddRecExpr *A = dyn_cast(LHS)) { + std::vector Operands; + for (unsigned i = 0, e = A->getNumOperands(); i != e; ++i) + Operands.push_back(getZeroExtendExpr(A->getOperand(i), ExtTy)); + if (getZeroExtendExpr(A, ExtTy) == getAddExpr(Operands)) { + Operands.clear(); for (unsigned i = 0, e = A->getNumOperands(); i != e; ++i) { SCEVHandle Op = getUDivExpr(A->getOperand(i), RHS); if (isa(Op) || getMulExpr(Op, RHS) != A->getOperand(i)) @@ -1413,6 +1423,7 @@ if (Operands.size() == A->getNumOperands()) return getAddExpr(Operands); } + } // Fold if both operands are constant. if (const SCEVConstant *LHSC = dyn_cast(LHS)) { Added: llvm/trunk/test/Analysis/ScalarEvolution/div-overflow.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/div-overflow.ll?rev=71284&view=auto ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/div-overflow.ll (added) +++ llvm/trunk/test/Analysis/ScalarEvolution/div-overflow.ll Fri May 8 18:11:16 2009 @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | opt -scalar-evolution -analyze -disable-output \ +; RUN: | grep {\\--> ((-128 \\* %a) /u -128)} + +; Don't let ScalarEvolution fold this div away. + +define i8 @foo(i8 %a) { + %t0 = shl i8 %a, 7 + %t1 = lshr i8 %t0, 7 + ret i8 %t1 +} From isanbard at gmail.com Fri May 8 18:16:06 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 08 May 2009 23:16:06 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r71287 - in /llvm-gcc-4.2/trunk: build_gcc gcc/ChangeLog.apple gcc/config/arm/arm.c gcc/cp/mangle.c gcc/objc/ChangeLog.apple gcc/objc/objc-act.c gcc/testsuite/ChangeLog.apple gcc/testsuite/g++.apple/anon-1.C gcc/testsuite/gcc.apple/weak.c gcc/testsuite/objc.dg/property-16.m gcc/tree-eh.c gcc/version.c Message-ID: <200905082316.n48NGDbU031470@zion.cs.uiuc.edu> Author: void Date: Fri May 8 18:16:04 2009 New Revision: 71287 URL: http://llvm.org/viewvc/llvm-project?rev=71287&view=rev Log: Merge to Apple gcc 5646. Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/anon-1.C llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/weak.c llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/property-16.m Modified: llvm-gcc-4.2/trunk/build_gcc llvm-gcc-4.2/trunk/gcc/ChangeLog.apple llvm-gcc-4.2/trunk/gcc/config/arm/arm.c llvm-gcc-4.2/trunk/gcc/cp/mangle.c llvm-gcc-4.2/trunk/gcc/objc/ChangeLog.apple llvm-gcc-4.2/trunk/gcc/objc/objc-act.c llvm-gcc-4.2/trunk/gcc/testsuite/ChangeLog.apple llvm-gcc-4.2/trunk/gcc/tree-eh.c llvm-gcc-4.2/trunk/gcc/version.c Modified: llvm-gcc-4.2/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/build_gcc?rev=71287&r1=71286&r2=71287&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/build_gcc (original) +++ llvm-gcc-4.2/trunk/build_gcc Fri May 8 18:16:04 2009 @@ -334,25 +334,25 @@ # Build the cross-compilers, using the compiler we just built. for t in $CROSS_TARGETS ; do - if [ $t != $BUILD ] ; then - mkdir -p $DIR/obj-$BUILD-$t $DIR/dst-$BUILD-$t || exit 1 - cd $DIR/obj-$BUILD-$t || exit 1 - if [ \! -f Makefile ]; then - # APPLE LOCAL begin ARM ARM_CONFIGFLAGS - $SRC_DIR/configure $CONFIGFLAGS --enable-werror-always \ - `if [ $t = 'arm' ] ; then echo $ARM_CONFIGFLAGS ; else echo $NON_ARM_CONFIGFLAGS ; fi` \ - --program-prefix=$t-apple-darwin$DARWIN_VERS- \ - --host=$BUILD-apple-darwin$DARWIN_VERS --target=$t-apple-darwin$DARWIN_VERS || exit 1 - # APPLE LOCAL end ARM ARM_CONFIGFLAGS - fi - make $MAKEFLAGS all CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1 - make $MAKEFLAGS DESTDIR=$DIR/dst-$BUILD-$t install-gcc install-target \ - CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1 - - # Add the compiler we just built to the path. - # LLVM LOCAL Support for non /usr $DEST_ROOT - PATH=$DIR/dst-$BUILD-$t/$DEST_ROOT/bin:$PATH - fi + if [ $t != $BUILD ] ; then + mkdir -p $DIR/obj-$BUILD-$t $DIR/dst-$BUILD-$t || exit 1 + cd $DIR/obj-$BUILD-$t || exit 1 + if [ \! -f Makefile ]; then + # APPLE LOCAL begin ARM ARM_CONFIGFLAGS + $SRC_DIR/configure $CONFIGFLAGS --enable-werror-always \ + `if [ $t = 'arm' ] ; then echo $ARM_CONFIGFLAGS ; else echo $NON_ARM_CONFIGFLAGS ; fi` \ + --program-prefix=$t-apple-darwin$DARWIN_VERS- \ + --host=$BUILD-apple-darwin$DARWIN_VERS --target=$t-apple-darwin$DARWIN_VERS || exit 1 + # APPLE LOCAL end ARM ARM_CONFIGFLAGS + fi + make $MAKEFLAGS all CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1 + make $MAKEFLAGS DESTDIR=$DIR/dst-$BUILD-$t install-gcc install-target \ + CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1 + + # Add the compiler we just built to the path. + # LLVM LOCAL Support for non /usr $DEST_ROOT + PATH=$DIR/dst-$BUILD-$t/$DEST_ROOT/bin:$PATH + fi done # Rearrange various libraries, for no really good reason. @@ -373,7 +373,17 @@ # Build the cross-hosted compilers. for h in $HOSTS ; do - if [ $h != $BUILD ] ; then + # LLVM LOCAL begin - Don't build for PowerPC on > 10.5 systems. + if [ $MACOSX_DEPLOYMENT_MAJOR -gt 10 -o \ + \( $MACOSX_DEPLOYMENT_MAJOR -eq 10 -a \ + $MACOSX_DEPLOYMENT_MINOR -gt 5 \) ]; then + if [ $h = "powerpc" ]; then + continue + fi + fi + # LLVM LOCAL end - Don't build for PowerPC on > 10.5 systems. + + if [ $h != $BUILD ]; then for t in $TARGETS ; do mkdir -p $DIR/obj-$h-$t $DIR/dst-$h-$t || exit 1 cd $DIR/obj-$h-$t || exit 1 Modified: llvm-gcc-4.2/trunk/gcc/ChangeLog.apple URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ChangeLog.apple?rev=71287&r1=71286&r2=71287&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/ChangeLog.apple (original) +++ llvm-gcc-4.2/trunk/gcc/ChangeLog.apple Fri May 8 18:16:04 2009 @@ -1,3 +1,9 @@ +2009-04-08 Jim Grosbach + + Radar 6738583 + * config/arm/arm.c (arm_init_cumulative_args): Always short call local + functions. + 2009-04-06 Stuart Hastings Radar 6755006 Modified: llvm-gcc-4.2/trunk/gcc/config/arm/arm.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/arm.c?rev=71287&r1=71286&r2=71287&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/arm/arm.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/arm/arm.c Fri May 8 18:16:04 2009 @@ -3055,7 +3055,8 @@ void arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype, rtx libname ATTRIBUTE_UNUSED, - tree fndecl ATTRIBUTE_UNUSED) +/* APPLE LOCAL 6738583 -mlong-calls PIC static functions */ + tree fndecl) { /* On the ARM, the offset starts at 0. */ pcum->nregs = 0; @@ -3075,6 +3076,10 @@ pcum->call_cookie = CALL_SHORT; else if (lookup_attribute ("long_call", TYPE_ATTRIBUTES (fntype))) pcum->call_cookie = CALL_LONG; + /* APPLE LOCAL begin 6738583 -mlong-calls PIC static functions */ + else if (fndecl && ! TREE_PUBLIC (fndecl)) + pcum->call_cookie = CALL_SHORT; + /* APPLE LOCAL end 6738583 -mlong-calls PIC static functions */ } /* Varargs vectors are treated the same as long long. Modified: llvm-gcc-4.2/trunk/gcc/cp/mangle.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/mangle.c?rev=71287&r1=71286&r2=71287&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/cp/mangle.c (original) +++ llvm-gcc-4.2/trunk/gcc/cp/mangle.c Fri May 8 18:16:04 2009 @@ -1468,6 +1468,10 @@ tree type = VEC_index (tree, local_classes, ix); if (type == entity) break; + /* APPLE LOCAL begin anon types 6822746 */ + if (TYPE_MAIN_DECL (type) == TYPE_MAIN_DECL (entity)) + break; + /* APPLE LOCAL end anon types 6822746 */ if (TYPE_IDENTIFIER (type) == TYPE_IDENTIFIER (entity) && TYPE_CONTEXT (type) == TYPE_CONTEXT (entity)) ++discriminator; Modified: llvm-gcc-4.2/trunk/gcc/objc/ChangeLog.apple URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/ChangeLog.apple?rev=71287&r1=71286&r2=71287&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/objc/ChangeLog.apple (original) +++ llvm-gcc-4.2/trunk/gcc/objc/ChangeLog.apple Fri May 8 18:16:04 2009 @@ -1,3 +1,20 @@ +2009-05-06 Fariborz Jahanian + + Radar 6083666 + * objc-act.c (objc_build_property_reference_expr): Never + issue diagnostics on use of an 'ivar' with property type + mismatch. Issue warning in all other cases and only in + legitimate property/user declared type mismatches. + (objc_build_property_reference_expr): Do not issue any + warning or error when property is more specialized than + its user declared accessor. + +2009-04-24 Fariborz Jahanian + + Radar 6825962 + * objc-act.c (objc_declare_property_impl): Issue property in + super class diagnostic even if explicitly asked for. + 2009-04-20 Fariborz Jahanian Radar 6803342 * objc-act.c (generate_objc_image_info): Set the imfo_info Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c?rev=71287&r1=71286&r2=71287&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Fri May 8 18:16:04 2009 @@ -1689,6 +1689,8 @@ tree rtype; tree prop, prop_type, res; bool receiver_is_class; + /* APPLE LOCAL radar 6083666 */ + tree ivar; if (component == error_mark_node || component == NULL_TREE || TREE_CODE (component) != IDENTIFIER_NODE) @@ -1703,14 +1705,16 @@ if (res == NULL_TREE || res == error_mark_node) return res; - prop_type = NULL_TREE; + /* APPLE LOCAL radar 6083666 */ + prop_type = ivar = NULL_TREE; /* APPLE LOCAL begin objc2 5512183 */ if (interface_type && !receiver_is_class) /* APPLE LOCAL end objc2 5512183 */ { /* type of the expression is either the property type or, if no property declared, then ivar type used in receiver.ivar expression. */ - tree ivar = nested_ivar_lookup (interface_type, component); + /* APPLE LOCAL radar 6083666 */ + ivar = nested_ivar_lookup (interface_type, component); if (ivar) prop_type = TREE_TYPE (ivar); else @@ -1767,11 +1771,14 @@ #endif comparison_result = comptypes (prop_type, property_type) != 1; } - if (prop_type && comparison_result) - error ("type of accessor does not match the type of property %qs", - IDENTIFIER_POINTER (PROPERTY_NAME (prop))); + /* APPLE LOCAL begin radar 6083666 */ + if (!ivar && prop_type && comparison_result + && !objc_compare_types(property_type, prop_type, -6, NULL_TREE, NULL)) + warning (0, "type of accessor does not match the type of property %qs", + IDENTIFIER_POINTER (PROPERTY_NAME (prop))); else - prop_type = property_type; + prop_type = property_type; + /* APPLE LOCAL end radar 6083666 */ /* APPLE LOCAL end radar 6029577 */ } /* APPLE LOCAL end objc2 5512183 */ @@ -17082,10 +17089,14 @@ getter_decl = lookup_method (CLASS_NST_METHODS (class), prop_name); if (getter_decl) { - if (comptypes (type, TREE_VALUE (TREE_TYPE (getter_decl))) != 1) + /* APPLE LOCAL begin radar 6083666 */ + tree getter_type = TREE_VALUE (TREE_TYPE (getter_decl)); + if ((comptypes (type, getter_type) != 1) + && !objc_compare_types (type, getter_type, -6, NULL_TREE, NULL)) /* APPLE LOCAL radar 4815054 */ - error ("type of accessor does not match the type of property %qs", - IDENTIFIER_POINTER (prop_name)); + warning (0, "type of accessor does not match the type of property %qs", + IDENTIFIER_POINTER (prop_name)); + /* APPLE LOCAL end radar 6083666 */ if (METHOD_SEL_ARGS (getter_decl) != NULL_TREE) error ("accessor %<%c%s%> cannot have any argument", '-', IDENTIFIER_POINTER (prop_name)); @@ -20275,20 +20286,19 @@ /* APPLE LOCAL begin radar 6029624 */ tree property_type = TREE_TYPE (property_decl); bool comparison_result; - /* APPLE LOCAL begin radar 5435299 */ - if (flag_new_property_ivar_synthesis && flag_objc_abi == 2 && - !TREE_PURPOSE (chain)) { + /* APPLE LOCAL begin radar 5435299 - radar 6825962 */ + if (flag_new_property_ivar_synthesis && flag_objc_abi == 2) { /* In ObjC2 abi, it is illegal when a @synthesize with no named ivar does not have a matching ivar in its class but some superclass ivar already has the desired name */ tree record = CLASS_STATIC_TEMPLATE (class); if (record && record != DECL_CONTEXT (ivar_decl)) - error ("property %qs attempting to use ivar %qs in super class %qs", + error ("property %qs attempting to use ivar %qs declared in super class of %qs", IDENTIFIER_POINTER (property_name), IDENTIFIER_POINTER (ivar_name), IDENTIFIER_POINTER (OBJC_TYPE_NAME (record))); } - /* APPLE LOCAL end radar 5435299 */ + /* APPLE LOCAL end radar 5435299 - radar 6825962 */ /* APPLE LOCAL begin radar 5389292 */ #ifdef OBJCPLUS if (TREE_CODE (property_type) == REFERENCE_TYPE) Modified: llvm-gcc-4.2/trunk/gcc/testsuite/ChangeLog.apple URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/ChangeLog.apple?rev=71287&r1=71286&r2=71287&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/ChangeLog.apple (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/ChangeLog.apple Fri May 8 18:16:04 2009 @@ -1,3 +1,15 @@ +2009-05-06 Fariborz Jahanian + + Radar 6083666 + * objc.dg/property-15.m: Modified + * objc.dg/property-16.m: New + +2009-04-24 Fariborz Jahanian + + Radar 6825962 + * property-synthesize-ivar-6.m : Modified. + * optional-property.m: Modified. + 2009-04-20 Fariborz Jahanian Radar 6803242 Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/anon-1.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/anon-1.C?rev=71287&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/anon-1.C (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/anon-1.C Fri May 8 18:16:04 2009 @@ -0,0 +1,15 @@ +/* APPLE LOCAL file anon types 6822746 */ +/* dg-do compile */ + +class C { +public: + C(); + C(const C& o); +}; + +void foo() { + typedef struct { + C m; + } T; + T l[4]; +} Added: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/weak.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/weak.c?rev=71287&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/weak.c (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/weak.c Fri May 8 18:16:04 2009 @@ -0,0 +1,31 @@ +/* APPLE LOCAL file weak variables 6822086 */ +/* { dg-do run { target "i?86-*-darwin*" } } */ +/* { dg-options "-O2 -m32" } */ +extern int i __attribute__((weak)); + +double sin(double); + +int j; + +void foo(int j); +double ed; + +main() { + int l; + double d; + for (l=0; l < 100; ++l) { + if (&i) + j = i; + else + j = 0; + d += sin(j); + } + ed = d; + return 0; +} + +/* Hide: void foo(int j) { } from the optimizer. */ +asm(".globl _foo"); +asm("_foo: ret"); +asm(".globl _i"); +asm(".set _i, 0"); Added: llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/property-16.m URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/property-16.m?rev=71287&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/property-16.m (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/property-16.m Fri May 8 18:16:04 2009 @@ -0,0 +1,39 @@ +/* APPLE LOCAL file radar 6083666 */ +/* Test to check that 1) no warning/error is issued when an 'ivar' which has + a matching name with property has a type mismatch with that property. */ +/* { dg-options "-mmacosx-version-min=10.5" { target powerpc*-*-darwin* i?86*-*-darwin* } } */ +/* { dg-do compile } */ + + at interface NSArray @end + + at interface NSMutableArray : NSArray + at end + + at interface Class1 +{ + NSMutableArray* pieces; + double* unrelated; +} + + at property (readonly) NSArray* pieces; + at property (readonly) NSArray* unrelated; + at property (readonly) NSMutableArray* prop_user_getter; + + at end + + at interface Class2 { + Class1* container; +} + + at end + + at implementation Class2 + +- (void) lastPiece +{ + container.pieces; + container.unrelated; + container.prop_user_getter; +} + + at end Modified: llvm-gcc-4.2/trunk/gcc/tree-eh.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/tree-eh.c?rev=71287&r1=71286&r2=71287&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/tree-eh.c (original) +++ llvm-gcc-4.2/trunk/gcc/tree-eh.c Fri May 8 18:16:04 2009 @@ -2015,6 +2015,14 @@ return true; return false; + /* APPLE LOCAL begin weak variables 6822086 */ + case VAR_DECL: + /* Assume that weak variables may trap. */ + if (DECL_WEAK (expr)) + return true; + return false; + /* APPLE LOCAL end weak variables 6822086 */ + default: /* Any floating arithmetic may trap. */ if (fp_operation && flag_trapping_math) Modified: llvm-gcc-4.2/trunk/gcc/version.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/version.c?rev=71287&r1=71286&r2=71287&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/version.c (original) +++ llvm-gcc-4.2/trunk/gcc/version.c Fri May 8 18:16:04 2009 @@ -11,12 +11,12 @@ /* APPLE LOCAL begin Apple version */ #ifdef ENABLE_LLVM #ifdef LLVM_VERSION_INFO -#define VERSUFFIX " (Based on Apple Inc. build 5645) (LLVM build " LLVM_VERSION_INFO ")" +#define VERSUFFIX " (Based on Apple Inc. build 5646) (LLVM build " LLVM_VERSION_INFO ")" #else -#define VERSUFFIX " (Based on Apple Inc. build 5645) (LLVM build)" +#define VERSUFFIX " (Based on Apple Inc. build 5646) (LLVM build)" #endif #else -#define VERSUFFIX " (Based on Apple Inc. build 5645)" +#define VERSUFFIX " (Based on Apple Inc. build 5646)" #endif /* APPLE LOCAL end Apple version */ From isanbard at gmail.com Fri May 8 18:32:51 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 08 May 2009 23:32:51 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r71289 - /llvm-gcc-4.2/trunk/build_gcc Message-ID: <200905082332.n48NWqJR032016@zion.cs.uiuc.edu> Author: void Date: Fri May 8 18:32:51 2009 New Revision: 71289 URL: http://llvm.org/viewvc/llvm-project?rev=71289&view=rev Log: Accidental commit. Modified: llvm-gcc-4.2/trunk/build_gcc Modified: llvm-gcc-4.2/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/build_gcc?rev=71289&r1=71288&r2=71289&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/build_gcc (original) +++ llvm-gcc-4.2/trunk/build_gcc Fri May 8 18:32:51 2009 @@ -334,25 +334,25 @@ # Build the cross-compilers, using the compiler we just built. for t in $CROSS_TARGETS ; do - if [ $t != $BUILD ] ; then - mkdir -p $DIR/obj-$BUILD-$t $DIR/dst-$BUILD-$t || exit 1 - cd $DIR/obj-$BUILD-$t || exit 1 - if [ \! -f Makefile ]; then - # APPLE LOCAL begin ARM ARM_CONFIGFLAGS - $SRC_DIR/configure $CONFIGFLAGS --enable-werror-always \ - `if [ $t = 'arm' ] ; then echo $ARM_CONFIGFLAGS ; else echo $NON_ARM_CONFIGFLAGS ; fi` \ - --program-prefix=$t-apple-darwin$DARWIN_VERS- \ - --host=$BUILD-apple-darwin$DARWIN_VERS --target=$t-apple-darwin$DARWIN_VERS || exit 1 - # APPLE LOCAL end ARM ARM_CONFIGFLAGS - fi - make $MAKEFLAGS all CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1 - make $MAKEFLAGS DESTDIR=$DIR/dst-$BUILD-$t install-gcc install-target \ - CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1 - - # Add the compiler we just built to the path. - # LLVM LOCAL Support for non /usr $DEST_ROOT - PATH=$DIR/dst-$BUILD-$t/$DEST_ROOT/bin:$PATH - fi + if [ $t != $BUILD ] ; then + mkdir -p $DIR/obj-$BUILD-$t $DIR/dst-$BUILD-$t || exit 1 + cd $DIR/obj-$BUILD-$t || exit 1 + if [ \! -f Makefile ]; then + # APPLE LOCAL begin ARM ARM_CONFIGFLAGS + $SRC_DIR/configure $CONFIGFLAGS --enable-werror-always \ + `if [ $t = 'arm' ] ; then echo $ARM_CONFIGFLAGS ; else echo $NON_ARM_CONFIGFLAGS ; fi` \ + --program-prefix=$t-apple-darwin$DARWIN_VERS- \ + --host=$BUILD-apple-darwin$DARWIN_VERS --target=$t-apple-darwin$DARWIN_VERS || exit 1 + # APPLE LOCAL end ARM ARM_CONFIGFLAGS + fi + make $MAKEFLAGS all CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1 + make $MAKEFLAGS DESTDIR=$DIR/dst-$BUILD-$t install-gcc install-target \ + CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1 + + # Add the compiler we just built to the path. + # LLVM LOCAL Support for non /usr $DEST_ROOT + PATH=$DIR/dst-$BUILD-$t/$DEST_ROOT/bin:$PATH + fi done # Rearrange various libraries, for no really good reason. @@ -373,17 +373,7 @@ # Build the cross-hosted compilers. for h in $HOSTS ; do - # LLVM LOCAL begin - Don't build for PowerPC on > 10.5 systems. - if [ $MACOSX_DEPLOYMENT_MAJOR -gt 10 -o \ - \( $MACOSX_DEPLOYMENT_MAJOR -eq 10 -a \ - $MACOSX_DEPLOYMENT_MINOR -gt 5 \) ]; then - if [ $h = "powerpc" ]; then - continue - fi - fi - # LLVM LOCAL end - Don't build for PowerPC on > 10.5 systems. - - if [ $h != $BUILD ]; then + if [ $h != $BUILD ] ; then for t in $TARGETS ; do mkdir -p $DIR/obj-$h-$t $DIR/dst-$h-$t || exit 1 cd $DIR/obj-$h-$t || exit 1 From evan.cheng at apple.com Fri May 8 18:35:49 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 08 May 2009 23:35:49 -0000 Subject: [llvm-commits] [llvm] r71291 - in /llvm/trunk: lib/CodeGen/CodePlacementOpt.cpp test/CodeGen/X86/code_placement.ll Message-ID: <200905082335.n48NZnqg032177@zion.cs.uiuc.edu> Author: evancheng Date: Fri May 8 18:35:49 2009 New Revision: 71291 URL: http://llvm.org/viewvc/llvm-project?rev=71291&view=rev Log: Enable loop bb placement optimization. Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp llvm/trunk/test/CodeGen/X86/code_placement.ll Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp?rev=71291&r1=71290&r2=71291&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp (original) +++ llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Fri May 8 18:35:49 2009 @@ -19,17 +19,11 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" using namespace llvm; -static cl::opt -OptLoopBBPlacement("opt-loop-bb-placement", - cl::init(false), cl::Hidden, - cl::desc("Optimize block placements in loops")); - STATISTIC(NumHeaderAligned, "Number of loop header aligned"); STATISTIC(NumIntraElim, "Number of intra loop branches eliminated"); STATISTIC(NumIntraMoved, "Number of intra loop branches moved"); @@ -108,9 +102,6 @@ /// jcc C, [exit] /// bool CodePlacementOpt::OptimizeIntraLoopEdges() { - if (!OptLoopBBPlacement) - return false; - bool Changed = false; for (unsigned i = 0, e = UncondJmpMBBs.size(); i != e; ++i) { MachineBasicBlock *MBB = UncondJmpMBBs[i].first; Modified: llvm/trunk/test/CodeGen/X86/code_placement.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/code_placement.ll?rev=71291&r1=71290&r2=71291&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/code_placement.ll (original) +++ llvm/trunk/test/CodeGen/X86/code_placement.ll Fri May 8 18:35:49 2009 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 -opt-loop-bb-placement | %prcontext jmp 1 | grep align +; RUN: llvm-as < %s | llc -march=x86 | %prcontext jmp 1 | grep align @Te0 = external global [256 x i32] ; <[256 x i32]*> [#uses=5] @Te1 = external global [256 x i32] ; <[256 x i32]*> [#uses=4] From gohman at apple.com Fri May 8 19:14:52 2009 From: gohman at apple.com (Dan Gohman) Date: Sat, 09 May 2009 00:14:52 -0000 Subject: [llvm-commits] [llvm] r71302 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200905090014.n490ErjB002759@zion.cs.uiuc.edu> Author: djg Date: Fri May 8 19:14:52 2009 New Revision: 71302 URL: http://llvm.org/viewvc/llvm-project?rev=71302&view=rev Log: Don't attempt to handle unsized types in ScalarEvolution's GEP analyzer. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71302&r1=71301&r2=71302&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May 8 19:14:52 2009 @@ -1935,6 +1935,9 @@ const Type *IntPtrTy = TD->getIntPtrType(); Value *Base = GEP->getOperand(0); + // Don't attempt to analyze GEPs over unsized objects. + if (!cast(Base->getType())->getElementType()->isSized()) + return getUnknown(GEP); SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy); gep_type_iterator GTI = gep_type_begin(GEP); for (GetElementPtrInst::op_iterator I = next(GEP->op_begin()), From evan.cheng at apple.com Fri May 8 20:08:24 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 09 May 2009 01:08:24 -0000 Subject: [llvm-commits] [llvm] r71305 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200905090108.n4918ON4005182@zion.cs.uiuc.edu> Author: evancheng Date: Fri May 8 20:08:24 2009 New Revision: 71305 URL: http://llvm.org/viewvc/llvm-project?rev=71305&view=rev Log: Factor out code that optimize loop terminating condition. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=71305&r1=71304&r2=71305&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Fri May 8 20:08:24 2009 @@ -164,8 +164,11 @@ ICmpInst *ChangeCompareStride(Loop *L, ICmpInst *Cond, IVStrideUse* &CondUse, const SCEVHandle* &CondStride); + void OptimizeIndvars(Loop *L); + void OptimizeLoopTermCond(Loop *L); + /// OptimizeShadowIV - If IV is used in a int-to-float cast /// inside the loop then try to eliminate the cast opeation. void OptimizeShadowIV(Loop *L); @@ -2378,6 +2381,12 @@ OptimizeShadowIV(L); + OptimizeLoopTermCond(L); +} + +/// OptimizeLoopTermCond - Change loop terminating condition to use the +/// postinc iv when possible. +void LoopStrengthReduce::OptimizeLoopTermCond(Loop *L) { // Finally, get the terminating condition for the loop if possible. If we // can, we want to change it to use a post-incremented version of its // induction variable, to allow coalescing the live ranges for the IV into From kremenek at apple.com Fri May 8 22:12:26 2009 From: kremenek at apple.com (Ted Kremenek) Date: Sat, 09 May 2009 03:12:26 -0000 Subject: [llvm-commits] [llvm] r71313 - /llvm/tags/checker/checker-0.197/ Message-ID: <200905090312.n493CQQd011033@zion.cs.uiuc.edu> Author: kremenek Date: Fri May 8 22:12:25 2009 New Revision: 71313 URL: http://llvm.org/viewvc/llvm-project?rev=71313&view=rev Log: Tagging checker-0.197. Added: llvm/tags/checker/checker-0.197/ - copied from r71312, llvm/trunk/ From sanjiv.gupta at microchip.com Sat May 9 00:11:21 2009 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Sat, 09 May 2009 05:11:21 -0000 Subject: [llvm-commits] [llvm] r71323 - /llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Message-ID: <200905090511.n495BLEJ014792@zion.cs.uiuc.edu> Author: sgupta Date: Sat May 9 00:11:19 2009 New Revision: 71323 URL: http://llvm.org/viewvc/llvm-project?rev=71323&view=rev Log: Use 16 bit arithmetic while retrieving the address of callee's frame during indirect function calls, and set pclath before every call to retrieve the frame address. Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=71323&r1=71322&r2=71323&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Sat May 9 00:11:19 2009 @@ -1151,10 +1151,14 @@ SDValue Data_Lo, Data_Hi; SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag); - Hi = DAG.getNode(PIC16ISD::MTPCLATH, dl, MVT::i8, Hi); - // Subtract 2 from Lo to get the Lower part of DataAddress. - Data_Lo = DAG.getNode(ISD::SUB, dl, MVT::i8, Lo, DAG.getConstant(2, MVT::i8)); - Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Data_Lo, Hi); + // Subtract 2 from Address to get the Lower part of DataAddress. + SDVTList VTList = DAG.getVTList(MVT::i8, MVT::Flag); + Data_Lo = DAG.getNode(ISD::SUBC, dl, VTList, Lo, + DAG.getConstant(2, MVT::i8)); + SDValue Ops[3] = { Hi, DAG.getConstant(0, MVT::i8), Data_Lo.getValue(1)}; + Data_Hi = DAG.getNode(ISD::SUBE, dl, VTList, Ops, 3); + SDValue PCLATH = DAG.getNode(PIC16ISD::MTPCLATH, dl, MVT::i8, Data_Hi); + Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Data_Lo, PCLATH); SDValue Call = DAG.getNode(PIC16ISD::CALLW, dl, Tys, Chain, Callee, OperFlag); Chain = getChain(Call); @@ -1172,10 +1176,15 @@ Chain = getChain(SeqStart); OperFlag = getOutFlag(SeqStart); // To manage the data dependency - // Subtract 1 to Lo part for the second code word. - Data_Lo = DAG.getNode(ISD::SUB, dl, MVT::i8, Lo, DAG.getConstant(1, MVT::i8)); + // Subtract 1 from Address to get high part of data address. + Data_Lo = DAG.getNode(ISD::SUBC, dl, VTList, Lo, + DAG.getConstant(1, MVT::i8)); + SDValue HiOps[3] = { Hi, DAG.getConstant(0, MVT::i8), Data_Lo.getValue(1)}; + Data_Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3); + PCLATH = DAG.getNode(PIC16ISD::MTPCLATH, dl, MVT::i8, Data_Hi); + // Use new Lo to make another CALLW - Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Data_Lo, Hi); + Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Data_Lo, PCLATH); Call = DAG.getNode(PIC16ISD::CALLW, dl, Tys, Chain, Callee, OperFlag); Chain = getChain(Call); OperFlag = getOutFlag(Call); From baldrick at free.fr Sat May 9 01:37:04 2009 From: baldrick at free.fr (Duncan Sands) Date: Sat, 9 May 2009 08:37:04 +0200 Subject: [llvm-commits] [llvm-gcc-4.2] r71287 - in /llvm-gcc-4.2/trunk: build_gcc gcc/ChangeLog.apple gcc/config/arm/arm.c gcc/cp/mangle.c gcc/objc/ChangeLog.apple gcc/objc/objc-act.c gcc/testsuite/ChangeLog.apple gcc/testsuite/g++.apple/anon-1.C gcc/testsuite/gcc.apple/weak.c gcc/testsuite/objc.dg/property-16.m gcc/tree-eh.c gcc/version.c In-Reply-To: <200905082316.n48NGDbU031470@zion.cs.uiuc.edu> References: <200905082316.n48NGDbU031470@zion.cs.uiuc.edu> Message-ID: <200905090837.04512.baldrick@free.fr> Hi, > + /* APPLE LOCAL begin weak variables 6822086 */ > + case VAR_DECL: > + /* Assume that weak variables may trap. */ > + if (DECL_WEAK (expr)) > + return true; > + return false; > + /* APPLE LOCAL end weak variables 6822086 */ shouldn't this only be needed for weak references (gets turned into ExternalWeakLinkage in LLVM)? Ciao, Duncan. From baldrick at free.fr Sat May 9 01:57:26 2009 From: baldrick at free.fr (Duncan Sands) Date: Sat, 9 May 2009 08:57:26 +0200 Subject: [llvm-commits] [llvm] r71262 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp In-Reply-To: <200905082058.n48KwdGu026892@zion.cs.uiuc.edu> References: <200905082058.n48KwdGu026892@zion.cs.uiuc.edu> Message-ID: <200905090857.27046.baldrick@free.fr> Hi Dan, > Fix another bug in r71252. This code supports GetElementPtr > constant exprs as well as instructions. ... > - SCEVHandle createNodeForGEP(GetElementPtrInst *GEP); > + SCEVHandle createNodeForGEP(User *GEP); can't you use a Value* here? That covers instructions as well as constants. Ciao, Duncan. From nicholas at mxc.ca Sat May 9 02:05:30 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 09 May 2009 00:05:30 -0700 Subject: [llvm-commits] [llvm] r71210 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: References: <200905080647.n486lbo6018160@zion.cs.uiuc.edu> Message-ID: <4A052B3A.50907@mxc.ca> Misha Brukman wrote: > On Fri, May 8, 2009 at 2:47 AM, Nick Lewycky > wrote: > > Author: nicholas > Date: Fri May 8 01:47:37 2009 > New Revision: 71210 > > URL: http://llvm.org/viewvc/llvm-project?rev=71210&view=rev > > Log: > This transform requires valid TargetData info. Wrap it in 'if (TD)' in > preparation for the day we use null TargetData when no target is > specified. > > > Instead of adding an extra indent level, how about adding: > > if (!TD) { > return; > } > > before the TargetData-dependent code? There's additional code in the same function that doesn't depend on TD. I could've broken them into two functions but made a judgement call not to (I couldn't think of a name to distinguish the two functions). Nick > > > ------------------------------------------------------------------------ > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Sat May 9 02:06:46 2009 From: baldrick at free.fr (Duncan Sands) Date: Sat, 09 May 2009 07:06:46 -0000 Subject: [llvm-commits] [llvm] r71349 - in /llvm/trunk: bindings/ocaml/target/ include/llvm-c/ include/llvm/Target/ lib/Analysis/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/ExecutionEngine/ lib/ExecutionEngine/Interpreter/ lib/ExecutionEngine/JIT/ lib/Target/ lib/Target/ARM/ lib/Target/ARM/AsmPrinter/ lib/Target/Alpha/AsmPrinter/ lib/Target/CBackend/ lib/Target/CellSPU/AsmPrinter/ lib/Target/IA64/AsmPrinter/ lib/Target/MSIL/ lib/Target/Mips/ lib/Target/Mips/AsmPrinter/ lib/Target/PIC16/ lib/Target/PowerP... Message-ID: <200905090706.n4976n4F018353@zion.cs.uiuc.edu> Author: baldrick Date: Sat May 9 02:06:46 2009 New Revision: 71349 URL: http://llvm.org/viewvc/llvm-project?rev=71349&view=rev Log: Rename PaddedSize to AllocSize, in the hope that this will make it more obvious what it represents, and stop it being confused with the StoreSize. Modified: llvm/trunk/bindings/ocaml/target/llvm_target.mli llvm/trunk/include/llvm-c/Target.h llvm/trunk/include/llvm/Target/TargetData.h llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp llvm/trunk/lib/Analysis/ConstantFolding.cpp llvm/trunk/lib/Analysis/ScalarEvolution.cpp llvm/trunk/lib/Analysis/ValueTracking.cpp llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/trunk/lib/CodeGen/ELFWriter.cpp llvm/trunk/lib/CodeGen/MachOWriter.cpp llvm/trunk/lib/CodeGen/MachOWriter.h llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/CodeGen/StackProtector.cpp llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp llvm/trunk/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp llvm/trunk/lib/Target/CBackend/CBackend.cpp llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp llvm/trunk/lib/Target/DarwinTargetAsmInfo.cpp llvm/trunk/lib/Target/ELFTargetAsmInfo.cpp llvm/trunk/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp llvm/trunk/lib/Target/MSIL/MSILWriter.cpp llvm/trunk/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp llvm/trunk/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp llvm/trunk/lib/Target/Target.cpp llvm/trunk/lib/Target/TargetData.cpp llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp llvm/trunk/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp llvm/trunk/lib/Target/X86/X86FastISel.cpp llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp llvm/trunk/lib/Target/XCore/XCoreTargetAsmInfo.cpp llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp llvm/trunk/utils/TableGen/CallingConvEmitter.cpp Modified: llvm/trunk/bindings/ocaml/target/llvm_target.mli URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/target/llvm_target.mli?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/target/llvm_target.mli (original) +++ llvm/trunk/bindings/ocaml/target/llvm_target.mli Sat May 9 02:06:46 2009 @@ -70,7 +70,7 @@ external store_size : TargetData.t -> Llvm.lltype -> Int64.t = "llvm_store_size" (** Computes the ABI size of a type in bytes for a target. - See the method llvm::TargetData::getTypePaddedSize. *) + See the method llvm::TargetData::getTypeAllocSize. *) external abi_size : TargetData.t -> Llvm.lltype -> Int64.t = "llvm_abi_size" (** Computes the ABI alignment of a type in bytes for a target. Modified: llvm/trunk/include/llvm-c/Target.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Target.h?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/Target.h (original) +++ llvm/trunk/include/llvm-c/Target.h Sat May 9 02:06:46 2009 @@ -70,7 +70,7 @@ unsigned long long LLVMStoreSizeOfType(LLVMTargetDataRef, LLVMTypeRef); /** Computes the ABI size of a type in bytes for a target. - See the method llvm::TargetData::getTypePaddedSize. */ + See the method llvm::TargetData::getTypeAllocSize. */ unsigned long long LLVMABISizeOfType(LLVMTargetDataRef, LLVMTypeRef); /** Computes the ABI alignment of a type in bytes for a target. Modified: llvm/trunk/include/llvm/Target/TargetData.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetData.h?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetData.h (original) +++ llvm/trunk/include/llvm/Target/TargetData.h Sat May 9 02:06:46 2009 @@ -157,8 +157,8 @@ /// Size examples: /// - /// Type SizeInBits StoreSizeInBits PaddedSizeInBits[*] - /// ---- ---------- --------------- ---------------- + /// Type SizeInBits StoreSizeInBits AllocSizeInBits[*] + /// ---- ---------- --------------- --------------- /// i1 1 8 8 /// i8 8 8 8 /// i19 19 24 32 @@ -169,7 +169,7 @@ /// Double 64 64 64 /// X86_FP80 80 80 96 /// - /// [*] The padded size depends on the alignment, and thus on the target. + /// [*] The alloc size depends on the alignment, and thus on the target. /// These values are for x86-32 linux. /// getTypeSizeInBits - Return the number of bits necessary to hold the @@ -190,21 +190,21 @@ return 8*getTypeStoreSize(Ty); } - /// getTypePaddedSize - Return the offset in bytes between successive objects + /// getTypeAllocSize - Return the offset in bytes between successive objects /// of the specified type, including alignment padding. This is the amount /// that alloca reserves for this type. For example, returns 12 or 16 for /// x86_fp80, depending on alignment. - uint64_t getTypePaddedSize(const Type* Ty) const { + uint64_t getTypeAllocSize(const Type* Ty) const { // Round up to the next alignment boundary. return RoundUpAlignment(getTypeStoreSize(Ty), getABITypeAlignment(Ty)); } - /// getTypePaddedSizeInBits - Return the offset in bits between successive + /// getTypeAllocSizeInBits - Return the offset in bits between successive /// objects of the specified type, including alignment padding; always a /// multiple of 8. This is the amount that alloca reserves for this type. /// For example, returns 96 or 128 for x86_fp80, depending on alignment. - uint64_t getTypePaddedSizeInBits(const Type* Ty) const { - return 8*getTypePaddedSize(Ty); + uint64_t getTypeAllocSizeInBits(const Type* Ty) const { + return 8*getTypeAllocSize(Ty); } /// getABITypeAlignment - Return the minimum ABI-required alignment for the Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Sat May 9 02:06:46 2009 @@ -123,7 +123,7 @@ } if (AccessTy->isSized()) - return TD.getTypePaddedSize(AccessTy) < Size; + return TD.getTypeAllocSize(AccessTy) < Size; return false; } Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Sat May 9 02:06:46 2009 @@ -77,7 +77,7 @@ Offset += TD.getStructLayout(ST)->getElementOffset(CI->getZExtValue()); } else { const SequentialType *SQT = cast(*GTI); - Offset += TD.getTypePaddedSize(SQT->getElementType())*CI->getSExtValue(); + Offset += TD.getTypeAllocSize(SQT->getElementType())*CI->getSExtValue(); } } return true; @@ -405,8 +405,8 @@ if (const ArrayType *AT = dyn_cast(GVTy->getElementType())) { const Type *ElTy = AT->getElementType(); - uint64_t PaddedSize = TD->getTypePaddedSize(ElTy); - APInt PSA(L->getValue().getBitWidth(), PaddedSize); + uint64_t AllocSize = TD->getTypeAllocSize(ElTy); + APInt PSA(L->getValue().getBitWidth(), AllocSize); if (ElTy == cast(DestTy)->getElementType() && L->getValue().urem(PSA) == 0) { APInt ElemIdx = L->getValue().udiv(PSA); Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Sat May 9 02:06:46 2009 @@ -1961,7 +1961,7 @@ IntPtrTy); LocalOffset = getMulExpr(LocalOffset, - getIntegerSCEV(TD->getTypePaddedSize(*GTI), + getIntegerSCEV(TD->getTypeAllocSize(*GTI), IntPtrTy)); TotalOffset = getAddExpr(TotalOffset, LocalOffset); } Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ValueTracking.cpp (original) +++ llvm/trunk/lib/Analysis/ValueTracking.cpp Sat May 9 02:06:46 2009 @@ -459,7 +459,7 @@ const Type *IndexedTy = GTI.getIndexedType(); if (!IndexedTy->isSized()) return; unsigned GEPOpiBits = Index->getType()->getPrimitiveSizeInBits(); - uint64_t TypeSize = TD ? TD->getTypePaddedSize(IndexedTy) : 1; + uint64_t TypeSize = TD ? TD->getTypeAllocSize(IndexedTy) : 1; LocalMask = APInt::getAllOnesValue(GEPOpiBits); LocalKnownZero = LocalKnownOne = APInt(GEPOpiBits, 0); ComputeMaskedBits(Index, LocalMask, Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Sat May 9 02:06:46 2009 @@ -313,7 +313,7 @@ EmitZeros(NewOffset - Offset); const Type *Ty = CPE.getType(); - Offset = NewOffset + TM.getTargetData()->getTypePaddedSize(Ty); + Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty); O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' << CPI << ":\t\t\t\t\t"; @@ -889,12 +889,12 @@ // We can emit the pointer value into this slot if the slot is an // integer slot greater or equal to the size of the pointer. - if (TD->getTypePaddedSize(Ty) >= TD->getTypePaddedSize(Op->getType())) + if (TD->getTypeAllocSize(Ty) >= TD->getTypeAllocSize(Op->getType())) return EmitConstantValueOnly(Op); O << "(("; EmitConstantValueOnly(Op); - APInt ptrMask = APInt::getAllOnesValue(TD->getTypePaddedSizeInBits(Ty)); + APInt ptrMask = APInt::getAllOnesValue(TD->getTypeAllocSizeInBits(Ty)); SmallString<40> S; ptrMask.toStringUnsigned(S); @@ -992,14 +992,14 @@ unsigned AddrSpace) { // Print the fields in successive locations. Pad to align if needed! const TargetData *TD = TM.getTargetData(); - unsigned Size = TD->getTypePaddedSize(CVS->getType()); + unsigned Size = TD->getTypeAllocSize(CVS->getType()); const StructLayout *cvsLayout = TD->getStructLayout(CVS->getType()); uint64_t sizeSoFar = 0; for (unsigned i = 0, e = CVS->getNumOperands(); i != e; ++i) { const Constant* field = CVS->getOperand(i); // Check if padding is needed and insert one or more 0s. - uint64_t fieldSize = TD->getTypePaddedSize(field->getType()); + uint64_t fieldSize = TD->getTypeAllocSize(field->getType()); uint64_t padSize = ((i == e-1 ? Size : cvsLayout->getElementOffset(i+1)) - cvsLayout->getElementOffset(i)) - fieldSize; sizeSoFar += fieldSize + padSize; @@ -1123,7 +1123,7 @@ << " long double most significant halfword"; O << '\n'; } - EmitZeros(TD->getTypePaddedSize(Type::X86_FP80Ty) - + EmitZeros(TD->getTypeAllocSize(Type::X86_FP80Ty) - TD->getTypeStoreSize(Type::X86_FP80Ty), AddrSpace); return; } else if (CFP->getType() == Type::PPC_FP128Ty) { @@ -1228,7 +1228,7 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) { const TargetData *TD = TM.getTargetData(); const Type *type = CV->getType(); - unsigned Size = TD->getTypePaddedSize(type); + unsigned Size = TD->getTypeAllocSize(type); if (CV->isNullValue() || isa(CV)) { EmitZeros(Size, AddrSpace); Modified: llvm/trunk/lib/CodeGen/ELFWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFWriter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ELFWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/ELFWriter.cpp Sat May 9 02:06:46 2009 @@ -284,7 +284,7 @@ unsigned Align = TM.getTargetData()->getPreferredAlignment(GV); unsigned Size = - TM.getTargetData()->getTypePaddedSize(GV->getType()->getElementType()); + TM.getTargetData()->getTypeAllocSize(GV->getType()->getElementType()); // If this global has a zero initializer, it is part of the .bss or common // section. Modified: llvm/trunk/lib/CodeGen/MachOWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachOWriter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachOWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/MachOWriter.cpp Sat May 9 02:06:46 2009 @@ -281,7 +281,7 @@ // "giant object for PIC" optimization. for (unsigned i = 0, e = CP.size(); i != e; ++i) { const Type *Ty = CP[i].getType(); - unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty); + unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty); MachOWriter::MachOSection *Sec = MOW.getConstSection(CP[i].Val.ConstVal); OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian); @@ -355,7 +355,7 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) { const Type *Ty = GV->getType()->getElementType(); - unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty); + unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty); unsigned Align = TM.getTargetData()->getPreferredAlignment(GV); // Reserve space in the .bss section for this symbol while maintaining the @@ -400,7 +400,7 @@ void MachOWriter::EmitGlobal(GlobalVariable *GV) { const Type *Ty = GV->getType()->getElementType(); - unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty); + unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty); bool NoInit = !GV->hasInitializer(); // If this global has a zero initializer, it is part of the .bss or common @@ -825,7 +825,7 @@ continue; } else if (const ConstantVector *CP = dyn_cast(PC)) { unsigned ElementSize = - TD->getTypePaddedSize(CP->getType()->getElementType()); + TD->getTypeAllocSize(CP->getType()->getElementType()); for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) WorkList.push_back(CPair(CP->getOperand(i), PA+i*ElementSize)); } else if (const ConstantExpr *CE = dyn_cast(PC)) { @@ -926,10 +926,10 @@ abort(); } } else if (isa(PC)) { - memset((void*)PA, 0, (size_t)TD->getTypePaddedSize(PC->getType())); + memset((void*)PA, 0, (size_t)TD->getTypeAllocSize(PC->getType())); } else if (const ConstantArray *CPA = dyn_cast(PC)) { unsigned ElementSize = - TD->getTypePaddedSize(CPA->getType()->getElementType()); + TD->getTypeAllocSize(CPA->getType()->getElementType()); for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i) WorkList.push_back(CPair(CPA->getOperand(i), PA+i*ElementSize)); } else if (const ConstantStruct *CPS = dyn_cast(PC)) { Modified: llvm/trunk/lib/CodeGen/MachOWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachOWriter.h?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachOWriter.h (original) +++ llvm/trunk/lib/CodeGen/MachOWriter.h Sat May 9 02:06:46 2009 @@ -468,7 +468,7 @@ const Type *Ty = C->getType(); if (Ty->isPrimitiveType() || Ty->isInteger()) { - unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty); + unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty); switch(Size) { default: break; // Fall through to __TEXT,__const case 4: Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sat May 9 02:06:46 2009 @@ -5694,7 +5694,7 @@ // Get the offsets to the 0 and 1 element of the array so that we can // select between them. SDValue Zero = DAG.getIntPtrConstant(0); - unsigned EltSize = (unsigned)TD.getTypePaddedSize(Elts[0]->getType()); + unsigned EltSize = (unsigned)TD.getTypeAllocSize(Elts[0]->getType()); SDValue One = DAG.getIntPtrConstant(EltSize); SDValue Cond = DAG.getSetCC(DL, Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Sat May 9 02:06:46 2009 @@ -285,7 +285,7 @@ if (ConstantInt *CI = dyn_cast(Idx)) { if (CI->getZExtValue() == 0) continue; uint64_t Offs = - TD.getTypePaddedSize(Ty)*cast(CI)->getSExtValue(); + TD.getTypeAllocSize(Ty)*cast(CI)->getSExtValue(); N = FastEmit_ri_(VT, ISD::ADD, N, Offs, VT); if (N == 0) // Unhandled operand. Halt "fast" selection and bail. @@ -294,7 +294,7 @@ } // N = N + Idx * ElementSize; - uint64_t ElementSize = TD.getTypePaddedSize(Ty); + uint64_t ElementSize = TD.getTypeAllocSize(Ty); unsigned IdxN = getRegForGEPIndex(Idx); if (IdxN == 0) // Unhandled operand. Halt "fast" selection and bail. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat May 9 02:06:46 2009 @@ -3638,7 +3638,7 @@ // Increment the pointer, VAList, to the next vaarg Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList, DAG.getConstant(TLI.getTargetData()-> - getTypePaddedSize(VT.getTypeForMVT()), + getTypeAllocSize(VT.getTypeForMVT()), TLI.getPointerTy())); // Store the incremented VAList to the legalized pointer Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp Sat May 9 02:06:46 2009 @@ -295,7 +295,7 @@ Align = TM.getTargetData()->getPrefTypeAlignment(Type); if (Align == 0) { // Alignment of vector types. FIXME! - Align = TM.getTargetData()->getTypePaddedSize(Type); + Align = TM.getTargetData()->getTypeAllocSize(Type); } } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Sat May 9 02:06:46 2009 @@ -128,7 +128,7 @@ // Given an array type, recursively traverse the elements. if (const ArrayType *ATy = dyn_cast(Ty)) { const Type *EltTy = ATy->getElementType(); - uint64_t EltSize = TLI.getTargetData()->getTypePaddedSize(EltTy); + uint64_t EltSize = TLI.getTargetData()->getTypeAllocSize(EltTy); for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) ComputeValueVTs(TLI, EltTy, ValueVTs, Offsets, StartingOffset + i * EltSize); @@ -294,7 +294,7 @@ if (AllocaInst *AI = dyn_cast(I)) if (ConstantInt *CUI = dyn_cast(AI->getArraySize())) { const Type *Ty = AI->getAllocatedType(); - uint64_t TySize = TLI.getTargetData()->getTypePaddedSize(Ty); + uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty); unsigned Align = std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), AI->getAlignment()); @@ -2700,7 +2700,7 @@ if (ConstantInt *CI = dyn_cast(Idx)) { if (CI->getZExtValue() == 0) continue; uint64_t Offs = - TD->getTypePaddedSize(Ty)*cast(CI)->getSExtValue(); + TD->getTypeAllocSize(Ty)*cast(CI)->getSExtValue(); SDValue OffsVal; unsigned PtrBits = TLI.getPointerTy().getSizeInBits(); if (PtrBits < 64) { @@ -2715,7 +2715,7 @@ } // N = N + Idx * ElementSize; - uint64_t ElementSize = TD->getTypePaddedSize(Ty); + uint64_t ElementSize = TD->getTypeAllocSize(Ty); SDValue IdxN = getValue(Idx); // If the index is smaller or larger than intptr_t, truncate or extend @@ -2756,7 +2756,7 @@ return; // getValue will auto-populate this. const Type *Ty = I.getAllocatedType(); - uint64_t TySize = TLI.getTargetData()->getTypePaddedSize(Ty); + uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty); unsigned Align = std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), I.getAlignment()); @@ -5199,7 +5199,7 @@ // Otherwise, create a stack slot and emit a store to it before the // asm. const Type *Ty = OpVal->getType(); - uint64_t TySize = TLI.getTargetData()->getTypePaddedSize(Ty); + uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty); unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty); MachineFunction &MF = DAG.getMachineFunction(); int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align); @@ -5500,7 +5500,7 @@ // i32-ness of the optimizer: we do not want to promote to i64 and then // multiply on 64-bit targets. // FIXME: Malloc inst should go away: PR715. - uint64_t ElementSize = TD->getTypePaddedSize(I.getType()->getElementType()); + uint64_t ElementSize = TD->getTypeAllocSize(I.getType()->getElementType()); if (ElementSize != 1) Src = DAG.getNode(ISD::MUL, getCurDebugLoc(), Src.getValueType(), Src, DAG.getConstant(ElementSize, Src.getValueType())); @@ -5614,7 +5614,7 @@ const PointerType *Ty = cast(I->getType()); const Type *ElementTy = Ty->getElementType(); unsigned FrameAlign = getByValTypeAlignment(ElementTy); - unsigned FrameSize = getTargetData()->getTypePaddedSize(ElementTy); + unsigned FrameSize = getTargetData()->getTypeAllocSize(ElementTy); // For ByVal, alignment should be passed from FE. BE will guess if // this info is not there but there are cases it cannot get right. if (F.getParamAlignment(j)) @@ -5747,7 +5747,7 @@ const PointerType *Ty = cast(Args[i].Ty); const Type *ElementTy = Ty->getElementType(); unsigned FrameAlign = getByValTypeAlignment(ElementTy); - unsigned FrameSize = getTargetData()->getTypePaddedSize(ElementTy); + unsigned FrameSize = getTargetData()->getTypeAllocSize(ElementTy); // For ByVal, alignment should come from FE. BE will guess if this // info is not there but there are cases it cannot get right. if (Args[i].Alignment) Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackProtector.cpp (original) +++ llvm/trunk/lib/CodeGen/StackProtector.cpp Sat May 9 02:06:46 2009 @@ -114,7 +114,7 @@ if (const ArrayType *AT = dyn_cast(AI->getAllocatedType())) // If an array has more than SSPBufferSize bytes of allocated space, // then we emit stack protectors. - if (SSPBufferSize <= TD->getTypePaddedSize(AT)) + if (SSPBufferSize <= TD->getTypeAllocSize(AT)) return true; } } Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Sat May 9 02:06:46 2009 @@ -55,7 +55,7 @@ char* ExecutionEngine::getMemoryForGV(const GlobalVariable* GV) { const Type *ElTy = GV->getType()->getElementType(); - size_t GVSize = (size_t)getTargetData()->getTypePaddedSize(ElTy); + size_t GVSize = (size_t)getTargetData()->getTypeAllocSize(ElTy); return new char[GVSize]; } @@ -848,16 +848,16 @@ return; } else if (const ConstantVector *CP = dyn_cast(Init)) { unsigned ElementSize = - getTargetData()->getTypePaddedSize(CP->getType()->getElementType()); + getTargetData()->getTypeAllocSize(CP->getType()->getElementType()); for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) InitializeMemory(CP->getOperand(i), (char*)Addr+i*ElementSize); return; } else if (isa(Init)) { - memset(Addr, 0, (size_t)getTargetData()->getTypePaddedSize(Init->getType())); + memset(Addr, 0, (size_t)getTargetData()->getTypeAllocSize(Init->getType())); return; } else if (const ConstantArray *CPA = dyn_cast(Init)) { unsigned ElementSize = - getTargetData()->getTypePaddedSize(CPA->getType()->getElementType()); + getTargetData()->getTypeAllocSize(CPA->getType()->getElementType()); for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i) InitializeMemory(CPA->getOperand(i), (char*)Addr+i*ElementSize); return; @@ -1004,7 +1004,7 @@ InitializeMemory(GV->getInitializer(), GA); const Type *ElTy = GV->getType()->getElementType(); - size_t GVSize = (size_t)getTargetData()->getTypePaddedSize(ElTy); + size_t GVSize = (size_t)getTargetData()->getTypeAllocSize(ElTy); NumInitBytes += (unsigned)GVSize; ++NumGlobals; } Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp Sat May 9 02:06:46 2009 @@ -750,7 +750,7 @@ unsigned NumElements = getOperandValue(I.getOperand(0), SF).IntVal.getZExtValue(); - unsigned TypeSize = (size_t)TD.getTypePaddedSize(Ty); + unsigned TypeSize = (size_t)TD.getTypeAllocSize(Ty); // Avoid malloc-ing zero bytes, use max()... unsigned MemToAlloc = std::max(1U, NumElements * TypeSize); @@ -810,7 +810,7 @@ assert(BitWidth == 64 && "Invalid index type for getelementptr"); Idx = (int64_t)IdxGV.IntVal.getZExtValue(); } - Total += TD.getTypePaddedSize(ST->getElementType())*Idx; + Total += TD.getTypeAllocSize(ST->getElementType())*Idx; } } Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Sat May 9 02:06:46 2009 @@ -632,7 +632,7 @@ // emit it into memory. It goes in the same array as the generated // code, jump tables, etc. const Type *GlobalType = GV->getType()->getElementType(); - size_t S = getTargetData()->getTypePaddedSize(GlobalType); + size_t S = getTargetData()->getTypeAllocSize(GlobalType); size_t A = getTargetData()->getPreferredAlignment(GV); if (GV->isThreadLocal()) { MutexGuard locked(lock); @@ -687,7 +687,7 @@ /// char* JIT::getMemoryForGV(const GlobalVariable* GV) { const Type *ElTy = GV->getType()->getElementType(); - size_t GVSize = (size_t)getTargetData()->getTypePaddedSize(ElTy); + size_t GVSize = (size_t)getTargetData()->getTypeAllocSize(ElTy); if (GV->isThreadLocal()) { MutexGuard locked(lock); return TJI.allocateThreadLocalMemory(GVSize); Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Sat May 9 02:06:46 2009 @@ -809,7 +809,7 @@ unsigned AlignMask = CPE.getAlignment() - 1; Size = (Size + AlignMask) & ~AlignMask; const Type *Ty = CPE.getType(); - Size += TD->getTypePaddedSize(Ty); + Size += TD->getTypeAllocSize(Ty); } return Size; } @@ -838,7 +838,7 @@ unsigned JITEmitter::addSizeOfGlobal(const GlobalVariable *GV, unsigned Size) { const Type *ElTy = GV->getType()->getElementType(); - size_t GVSize = (size_t)TheJIT->getTargetData()->getTypePaddedSize(ElTy); + size_t GVSize = (size_t)TheJIT->getTargetData()->getTypeAllocSize(ElTy); size_t GVAlign = (size_t)TheJIT->getTargetData()->getPreferredAlignment(GV); DOUT << "JIT: Adding in size " << GVSize << " alignment " << GVAlign; @@ -1322,7 +1322,7 @@ << std::hex << CAddr << std::dec << "]\n"; const Type *Ty = CPE.Val.ConstVal->getType(); - Offset += TheJIT->getTargetData()->getTypePaddedSize(Ty); + Offset += TheJIT->getTargetData()->getTypeAllocSize(Ty); } } Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Sat May 9 02:06:46 2009 @@ -295,7 +295,7 @@ const TargetData &TD = *Fn.getTarget().getTargetData(); for (unsigned i = 0, e = CPs.size(); i != e; ++i) { - unsigned Size = TD.getTypePaddedSize(CPs[i].getType()); + unsigned Size = TD.getTypeAllocSize(CPs[i].getType()); // Verify that all constant pool entries are a multiple of 4 bytes. If not, // we would have to pad them out or something so that instructions stay // aligned. Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Sat May 9 02:06:46 2009 @@ -838,7 +838,7 @@ std::string name = Mang->getValueName(GVar); Constant *C = GVar->getInitializer(); const Type *Type = C->getType(); - unsigned Size = TD->getTypePaddedSize(Type); + unsigned Size = TD->getTypeAllocSize(Type); unsigned Align = TD->getPreferredAlignmentLog(GVar); bool isDarwin = Subtarget->isTargetDarwin(); Modified: llvm/trunk/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp Sat May 9 02:06:46 2009 @@ -224,7 +224,7 @@ std::string name = Mang->getValueName(GVar); Constant *C = GVar->getInitializer(); - unsigned Size = TD->getTypePaddedSize(C->getType()); + unsigned Size = TD->getTypeAllocSize(C->getType()); unsigned Align = TD->getPreferredAlignmentLog(GVar); // 0: Switch to section Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Sat May 9 02:06:46 2009 @@ -497,7 +497,7 @@ const VectorType *VTy = cast(Ty); return printSimpleType(Out, VTy->getElementType(), isSigned, " __attribute__((vector_size(" + - utostr(TD->getTypePaddedSize(VTy)) + " ))) " + NameSoFar); + utostr(TD->getTypeAllocSize(VTy)) + " ))) " + NameSoFar); } default: @@ -542,7 +542,7 @@ const VectorType *VTy = cast(Ty); return printSimpleType(Out, VTy->getElementType(), isSigned, " __attribute__((vector_size(" + - utostr(TD->getTypePaddedSize(VTy)) + " ))) " + NameSoFar); + utostr(TD->getTypeAllocSize(VTy)) + " ))) " + NameSoFar); } default: Modified: llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp Sat May 9 02:06:46 2009 @@ -530,7 +530,7 @@ Constant *C = GVar->getInitializer(); const Type *Type = C->getType(); - unsigned Size = TD->getTypePaddedSize(Type); + unsigned Size = TD->getTypeAllocSize(Type); unsigned Align = TD->getPreferredAlignmentLog(GVar); SwitchToSection(TAI->SectionForGlobal(GVar)); Modified: llvm/trunk/lib/Target/DarwinTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/DarwinTargetAsmInfo.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/DarwinTargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/DarwinTargetAsmInfo.cpp Sat May 9 02:06:46 2009 @@ -117,7 +117,7 @@ Constant *C = cast(GV)->getInitializer(); const Type *Ty = cast(C->getType())->getElementType(); - unsigned Size = TD->getTypePaddedSize(Ty); + unsigned Size = TD->getTypeAllocSize(Ty); if (Size) { unsigned Align = TD->getPreferredAlignment(GV); if (Align <= 32) @@ -138,7 +138,7 @@ DarwinTargetAsmInfo::MergeableConstSection(const Type *Ty) const { const TargetData *TD = TM.getTargetData(); - unsigned Size = TD->getTypePaddedSize(Ty); + unsigned Size = TD->getTypeAllocSize(Ty); if (Size == 4) return FourByteConstantSection; else if (Size == 8) Modified: llvm/trunk/lib/Target/ELFTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ELFTargetAsmInfo.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/ELFTargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/ELFTargetAsmInfo.cpp Sat May 9 02:06:46 2009 @@ -151,7 +151,7 @@ // FIXME: string here is temporary, until stuff will fully land in. // We cannot use {Four,Eight,Sixteen}ByteConstantSection here, since it's // currently directly used by asmprinter. - unsigned Size = TD->getTypePaddedSize(Ty); + unsigned Size = TD->getTypeAllocSize(Ty); if (Size == 4 || Size == 8 || Size == 16) { std::string Name = ".rodata.cst" + utostr(Size); @@ -169,7 +169,7 @@ Constant *C = cast(GV)->getInitializer(); const Type *Ty = cast(C->getType())->getElementType(); - unsigned Size = TD->getTypePaddedSize(Ty); + unsigned Size = TD->getTypeAllocSize(Ty); if (Size <= 16) { assert(getCStringSection() && "Should have string section prefix"); Modified: llvm/trunk/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp Sat May 9 02:06:46 2009 @@ -269,7 +269,7 @@ O << "\n\n"; std::string name = Mang->getValueName(GVar); Constant *C = GVar->getInitializer(); - unsigned Size = TD->getTypePaddedSize(C->getType()); + unsigned Size = TD->getTypeAllocSize(C->getType()); unsigned Align = TD->getPreferredAlignmentLog(GVar); printVisibility(name, GVar->getVisibility()); Modified: llvm/trunk/lib/Target/MSIL/MSILWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSIL/MSILWriter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSIL/MSILWriter.cpp (original) +++ llvm/trunk/lib/Target/MSIL/MSILWriter.cpp Sat May 9 02:06:46 2009 @@ -385,7 +385,7 @@ case Type::DoubleTyID: return "r8"; case Type::PointerTyID: - return "i"+utostr(TD->getTypePaddedSize(Ty)); + return "i"+utostr(TD->getTypeAllocSize(Ty)); default: cerr << "TypeID = " << Ty->getTypeID() << '\n'; assert(0 && "Invalid type in TypeToPostfix()"); @@ -695,14 +695,14 @@ uint64_t FieldIndex = cast(IndexValue)->getZExtValue(); // Offset is the sum of all previous structure fields. for (uint64_t F = 0; FgetTypePaddedSize(StrucTy->getContainedType((unsigned)F)); + Size += TD->getTypeAllocSize(StrucTy->getContainedType((unsigned)F)); printPtrLoad(Size); printSimpleInstruction("add"); continue; } else if (const SequentialType* SeqTy = dyn_cast(*I)) { - Size = TD->getTypePaddedSize(SeqTy->getElementType()); + Size = TD->getTypeAllocSize(SeqTy->getElementType()); } else { - Size = TD->getTypePaddedSize(*I); + Size = TD->getTypeAllocSize(*I); } // Add offset of current element to stack top. if (!isZeroValue(IndexValue)) { @@ -1027,7 +1027,7 @@ void MSILWriter::printAllocaInstruction(const AllocaInst* Inst) { - uint64_t Size = TD->getTypePaddedSize(Inst->getAllocatedType()); + uint64_t Size = TD->getTypeAllocSize(Inst->getAllocatedType()); // Constant optimization. if (const ConstantInt* CInt = dyn_cast(Inst->getOperand(0))) { printPtrLoad(CInt->getZExtValue()*Size); @@ -1443,7 +1443,7 @@ // Print not duplicated type if (Printed.insert(Ty).second) { Out << ".class value explicit ansi sealed '" << Name << "'"; - Out << " { .pack " << 1 << " .size " << TD->getTypePaddedSize(Ty); + Out << " { .pack " << 1 << " .size " << TD->getTypeAllocSize(Ty); Out << " }\n\n"; } } @@ -1473,7 +1473,7 @@ const Type* Ty = C->getType(); // Print zero initialized constant. if (isa(C) || C->isNullValue()) { - TySize = TD->getTypePaddedSize(C->getType()); + TySize = TD->getTypeAllocSize(C->getType()); Offset += TySize; Out << "int8 (0) [" << TySize << "]"; return; @@ -1481,14 +1481,14 @@ // Print constant initializer switch (Ty->getTypeID()) { case Type::IntegerTyID: { - TySize = TD->getTypePaddedSize(Ty); + TySize = TD->getTypeAllocSize(Ty); const ConstantInt* Int = cast(C); Out << getPrimitiveTypeName(Ty,true) << "(" << Int->getSExtValue() << ")"; break; } case Type::FloatTyID: case Type::DoubleTyID: { - TySize = TD->getTypePaddedSize(Ty); + TySize = TD->getTypeAllocSize(Ty); const ConstantFP* FP = cast(C); if (Ty->getTypeID() == Type::FloatTyID) Out << "int32 (" << @@ -1507,7 +1507,7 @@ } break; case Type::PointerTyID: - TySize = TD->getTypePaddedSize(C->getType()); + TySize = TD->getTypeAllocSize(C->getType()); // Initialize with global variable address if (const GlobalVariable *G = dyn_cast(C)) { std::string name = getValueName(G); Modified: llvm/trunk/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp Sat May 9 02:06:46 2009 @@ -484,7 +484,7 @@ std::string name = Mang->getValueName(GVar); Constant *C = GVar->getInitializer(); const Type *CTy = C->getType(); - unsigned Size = TD->getTypePaddedSize(CTy); + unsigned Size = TD->getTypeAllocSize(CTy); const ConstantArray *CVA = dyn_cast(C); bool printSizeAndType = true; Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Sat May 9 02:06:46 2009 @@ -210,7 +210,7 @@ return false; const Type *Ty = GV->getType()->getElementType(); - unsigned Size = TD->getTypePaddedSize(Ty); + unsigned Size = TD->getTypeAllocSize(Ty); // if this is a internal constant string, there is a special // section for it, but not in small data/bss. @@ -551,7 +551,7 @@ // hacking it. This feature should come soon so we can uncomment the // stuff below. //if (!Subtarget->hasABICall() && - // IsInSmallSection(getTargetData()->getTypePaddedSize(C->getType()))) { + // IsInSmallSection(getTargetData()->getTypeAllocSize(C->getType()))) { // SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, MVT::i32, CP); // SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32); // ResNode = DAG.getNode(ISD::ADD, MVT::i32, GOT, GPRelNode); Modified: llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp Sat May 9 02:06:46 2009 @@ -66,7 +66,7 @@ if (isa(GV)) { const TargetData *TD = TM.getTargetData(); - unsigned Size = TD->getTypePaddedSize(GV->getType()->getElementType()); + unsigned Size = TD->getTypeAllocSize(GV->getType()->getElementType()); unsigned Threshold = Subtarget->getSSectionThreshold(); if (Size > 0 && Size <= Threshold) { Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp Sat May 9 02:06:46 2009 @@ -286,7 +286,7 @@ const Type *RetType = F->getReturnType(); unsigned RetSize = 0; if (RetType->getTypeID() != Type::VoidTyID) - RetSize = TD->getTypePaddedSize(RetType); + RetSize = TD->getTypeAllocSize(RetType); //Emit function return value space if(RetSize > 0) @@ -300,7 +300,7 @@ for (Function::const_arg_iterator argi = F->arg_begin(), arge = F->arg_end(); argi != arge ; ++argi) { const Type *Ty = argi->getType(); - ArgSize += TD->getTypePaddedSize(Ty); + ArgSize += TD->getTypeAllocSize(Ty); } O << FunctionLabelBegin << CurrentFnName << ".args. RES " << ArgSize << "\n"; @@ -340,7 +340,7 @@ I->setSection("fadata." + CurrentFnName + ".#"); Constant *C = I->getInitializer(); const Type *Ty = C->getType(); - unsigned Size = TD->getTypePaddedSize(Ty); + unsigned Size = TD->getTypeAllocSize(Ty); FrameSize += Size; // Emit memory reserve directive. O << FunctionLabelBegin << VarName << " RES " << Size << "\n"; @@ -374,7 +374,7 @@ std::string Name = Mang->getValueName(Items[j]); Constant *C = Items[j]->getInitializer(); const Type *Ty = C->getType(); - unsigned Size = TD->getTypePaddedSize(Ty); + unsigned Size = TD->getTypeAllocSize(Ty); O << Name << " " <<"RES"<< " " << Size ; O << "\n"; Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp Sat May 9 02:06:46 2009 @@ -72,7 +72,7 @@ // Find how much space this global needs. const TargetData *TD = TM.getTargetData(); const Type *Ty = C->getType(); - unsigned ValSize = TD->getTypePaddedSize(Ty); + unsigned ValSize = TD->getTypeAllocSize(Ty); // Go through all BSS Sections and assign this variable // to the first available section having enough space. @@ -118,7 +118,7 @@ // Find how much space this global needs. const TargetData *TD = TM.getTargetData(); const Type *Ty = C->getType(); - unsigned ValSize = TD->getTypePaddedSize(Ty); + unsigned ValSize = TD->getTypeAllocSize(Ty); // Go through all IDATA Sections and assign this variable // to the first available section having enough space. Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Sat May 9 02:06:46 2009 @@ -687,7 +687,7 @@ Constant *C = GVar->getInitializer(); const Type *Type = C->getType(); - unsigned Size = TD->getTypePaddedSize(Type); + unsigned Size = TD->getTypeAllocSize(Type); unsigned Align = TD->getPreferredAlignmentLog(GVar); SwitchToSection(TAI->SectionForGlobal(GVar)); @@ -927,7 +927,7 @@ Constant *C = GVar->getInitializer(); const Type *Type = C->getType(); - unsigned Size = TD->getTypePaddedSize(Type); + unsigned Size = TD->getTypeAllocSize(Type); unsigned Align = TD->getPreferredAlignmentLog(GVar); SwitchToSection(TAI->SectionForGlobal(GVar)); Modified: llvm/trunk/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp Sat May 9 02:06:46 2009 @@ -253,7 +253,7 @@ O << "\n\n"; std::string name = Mang->getValueName(GVar); Constant *C = GVar->getInitializer(); - unsigned Size = TD->getTypePaddedSize(C->getType()); + unsigned Size = TD->getTypeAllocSize(C->getType()); unsigned Align = TD->getPreferredAlignment(GVar); printVisibility(name, GVar->getVisibility()); Modified: llvm/trunk/lib/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Target.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/Target.cpp (original) +++ llvm/trunk/lib/Target/Target.cpp Sat May 9 02:06:46 2009 @@ -53,7 +53,7 @@ } unsigned long long LLVMABISizeOfType(LLVMTargetDataRef TD, LLVMTypeRef Ty) { - return unwrap(TD)->getTypePaddedSize(unwrap(Ty)); + return unwrap(TD)->getTypeAllocSize(unwrap(Ty)); } unsigned LLVMABIAlignmentOfType(LLVMTargetDataRef TD, LLVMTypeRef Ty) { Modified: llvm/trunk/lib/Target/TargetData.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetData.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetData.cpp (original) +++ llvm/trunk/lib/Target/TargetData.cpp Sat May 9 02:06:46 2009 @@ -58,7 +58,7 @@ StructAlignment = std::max(TyAlign, StructAlignment); MemberOffsets[i] = StructSize; - StructSize += TD.getTypePaddedSize(Ty); // Consume space for this data item + StructSize += TD.getTypeAllocSize(Ty); // Consume space for this data item } // Empty structures have alignment of 1 byte. @@ -425,7 +425,7 @@ return getPointerSizeInBits(); case Type::ArrayTyID: { const ArrayType *ATy = cast(Ty); - return getTypePaddedSizeInBits(ATy->getElementType())*ATy->getNumElements(); + return getTypeAllocSizeInBits(ATy->getElementType())*ATy->getNumElements(); } case Type::StructTyID: // Get the layout annotation... which is lazily created on demand. @@ -568,7 +568,7 @@ // Get the array index and the size of each array element. int64_t arrayIdx = cast(Indices[CurIDX])->getSExtValue(); - Result += arrayIdx * (int64_t)getTypePaddedSize(Ty); + Result += arrayIdx * (int64_t)getTypeAllocSize(Ty); } } Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp Sat May 9 02:06:46 2009 @@ -76,7 +76,7 @@ Ty = cast(Ty)->getElementType(); // Size should be aligned to DWORD boundary - Size += ((TD->getTypePaddedSize(Ty) + 3)/4)*4; + Size += ((TD->getTypeAllocSize(Ty) + 3)/4)*4; } // We're not supporting tooooo huge arguments :) @@ -811,7 +811,7 @@ std::string name = Mang->getValueName(GVar); Constant *C = GVar->getInitializer(); const Type *Type = C->getType(); - unsigned Size = TD->getTypePaddedSize(Type); + unsigned Size = TD->getTypeAllocSize(Type); unsigned Align = TD->getPreferredAlignmentLog(GVar); printVisibility(name, GVar->getVisibility()); Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp Sat May 9 02:06:46 2009 @@ -59,7 +59,7 @@ Ty = cast(Ty)->getElementType(); // Size should be aligned to DWORD boundary - Size += ((TD->getTypePaddedSize(Ty) + 3)/4)*4; + Size += ((TD->getTypeAllocSize(Ty) + 3)/4)*4; } // We're not supporting tooooo huge arguments :) Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Sat May 9 02:06:46 2009 @@ -393,7 +393,7 @@ unsigned Idx = cast(Op)->getZExtValue(); Disp += SL->getElementOffset(Idx); } else { - uint64_t S = TD.getTypePaddedSize(GTI.getIndexedType()); + uint64_t S = TD.getTypeAllocSize(GTI.getIndexedType()); if (ConstantInt *CI = dyn_cast(Op)) { // Constant-offset addressing. Disp += CI->getSExtValue() * S; @@ -1490,7 +1490,7 @@ unsigned Align = TD.getPrefTypeAlignment(C->getType()); if (Align == 0) { // Alignment of vector types. FIXME! - Align = TD.getTypePaddedSize(C->getType()); + Align = TD.getTypeAllocSize(C->getType()); } // x86-32 PIC requires a PIC base register for constant pools. Modified: llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp Sat May 9 02:06:46 2009 @@ -220,7 +220,7 @@ EmitAlignment(Align, GV, 2); - unsigned Size = TD->getTypePaddedSize(C->getType()); + unsigned Size = TD->getTypeAllocSize(C->getType()); if (GV->isThreadLocal()) { Size *= MaxThreads; } Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original) +++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Sat May 9 02:06:46 2009 @@ -270,7 +270,7 @@ } SDValue base = getGlobalAddressWrapper(GA, GV, DAG); const TargetData *TD = TM.getTargetData(); - unsigned Size = TD->getTypePaddedSize(Ty); + unsigned Size = TD->getTypeAllocSize(Ty); SDValue offset = DAG.getNode(ISD::MUL, dl, MVT::i32, BuildGetId(DAG, dl), DAG.getConstant(Size, MVT::i32)); return DAG.getNode(ISD::ADD, dl, MVT::i32, base, offset); Modified: llvm/trunk/lib/Target/XCore/XCoreTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreTargetAsmInfo.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreTargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/XCore/XCoreTargetAsmInfo.cpp Sat May 9 02:06:46 2009 @@ -106,7 +106,7 @@ XCoreTargetAsmInfo::MergeableConstSection(const Type *Ty) const { const TargetData *TD = TM.getTargetData(); - unsigned Size = TD->getTypePaddedSize(Ty); + unsigned Size = TD->getTypeAllocSize(Ty); if (Size == 4 || Size == 8 || Size == 16) { std::string Name = ".cp.const" + utostr(Size); Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sat May 9 02:06:46 2009 @@ -513,7 +513,7 @@ return 0; // It's not worth it. NewGlobals.reserve(NumElements); - uint64_t EltSize = TD.getTypePaddedSize(STy->getElementType()); + uint64_t EltSize = TD.getTypeAllocSize(STy->getElementType()); unsigned EltAlign = TD.getABITypeAlignment(STy->getElementType()); for (unsigned i = 0, e = NumElements; i != e; ++i) { Constant *In = getAggregateConstantElement(Init, @@ -1448,7 +1448,7 @@ // (2048 bytes currently), as we don't want to introduce a 16M global or // something. if (NElements->getZExtValue()* - TD.getTypePaddedSize(MI->getAllocatedType()) < 2048) { + TD.getTypeAllocSize(MI->getAllocatedType()) < 2048) { GVI = OptimizeGlobalAddressOfMalloc(GV, MI); return true; } Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Sat May 9 02:06:46 2009 @@ -305,11 +305,11 @@ if (AllocaInst* A = dyn_cast(*I)) { if (ConstantInt* C = dyn_cast(A->getArraySize())) pointerSize = C->getZExtValue() * - TD.getTypePaddedSize(A->getAllocatedType()); + TD.getTypeAllocSize(A->getAllocatedType()); } else { const PointerType* PT = cast( cast(*I)->getType()); - pointerSize = TD.getTypePaddedSize(PT->getElementType()); + pointerSize = TD.getTypeAllocSize(PT->getElementType()); } // See if the call site touches it @@ -382,10 +382,10 @@ if (AllocaInst* A = dyn_cast(*I)) { if (ConstantInt* C = dyn_cast(A->getArraySize())) pointerSize = C->getZExtValue() * - TD.getTypePaddedSize(A->getAllocatedType()); + TD.getTypeAllocSize(A->getAllocatedType()); } else { const PointerType* PT = cast(cast(*I)->getType()); - pointerSize = TD.getTypePaddedSize(PT->getElementType()); + pointerSize = TD.getTypeAllocSize(PT->getElementType()); } // See if this pointer could alias it Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sat May 9 02:06:46 2009 @@ -5202,7 +5202,7 @@ for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e; ++i, ++GTI) { Value *Op = *i; - uint64_t Size = TD.getTypePaddedSize(GTI.getIndexedType()) & PtrSizeMask; + uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask; if (ConstantInt *OpC = dyn_cast(Op)) { if (OpC->isZero()) continue; @@ -5294,7 +5294,7 @@ if (const StructType *STy = dyn_cast(*GTI)) { Offset += TD.getStructLayout(STy)->getElementOffset(CI->getZExtValue()); } else { - uint64_t Size = TD.getTypePaddedSize(GTI.getIndexedType()); + uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()); Offset += Size*CI->getSExtValue(); } } else { @@ -5310,7 +5310,7 @@ Value *VariableIdx = GEP->getOperand(i); // Determine the scale factor of the variable element. For example, this is // 4 if the variable index is into an array of i32. - uint64_t VariableScale = TD.getTypePaddedSize(GTI.getIndexedType()); + uint64_t VariableScale = TD.getTypeAllocSize(GTI.getIndexedType()); // Verify that there are no other variable indices. If so, emit the hard way. for (++i, ++GTI; i != e; ++i, ++GTI) { @@ -5324,7 +5324,7 @@ if (const StructType *STy = dyn_cast(*GTI)) { Offset += TD.getStructLayout(STy)->getElementOffset(CI->getZExtValue()); } else { - uint64_t Size = TD.getTypePaddedSize(GTI.getIndexedType()); + uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()); Offset += Size*CI->getSExtValue(); } } @@ -7606,8 +7606,8 @@ if (!AI.hasOneUse() && !hasOneUsePlusDeclare(&AI) && CastElTyAlign == AllocElTyAlign) return 0; - uint64_t AllocElTySize = TD->getTypePaddedSize(AllocElTy); - uint64_t CastElTySize = TD->getTypePaddedSize(CastElTy); + uint64_t AllocElTySize = TD->getTypeAllocSize(AllocElTy); + uint64_t CastElTySize = TD->getTypeAllocSize(CastElTy); if (CastElTySize == 0 || AllocElTySize == 0) return 0; // See if we can satisfy the modulus by pulling a scale out of the array @@ -7905,7 +7905,7 @@ // is something like [0 x {int, int}] const Type *IntPtrTy = TD->getIntPtrType(); int64_t FirstIdx = 0; - if (int64_t TySize = TD->getTypePaddedSize(Ty)) { + if (int64_t TySize = TD->getTypeAllocSize(Ty)) { FirstIdx = Offset/TySize; Offset -= FirstIdx*TySize; @@ -7937,7 +7937,7 @@ Offset -= SL->getElementOffset(Elt); Ty = STy->getElementType(Elt); } else if (const ArrayType *AT = dyn_cast(Ty)) { - uint64_t EltSize = TD->getTypePaddedSize(AT->getElementType()); + uint64_t EltSize = TD->getTypeAllocSize(AT->getElementType()); assert(EltSize && "Cannot index into a zero-sized array"); NewIndices.push_back(ConstantInt::get(IntPtrTy,Offset/EltSize)); Offset %= EltSize; @@ -8687,7 +8687,7 @@ // is a single-index GEP. if (X->getType() == CI.getType()) { // Get the size of the pointee type. - uint64_t Size = TD->getTypePaddedSize(DestPointee); + uint64_t Size = TD->getTypeAllocSize(DestPointee); // Convert the constant to intptr type. APInt Offset = Cst->getValue(); @@ -8707,7 +8707,7 @@ // "inttoptr+GEP" instead of "add+intptr". // Get the size of the pointee type. - uint64_t Size = TD->getTypePaddedSize(DestPointee); + uint64_t Size = TD->getTypeAllocSize(DestPointee); // Convert the constant to intptr type. APInt Offset = Cst->getValue(); @@ -9811,7 +9811,7 @@ const Type* DstTy = cast(CI->getType())->getElementType(); if (!SrcTy->isSized() || !DstTy->isSized()) return false; - if (TD->getTypePaddedSize(SrcTy) != TD->getTypePaddedSize(DstTy)) + if (TD->getTypeAllocSize(SrcTy) != TD->getTypeAllocSize(DstTy)) return false; return true; } @@ -10966,8 +10966,8 @@ const Type *SrcElTy = cast(X->getType())->getElementType(); const Type *ResElTy=cast(PtrOp->getType())->getElementType(); if (isa(SrcElTy) && - TD->getTypePaddedSize(cast(SrcElTy)->getElementType()) == - TD->getTypePaddedSize(ResElTy)) { + TD->getTypeAllocSize(cast(SrcElTy)->getElementType()) == + TD->getTypeAllocSize(ResElTy)) { Value *Idx[2]; Idx[0] = Constant::getNullValue(Type::Int32Ty); Idx[1] = GEP.getOperand(1); @@ -10984,7 +10984,7 @@ if (isa(SrcElTy) && ResElTy == Type::Int8Ty) { uint64_t ArrayEltSize = - TD->getTypePaddedSize(cast(SrcElTy)->getElementType()); + TD->getTypeAllocSize(cast(SrcElTy)->getElementType()); // Check to see if "tmp" is a scale by a multiple of ArrayEltSize. We // allow either a mul, shift, or constant here. @@ -11137,7 +11137,7 @@ // If alloca'ing a zero byte object, replace the alloca with a null pointer. // Note that we only do this for alloca's, because malloc should allocate // and return a unique pointer, even for a zero byte allocation. - if (TD->getTypePaddedSize(AI.getAllocatedType()) == 0) + if (TD->getTypeAllocSize(AI.getAllocatedType()) == 0) return ReplaceInstUsesWith(AI, Constant::getNullValue(AI.getType())); // If the alignment is 0 (unspecified), assign it the preferred alignment. Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Sat May 9 02:06:46 2009 @@ -104,7 +104,7 @@ // Otherwise, we have a sequential type like an array or vector. Multiply // the index by the ElementSize. - uint64_t Size = TD.getTypePaddedSize(GTI.getIndexedType()); + uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()); Offset += Size*OpC->getSExtValue(); } @@ -511,7 +511,7 @@ if (!srcArraySize) return false; - uint64_t srcSize = TD.getTypePaddedSize(srcAlloca->getAllocatedType()) * + uint64_t srcSize = TD.getTypeAllocSize(srcAlloca->getAllocatedType()) * srcArraySize->getZExtValue(); if (cpyLength->getZExtValue() < srcSize) @@ -526,7 +526,7 @@ if (!destArraySize) return false; - uint64_t destSize = TD.getTypePaddedSize(A->getAllocatedType()) * + uint64_t destSize = TD.getTypeAllocSize(A->getAllocatedType()) * destArraySize->getZExtValue(); if (destSize < srcSize) @@ -538,7 +538,7 @@ return false; const Type* StructTy = cast(A->getType())->getElementType(); - uint64_t destSize = TD.getTypePaddedSize(StructTy); + uint64_t destSize = TD.getTypeAllocSize(StructTy); if (destSize < srcSize) return false; Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Sat May 9 02:06:46 2009 @@ -252,7 +252,7 @@ // transform the allocation instruction if it is an array allocation // (allocations OF arrays are ok though), and an allocation of a scalar // value cannot be decomposed at all. - uint64_t AllocaSize = TD->getTypePaddedSize(AI->getAllocatedType()); + uint64_t AllocaSize = TD->getTypeAllocSize(AI->getAllocatedType()); // Do not promote any struct whose size is too big. if (AllocaSize > SRThreshold) continue; @@ -601,7 +601,7 @@ // If not the whole aggregate, give up. if (Length->getZExtValue() != - TD->getTypePaddedSize(AI->getType()->getElementType())) + TD->getTypeAllocSize(AI->getType()->getElementType())) return MarkUnsafe(Info); // We only know about memcpy/memset/memmove. @@ -637,8 +637,8 @@ // cast a {i32,i32}* to i64* and store through it. This is similar to the // memcpy case and occurs in various "byval" cases and emulated memcpys. if (isa(SI->getOperand(0)->getType()) && - TD->getTypePaddedSize(SI->getOperand(0)->getType()) == - TD->getTypePaddedSize(AI->getType()->getElementType())) { + TD->getTypeAllocSize(SI->getOperand(0)->getType()) == + TD->getTypeAllocSize(AI->getType()->getElementType())) { Info.isMemCpyDst = true; continue; } @@ -652,8 +652,8 @@ // cast a {i32,i32}* to i64* and load through it. This is similar to the // memcpy case and occurs in various "byval" cases and emulated memcpys. if (isa(LI->getType()) && - TD->getTypePaddedSize(LI->getType()) == - TD->getTypePaddedSize(AI->getType()->getElementType())) { + TD->getTypeAllocSize(LI->getType()) == + TD->getTypeAllocSize(AI->getType()->getElementType())) { Info.isMemCpySrc = true; continue; } @@ -782,7 +782,7 @@ } else { const Type *EltTy = cast(OtherPtr->getType())->getElementType(); - EltOffset = TD->getTypePaddedSize(EltTy)*i; + EltOffset = TD->getTypeAllocSize(EltTy)*i; } // The alignment of the other pointer is the guaranteed alignment of the @@ -865,7 +865,7 @@ OtherElt = new BitCastInst(OtherElt, BytePtrTy,OtherElt->getNameStr(), MI); - unsigned EltSize = TD->getTypePaddedSize(EltTy); + unsigned EltSize = TD->getTypeAllocSize(EltTy); // Finally, insert the meminst for this element. if (isa(MI)) { @@ -899,7 +899,7 @@ // and store the element value to the individual alloca. Value *SrcVal = SI->getOperand(0); const Type *AllocaEltTy = AI->getType()->getElementType(); - uint64_t AllocaSizeBits = TD->getTypePaddedSizeInBits(AllocaEltTy); + uint64_t AllocaSizeBits = TD->getTypeAllocSizeInBits(AllocaEltTy); // If this isn't a store of an integer to the whole alloca, it may be a store // to the first element. Just ignore the store in this case and normal SROA @@ -922,7 +922,7 @@ uint64_t Shift = Layout->getElementOffsetInBits(i); if (TD->isBigEndian()) - Shift = AllocaSizeBits-Shift-TD->getTypePaddedSizeInBits(FieldTy); + Shift = AllocaSizeBits-Shift-TD->getTypeAllocSizeInBits(FieldTy); Value *EltVal = SrcVal; if (Shift) { @@ -957,7 +957,7 @@ } else { const ArrayType *ATy = cast(AllocaEltTy); const Type *ArrayEltTy = ATy->getElementType(); - uint64_t ElementOffset = TD->getTypePaddedSizeInBits(ArrayEltTy); + uint64_t ElementOffset = TD->getTypeAllocSizeInBits(ArrayEltTy); uint64_t ElementSizeBits = TD->getTypeSizeInBits(ArrayEltTy); uint64_t Shift; @@ -1012,7 +1012,7 @@ // Extract each element out of the NewElts according to its structure offset // and form the result value. const Type *AllocaEltTy = AI->getType()->getElementType(); - uint64_t AllocaSizeBits = TD->getTypePaddedSizeInBits(AllocaEltTy); + uint64_t AllocaSizeBits = TD->getTypeAllocSizeInBits(AllocaEltTy); // If this isn't a load of the whole alloca to an integer, it may be a load // of the first element. Just ignore the load in this case and normal SROA @@ -1032,7 +1032,7 @@ Layout = TD->getStructLayout(EltSTy); } else { const Type *ArrayEltTy = cast(AllocaEltTy)->getElementType(); - ArrayEltBitOffset = TD->getTypePaddedSizeInBits(ArrayEltTy); + ArrayEltBitOffset = TD->getTypeAllocSizeInBits(ArrayEltTy); } Value *ResultVal = Constant::getNullValue(LI->getType()); @@ -1126,7 +1126,7 @@ } else if (const VectorType *VTy = dyn_cast(Ty)) { return HasPadding(VTy->getElementType(), TD); } - return TD.getTypeSizeInBits(Ty) != TD.getTypePaddedSizeInBits(Ty); + return TD.getTypeSizeInBits(Ty) != TD.getTypeAllocSizeInBits(Ty); } /// isSafeStructAllocaToScalarRepl - Check to see if the specified allocation of @@ -1527,7 +1527,7 @@ // Otherwise it must be an element access. unsigned Elt = 0; if (Offset) { - unsigned EltSize = TD->getTypePaddedSizeInBits(VTy->getElementType()); + unsigned EltSize = TD->getTypeAllocSizeInBits(VTy->getElementType()); Elt = Offset/EltSize; assert(EltSize*Elt == Offset && "Invalid modulus in validity checking"); } @@ -1555,7 +1555,7 @@ } if (const ArrayType *AT = dyn_cast(ToType)) { - uint64_t EltSize = TD->getTypePaddedSizeInBits(AT->getElementType()); + uint64_t EltSize = TD->getTypeAllocSizeInBits(AT->getElementType()); Value *Res = UndefValue::get(AT); for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) { Value *Elt = ConvertScalar_ExtractValue(FromVal, AT->getElementType(), @@ -1630,15 +1630,15 @@ const Type *AllocaType = Old->getType(); if (const VectorType *VTy = dyn_cast(AllocaType)) { - uint64_t VecSize = TD->getTypePaddedSizeInBits(VTy); - uint64_t ValSize = TD->getTypePaddedSizeInBits(SV->getType()); + uint64_t VecSize = TD->getTypeAllocSizeInBits(VTy); + uint64_t ValSize = TD->getTypeAllocSizeInBits(SV->getType()); // Changing the whole vector with memset or with an access of a different // vector type? if (ValSize == VecSize) return Builder.CreateBitCast(SV, AllocaType, "tmp"); - uint64_t EltSize = TD->getTypePaddedSizeInBits(VTy->getElementType()); + uint64_t EltSize = TD->getTypeAllocSizeInBits(VTy->getElementType()); // Must be an element insertion. unsigned Elt = Offset/EltSize; @@ -1665,7 +1665,7 @@ } if (const ArrayType *AT = dyn_cast(SV->getType())) { - uint64_t EltSize = TD->getTypePaddedSizeInBits(AT->getElementType()); + uint64_t EltSize = TD->getTypeAllocSizeInBits(AT->getElementType()); for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) { Value *Elt = Builder.CreateExtractValue(SV, i, "tmp"); Old = ConvertScalar_InsertValue(Elt, Old, Offset+i*EltSize, Builder); Modified: llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp Sat May 9 02:06:46 2009 @@ -225,7 +225,7 @@ cast(AddrInst->getOperand(i))->getZExtValue(); ConstantOffset += SL->getElementOffset(Idx); } else { - uint64_t TypeSize = TD->getTypePaddedSize(GTI.getIndexedType()); + uint64_t TypeSize = TD->getTypeAllocSize(GTI.getIndexedType()); if (ConstantInt *CI = dyn_cast(AddrInst->getOperand(i))) { ConstantOffset += CI->getSExtValue()*TypeSize; } else if (TypeSize) { // Scales of zero don't do anything. Modified: llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp Sat May 9 02:06:46 2009 @@ -116,7 +116,7 @@ Value *MallocArg; if (LowerMallocArgToInteger) MallocArg = ConstantInt::get(Type::Int64Ty, - TD.getTypePaddedSize(AllocTy)); + TD.getTypeAllocSize(AllocTy)); else MallocArg = ConstantExpr::getSizeOf(AllocTy); MallocArg = ConstantExpr::getTruncOrBitCast(cast(MallocArg), Modified: llvm/trunk/utils/TableGen/CallingConvEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CallingConvEmitter.cpp?rev=71349&r1=71348&r2=71349&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CallingConvEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/CallingConvEmitter.cpp Sat May 9 02:06:46 2009 @@ -163,7 +163,7 @@ O << Size << ", "; else O << "\n" << IndentStr << " State.getTarget().getTargetData()" - "->getTypePaddedSize(LocVT.getTypeForMVT()), "; + "->getTypeAllocSize(LocVT.getTypeForMVT()), "; if (Align) O << Align; else From isanbard at gmail.com Sat May 9 02:24:00 2009 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 9 May 2009 00:24:00 -0700 Subject: [llvm-commits] [llvm] r71349 - in /llvm/trunk: bindings/ocaml/target/ include/llvm-c/ include/llvm/Target/ lib/Analysis/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/ExecutionEngine/ lib/ExecutionEngine/Interpreter/ lib/ExecutionEngine/JIT/ lib/Target/ lib/Target/ARM/ lib/Target/ARM/AsmPrinter/ lib/Target/Alpha/AsmPrinter/ lib/Target/CBackend/ lib/Target/CellSPU/AsmPrinter/ lib/Target/IA64/AsmPrinter/ lib/Target/MSIL/ lib/Target/Mips/ lib/Target/Mips/AsmPrinter/ lib/Target/PIC16/ lib/Target/PowerP... In-Reply-To: <200905090706.n4976n4F018353@zion.cs.uiuc.edu> References: <200905090706.n4976n4F018353@zion.cs.uiuc.edu> Message-ID: Duncan, Please make the appropriate changes in llvm-gcc. Thanks! -bw On May 9, 2009, at 12:06 AM, Duncan Sands wrote: > Author: baldrick > Date: Sat May 9 02:06:46 2009 > New Revision: 71349 > > URL: http://llvm.org/viewvc/llvm-project?rev=71349&view=rev > Log: > Rename PaddedSize to AllocSize, in the hope that this > will make it more obvious what it represents, and stop > it being confused with the StoreSize. > > Modified: > llvm/trunk/bindings/ocaml/target/llvm_target.mli > llvm/trunk/include/llvm-c/Target.h > llvm/trunk/include/llvm/Target/TargetData.h > llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp > llvm/trunk/lib/Analysis/ConstantFolding.cpp > llvm/trunk/lib/Analysis/ScalarEvolution.cpp > llvm/trunk/lib/Analysis/ValueTracking.cpp > llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp > llvm/trunk/lib/CodeGen/ELFWriter.cpp > llvm/trunk/lib/CodeGen/MachOWriter.cpp > llvm/trunk/lib/CodeGen/MachOWriter.h > llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp > llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp > llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp > llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp > llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp > llvm/trunk/lib/CodeGen/StackProtector.cpp > llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp > llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp > llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp > llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp > llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp > llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp > llvm/trunk/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp > llvm/trunk/lib/Target/CBackend/CBackend.cpp > llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp > llvm/trunk/lib/Target/DarwinTargetAsmInfo.cpp > llvm/trunk/lib/Target/ELFTargetAsmInfo.cpp > llvm/trunk/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp > llvm/trunk/lib/Target/MSIL/MSILWriter.cpp > llvm/trunk/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp > llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp > llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp > llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp > llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp > llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp > llvm/trunk/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp > llvm/trunk/lib/Target/Target.cpp > llvm/trunk/lib/Target/TargetData.cpp > llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp > llvm/trunk/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp > llvm/trunk/lib/Target/X86/X86FastISel.cpp > llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp > llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp > llvm/trunk/lib/Target/XCore/XCoreTargetAsmInfo.cpp > llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp > llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp > llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp > llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp > llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp > llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp > llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp > llvm/trunk/utils/TableGen/CallingConvEmitter.cpp > > Modified: llvm/trunk/bindings/ocaml/target/llvm_target.mli > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/target/llvm_target.mli?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/bindings/ocaml/target/llvm_target.mli (original) > +++ llvm/trunk/bindings/ocaml/target/llvm_target.mli Sat May 9 > 02:06:46 2009 > @@ -70,7 +70,7 @@ > external store_size : TargetData.t -> Llvm.lltype -> Int64.t = > "llvm_store_size" > > (** Computes the ABI size of a type in bytes for a target. > - See the method llvm::TargetData::getTypePaddedSize. *) > + See the method llvm::TargetData::getTypeAllocSize. *) > external abi_size : TargetData.t -> Llvm.lltype -> Int64.t = > "llvm_abi_size" > > (** Computes the ABI alignment of a type in bytes for a target. > > Modified: llvm/trunk/include/llvm-c/Target.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Target.h?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm-c/Target.h (original) > +++ llvm/trunk/include/llvm-c/Target.h Sat May 9 02:06:46 2009 > @@ -70,7 +70,7 @@ > unsigned long long LLVMStoreSizeOfType(LLVMTargetDataRef, > LLVMTypeRef); > > /** Computes the ABI size of a type in bytes for a target. > - See the method llvm::TargetData::getTypePaddedSize. */ > + See the method llvm::TargetData::getTypeAllocSize. */ > unsigned long long LLVMABISizeOfType(LLVMTargetDataRef, LLVMTypeRef); > > /** Computes the ABI alignment of a type in bytes for a target. > > Modified: llvm/trunk/include/llvm/Target/TargetData.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetData.h?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Target/TargetData.h (original) > +++ llvm/trunk/include/llvm/Target/TargetData.h Sat May 9 02:06:46 > 2009 > @@ -157,8 +157,8 @@ > > /// Size examples: > /// > - /// Type SizeInBits StoreSizeInBits PaddedSizeInBits[*] > - /// ---- ---------- --------------- ---------------- > + /// Type SizeInBits StoreSizeInBits AllocSizeInBits[*] > + /// ---- ---------- --------------- --------------- > /// i1 1 8 8 > /// i8 8 8 8 > /// i19 19 24 32 > @@ -169,7 +169,7 @@ > /// Double 64 64 64 > /// X86_FP80 80 80 96 > /// > - /// [*] The padded size depends on the alignment, and thus on the > target. > + /// [*] The alloc size depends on the alignment, and thus on the > target. > /// These values are for x86-32 linux. > > /// getTypeSizeInBits - Return the number of bits necessary to > hold the > @@ -190,21 +190,21 @@ > return 8*getTypeStoreSize(Ty); > } > > - /// getTypePaddedSize - Return the offset in bytes between > successive objects > + /// getTypeAllocSize - Return the offset in bytes between > successive objects > /// of the specified type, including alignment padding. This is > the amount > /// that alloca reserves for this type. For example, returns 12 > or 16 for > /// x86_fp80, depending on alignment. > - uint64_t getTypePaddedSize(const Type* Ty) const { > + uint64_t getTypeAllocSize(const Type* Ty) const { > // Round up to the next alignment boundary. > return RoundUpAlignment(getTypeStoreSize(Ty), > getABITypeAlignment(Ty)); > } > > - /// getTypePaddedSizeInBits - Return the offset in bits between > successive > + /// getTypeAllocSizeInBits - Return the offset in bits between > successive > /// objects of the specified type, including alignment padding; > always a > /// multiple of 8. This is the amount that alloca reserves for > this type. > /// For example, returns 96 or 128 for x86_fp80, depending on > alignment. > - uint64_t getTypePaddedSizeInBits(const Type* Ty) const { > - return 8*getTypePaddedSize(Ty); > + uint64_t getTypeAllocSizeInBits(const Type* Ty) const { > + return 8*getTypeAllocSize(Ty); > } > > /// getABITypeAlignment - Return the minimum ABI-required > alignment for the > > Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) > +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Sat May 9 > 02:06:46 2009 > @@ -123,7 +123,7 @@ > } > > if (AccessTy->isSized()) > - return TD.getTypePaddedSize(AccessTy) < Size; > + return TD.getTypeAllocSize(AccessTy) < Size; > return false; > } > > > Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) > +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Sat May 9 02:06:46 > 2009 > @@ -77,7 +77,7 @@ > Offset += TD.getStructLayout(ST)->getElementOffset(CI- > >getZExtValue()); > } else { > const SequentialType *SQT = cast(*GTI); > - Offset += TD.getTypePaddedSize(SQT->getElementType())*CI- > >getSExtValue(); > + Offset += TD.getTypeAllocSize(SQT->getElementType())*CI- > >getSExtValue(); > } > } > return true; > @@ -405,8 +405,8 @@ > if (const ArrayType *AT = > dyn_cast(GVTy->getElementType())) { > const Type *ElTy = AT->getElementType(); > - uint64_t PaddedSize = TD- > >getTypePaddedSize(ElTy); > - APInt PSA(L->getValue().getBitWidth(), > PaddedSize); > + uint64_t AllocSize = TD->getTypeAllocSize(ElTy); > + APInt PSA(L->getValue().getBitWidth(), > AllocSize); > if (ElTy == cast(DestTy)- > >getElementType() && > L->getValue().urem(PSA) == 0) { > APInt ElemIdx = L->getValue().udiv(PSA); > > Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) > +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Sat May 9 02:06:46 > 2009 > @@ -1961,7 +1961,7 @@ > IntPtrTy); > LocalOffset = > getMulExpr(LocalOffset, > - getIntegerSCEV(TD->getTypePaddedSize(*GTI), > + getIntegerSCEV(TD->getTypeAllocSize(*GTI), > IntPtrTy)); > TotalOffset = getAddExpr(TotalOffset, LocalOffset); > } > > Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Analysis/ValueTracking.cpp (original) > +++ llvm/trunk/lib/Analysis/ValueTracking.cpp Sat May 9 02:06:46 2009 > @@ -459,7 +459,7 @@ > const Type *IndexedTy = GTI.getIndexedType(); > if (!IndexedTy->isSized()) return; > unsigned GEPOpiBits = Index->getType()- > >getPrimitiveSizeInBits(); > - uint64_t TypeSize = TD ? TD->getTypePaddedSize(IndexedTy) : > 1; > + uint64_t TypeSize = TD ? TD->getTypeAllocSize(IndexedTy) : 1; > LocalMask = APInt::getAllOnesValue(GEPOpiBits); > LocalKnownZero = LocalKnownOne = APInt(GEPOpiBits, 0); > ComputeMaskedBits(Index, LocalMask, > > Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) > +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Sat May 9 > 02:06:46 2009 > @@ -313,7 +313,7 @@ > EmitZeros(NewOffset - Offset); > > const Type *Ty = CPE.getType(); > - Offset = NewOffset + TM.getTargetData()->getTypePaddedSize(Ty); > + Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty); > > O << TAI->getPrivateGlobalPrefix() << "CPI" << > getFunctionNumber() << '_' > << CPI << ":\t\t\t\t\t"; > @@ -889,12 +889,12 @@ > > // We can emit the pointer value into this slot if the slot is > an > // integer slot greater or equal to the size of the pointer. > - if (TD->getTypePaddedSize(Ty) >= TD->getTypePaddedSize(Op- > >getType())) > + if (TD->getTypeAllocSize(Ty) >= TD->getTypeAllocSize(Op- > >getType())) > return EmitConstantValueOnly(Op); > > O << "(("; > EmitConstantValueOnly(Op); > - APInt ptrMask = APInt::getAllOnesValue(TD- > >getTypePaddedSizeInBits(Ty)); > + APInt ptrMask = APInt::getAllOnesValue(TD- > >getTypeAllocSizeInBits(Ty)); > > SmallString<40> S; > ptrMask.toStringUnsigned(S); > @@ -992,14 +992,14 @@ > unsigned AddrSpace) { > // Print the fields in successive locations. Pad to align if needed! > const TargetData *TD = TM.getTargetData(); > - unsigned Size = TD->getTypePaddedSize(CVS->getType()); > + unsigned Size = TD->getTypeAllocSize(CVS->getType()); > const StructLayout *cvsLayout = TD->getStructLayout(CVS->getType()); > uint64_t sizeSoFar = 0; > for (unsigned i = 0, e = CVS->getNumOperands(); i != e; ++i) { > const Constant* field = CVS->getOperand(i); > > // Check if padding is needed and insert one or more 0s. > - uint64_t fieldSize = TD->getTypePaddedSize(field->getType()); > + uint64_t fieldSize = TD->getTypeAllocSize(field->getType()); > uint64_t padSize = ((i == e-1 ? Size : cvsLayout- > >getElementOffset(i+1)) > - cvsLayout->getElementOffset(i)) - fieldSize; > sizeSoFar += fieldSize + padSize; > @@ -1123,7 +1123,7 @@ > << " long double most significant halfword"; > O << '\n'; > } > - EmitZeros(TD->getTypePaddedSize(Type::X86_FP80Ty) - > + EmitZeros(TD->getTypeAllocSize(Type::X86_FP80Ty) - > TD->getTypeStoreSize(Type::X86_FP80Ty), AddrSpace); > return; > } else if (CFP->getType() == Type::PPC_FP128Ty) { > @@ -1228,7 +1228,7 @@ > void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned > AddrSpace) { > const TargetData *TD = TM.getTargetData(); > const Type *type = CV->getType(); > - unsigned Size = TD->getTypePaddedSize(type); > + unsigned Size = TD->getTypeAllocSize(type); > > if (CV->isNullValue() || isa(CV)) { > EmitZeros(Size, AddrSpace); > > Modified: llvm/trunk/lib/CodeGen/ELFWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFWriter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/ELFWriter.cpp (original) > +++ llvm/trunk/lib/CodeGen/ELFWriter.cpp Sat May 9 02:06:46 2009 > @@ -284,7 +284,7 @@ > > unsigned Align = TM.getTargetData()->getPreferredAlignment(GV); > unsigned Size = > - TM.getTargetData()->getTypePaddedSize(GV->getType()- > >getElementType()); > + TM.getTargetData()->getTypeAllocSize(GV->getType()- > >getElementType()); > > // If this global has a zero initializer, it is part of the .bss > or common > // section. > > Modified: llvm/trunk/lib/CodeGen/MachOWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachOWriter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/MachOWriter.cpp (original) > +++ llvm/trunk/lib/CodeGen/MachOWriter.cpp Sat May 9 02:06:46 2009 > @@ -281,7 +281,7 @@ > // "giant object for PIC" optimization. > for (unsigned i = 0, e = CP.size(); i != e; ++i) { > const Type *Ty = CP[i].getType(); > - unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty); > + unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty); > > MachOWriter::MachOSection *Sec = > MOW.getConstSection(CP[i].Val.ConstVal); > OutputBuffer SecDataOut(Sec->SectionData, is64Bit, > isLittleEndian); > @@ -355,7 +355,7 @@ > > void MachOWriter::AddSymbolToSection(MachOSection *Sec, > GlobalVariable *GV) { > const Type *Ty = GV->getType()->getElementType(); > - unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty); > + unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty); > unsigned Align = TM.getTargetData()->getPreferredAlignment(GV); > > // Reserve space in the .bss section for this symbol while > maintaining the > @@ -400,7 +400,7 @@ > > void MachOWriter::EmitGlobal(GlobalVariable *GV) { > const Type *Ty = GV->getType()->getElementType(); > - unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty); > + unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty); > bool NoInit = !GV->hasInitializer(); > > // If this global has a zero initializer, it is part of the .bss > or common > @@ -825,7 +825,7 @@ > continue; > } else if (const ConstantVector *CP = > dyn_cast(PC)) { > unsigned ElementSize = > - TD->getTypePaddedSize(CP->getType()->getElementType()); > + TD->getTypeAllocSize(CP->getType()->getElementType()); > for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) > WorkList.push_back(CPair(CP->getOperand(i), PA > +i*ElementSize)); > } else if (const ConstantExpr *CE = dyn_cast(PC)) { > @@ -926,10 +926,10 @@ > abort(); > } > } else if (isa(PC)) { > - memset((void*)PA, 0, (size_t)TD->getTypePaddedSize(PC- > >getType())); > + memset((void*)PA, 0, (size_t)TD->getTypeAllocSize(PC- > >getType())); > } else if (const ConstantArray *CPA = > dyn_cast(PC)) { > unsigned ElementSize = > - TD->getTypePaddedSize(CPA->getType()->getElementType()); > + TD->getTypeAllocSize(CPA->getType()->getElementType()); > for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i) > WorkList.push_back(CPair(CPA->getOperand(i), PA > +i*ElementSize)); > } else if (const ConstantStruct *CPS = > dyn_cast(PC)) { > > Modified: llvm/trunk/lib/CodeGen/MachOWriter.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachOWriter.h?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/MachOWriter.h (original) > +++ llvm/trunk/lib/CodeGen/MachOWriter.h Sat May 9 02:06:46 2009 > @@ -468,7 +468,7 @@ > > const Type *Ty = C->getType(); > if (Ty->isPrimitiveType() || Ty->isInteger()) { > - unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty); > + unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty); > switch(Size) { > default: break; // Fall through to __TEXT,__const > case 4: > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sat May 9 > 02:06:46 2009 > @@ -5694,7 +5694,7 @@ > // Get the offsets to the 0 and 1 element of the array so > that we can > // select between them. > SDValue Zero = DAG.getIntPtrConstant(0); > - unsigned EltSize = (unsigned)TD.getTypePaddedSize(Elts[0]- > >getType()); > + unsigned EltSize = (unsigned)TD.getTypeAllocSize(Elts[0]- > >getType()); > SDValue One = DAG.getIntPtrConstant(EltSize); > > SDValue Cond = DAG.getSetCC(DL, > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Sat May 9 > 02:06:46 2009 > @@ -285,7 +285,7 @@ > if (ConstantInt *CI = dyn_cast(Idx)) { > if (CI->getZExtValue() == 0) continue; > uint64_t Offs = > - TD.getTypePaddedSize(Ty)*cast(CI)- > >getSExtValue(); > + TD.getTypeAllocSize(Ty)*cast(CI)- > >getSExtValue(); > N = FastEmit_ri_(VT, ISD::ADD, N, Offs, VT); > if (N == 0) > // Unhandled operand. Halt "fast" selection and bail. > @@ -294,7 +294,7 @@ > } > > // N = N + Idx * ElementSize; > - uint64_t ElementSize = TD.getTypePaddedSize(Ty); > + uint64_t ElementSize = TD.getTypeAllocSize(Ty); > unsigned IdxN = getRegForGEPIndex(Idx); > if (IdxN == 0) > // Unhandled operand. Halt "fast" selection and bail. > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat May 9 > 02:06:46 2009 > @@ -3638,7 +3638,7 @@ > // Increment the pointer, VAList, to the next vaarg > Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList, > DAG.getConstant(TLI.getTargetData()-> > - > getTypePaddedSize(VT.getTypeForMVT()), > + > getTypeAllocSize(VT.getTypeForMVT()), > TLI.getPointerTy())); > // Store the incremented VAList to the legalized pointer > Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0); > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ > ScheduleDAGSDNodesEmit.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp > (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp > Sat May 9 02:06:46 2009 > @@ -295,7 +295,7 @@ > Align = TM.getTargetData()->getPrefTypeAlignment(Type); > if (Align == 0) { > // Alignment of vector types. FIXME! > - Align = TM.getTargetData()->getTypePaddedSize(Type); > + Align = TM.getTargetData()->getTypeAllocSize(Type); > } > } > > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp > (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Sat > May 9 02:06:46 2009 > @@ -128,7 +128,7 @@ > // Given an array type, recursively traverse the elements. > if (const ArrayType *ATy = dyn_cast(Ty)) { > const Type *EltTy = ATy->getElementType(); > - uint64_t EltSize = TLI.getTargetData()->getTypePaddedSize(EltTy); > + uint64_t EltSize = TLI.getTargetData()->getTypeAllocSize(EltTy); > for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) > ComputeValueVTs(TLI, EltTy, ValueVTs, Offsets, > StartingOffset + i * EltSize); > @@ -294,7 +294,7 @@ > if (AllocaInst *AI = dyn_cast(I)) > if (ConstantInt *CUI = dyn_cast(AI- > >getArraySize())) { > const Type *Ty = AI->getAllocatedType(); > - uint64_t TySize = TLI.getTargetData()->getTypePaddedSize(Ty); > + uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty); > unsigned Align = > std::max((unsigned)TLI.getTargetData()- > >getPrefTypeAlignment(Ty), > AI->getAlignment()); > @@ -2700,7 +2700,7 @@ > if (ConstantInt *CI = dyn_cast(Idx)) { > if (CI->getZExtValue() == 0) continue; > uint64_t Offs = > - TD->getTypePaddedSize(Ty)*cast(CI)- > >getSExtValue(); > + TD->getTypeAllocSize(Ty)*cast(CI)- > >getSExtValue(); > SDValue OffsVal; > unsigned PtrBits = TLI.getPointerTy().getSizeInBits(); > if (PtrBits < 64) { > @@ -2715,7 +2715,7 @@ > } > > // N = N + Idx * ElementSize; > - uint64_t ElementSize = TD->getTypePaddedSize(Ty); > + uint64_t ElementSize = TD->getTypeAllocSize(Ty); > SDValue IdxN = getValue(Idx); > > // If the index is smaller or larger than intptr_t, truncate > or extend > @@ -2756,7 +2756,7 @@ > return; // getValue will auto-populate this. > > const Type *Ty = I.getAllocatedType(); > - uint64_t TySize = TLI.getTargetData()->getTypePaddedSize(Ty); > + uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty); > unsigned Align = > std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), > I.getAlignment()); > @@ -5199,7 +5199,7 @@ > // Otherwise, create a stack slot and emit a store to it > before the > // asm. > const Type *Ty = OpVal->getType(); > - uint64_t TySize = TLI.getTargetData()->getTypePaddedSize(Ty); > + uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty); > unsigned Align = TLI.getTargetData()- > >getPrefTypeAlignment(Ty); > MachineFunction &MF = DAG.getMachineFunction(); > int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, > Align); > @@ -5500,7 +5500,7 @@ > // i32-ness of the optimizer: we do not want to promote to i64 and > then > // multiply on 64-bit targets. > // FIXME: Malloc inst should go away: PR715. > - uint64_t ElementSize = TD->getTypePaddedSize(I.getType()- > >getElementType()); > + uint64_t ElementSize = TD->getTypeAllocSize(I.getType()- > >getElementType()); > if (ElementSize != 1) > Src = DAG.getNode(ISD::MUL, getCurDebugLoc(), Src.getValueType(), > Src, DAG.getConstant(ElementSize, > Src.getValueType())); > @@ -5614,7 +5614,7 @@ > const PointerType *Ty = cast(I->getType()); > const Type *ElementTy = Ty->getElementType(); > unsigned FrameAlign = getByValTypeAlignment(ElementTy); > - unsigned FrameSize = getTargetData()- > >getTypePaddedSize(ElementTy); > + unsigned FrameSize = getTargetData()- > >getTypeAllocSize(ElementTy); > // For ByVal, alignment should be passed from FE. BE will > guess if > // this info is not there but there are cases it cannot get > right. > if (F.getParamAlignment(j)) > @@ -5747,7 +5747,7 @@ > const PointerType *Ty = cast(Args[i].Ty); > const Type *ElementTy = Ty->getElementType(); > unsigned FrameAlign = getByValTypeAlignment(ElementTy); > - unsigned FrameSize = getTargetData()- > >getTypePaddedSize(ElementTy); > + unsigned FrameSize = getTargetData()- > >getTypeAllocSize(ElementTy); > // For ByVal, alignment should come from FE. BE will guess > if this > // info is not there but there are cases it cannot get right. > if (Args[i].Alignment) > > Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/StackProtector.cpp (original) > +++ llvm/trunk/lib/CodeGen/StackProtector.cpp Sat May 9 02:06:46 2009 > @@ -114,7 +114,7 @@ > if (const ArrayType *AT = dyn_cast(AI- > >getAllocatedType())) > // If an array has more than SSPBufferSize bytes of > allocated space, > // then we emit stack protectors. > - if (SSPBufferSize <= TD->getTypePaddedSize(AT)) > + if (SSPBufferSize <= TD->getTypeAllocSize(AT)) > return true; > } > } > > Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original) > +++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Sat May 9 > 02:06:46 2009 > @@ -55,7 +55,7 @@ > > char* ExecutionEngine::getMemoryForGV(const GlobalVariable* GV) { > const Type *ElTy = GV->getType()->getElementType(); > - size_t GVSize = (size_t)getTargetData()->getTypePaddedSize(ElTy); > + size_t GVSize = (size_t)getTargetData()->getTypeAllocSize(ElTy); > return new char[GVSize]; > } > > @@ -848,16 +848,16 @@ > return; > } else if (const ConstantVector *CP = > dyn_cast(Init)) { > unsigned ElementSize = > - getTargetData()->getTypePaddedSize(CP->getType()- > >getElementType()); > + getTargetData()->getTypeAllocSize(CP->getType()- > >getElementType()); > for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) > InitializeMemory(CP->getOperand(i), (char*)Addr+i*ElementSize); > return; > } else if (isa(Init)) { > - memset(Addr, 0, (size_t)getTargetData()->getTypePaddedSize(Init- > >getType())); > + memset(Addr, 0, (size_t)getTargetData()->getTypeAllocSize(Init- > >getType())); > return; > } else if (const ConstantArray *CPA = > dyn_cast(Init)) { > unsigned ElementSize = > - getTargetData()->getTypePaddedSize(CPA->getType()- > >getElementType()); > + getTargetData()->getTypeAllocSize(CPA->getType()- > >getElementType()); > for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i) > InitializeMemory(CPA->getOperand(i), (char*)Addr+i*ElementSize); > return; > @@ -1004,7 +1004,7 @@ > InitializeMemory(GV->getInitializer(), GA); > > const Type *ElTy = GV->getType()->getElementType(); > - size_t GVSize = (size_t)getTargetData()->getTypePaddedSize(ElTy); > + size_t GVSize = (size_t)getTargetData()->getTypeAllocSize(ElTy); > NumInitBytes += (unsigned)GVSize; > ++NumGlobals; > } > > Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp > (original) > +++ llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp Sat > May 9 02:06:46 2009 > @@ -750,7 +750,7 @@ > unsigned NumElements = > getOperandValue(I.getOperand(0), SF).IntVal.getZExtValue(); > > - unsigned TypeSize = (size_t)TD.getTypePaddedSize(Ty); > + unsigned TypeSize = (size_t)TD.getTypeAllocSize(Ty); > > // Avoid malloc-ing zero bytes, use max()... > unsigned MemToAlloc = std::max(1U, NumElements * TypeSize); > @@ -810,7 +810,7 @@ > assert(BitWidth == 64 && "Invalid index type for > getelementptr"); > Idx = (int64_t)IdxGV.IntVal.getZExtValue(); > } > - Total += TD.getTypePaddedSize(ST->getElementType())*Idx; > + Total += TD.getTypeAllocSize(ST->getElementType())*Idx; > } > } > > > Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) > +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Sat May 9 02:06:46 > 2009 > @@ -632,7 +632,7 @@ > // emit it into memory. It goes in the same array as the > generated > // code, jump tables, etc. > const Type *GlobalType = GV->getType()->getElementType(); > - size_t S = getTargetData()->getTypePaddedSize(GlobalType); > + size_t S = getTargetData()->getTypeAllocSize(GlobalType); > size_t A = getTargetData()->getPreferredAlignment(GV); > if (GV->isThreadLocal()) { > MutexGuard locked(lock); > @@ -687,7 +687,7 @@ > /// > char* JIT::getMemoryForGV(const GlobalVariable* GV) { > const Type *ElTy = GV->getType()->getElementType(); > - size_t GVSize = (size_t)getTargetData()->getTypePaddedSize(ElTy); > + size_t GVSize = (size_t)getTargetData()->getTypeAllocSize(ElTy); > if (GV->isThreadLocal()) { > MutexGuard locked(lock); > return TJI.allocateThreadLocalMemory(GVSize); > > Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original) > +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Sat May 9 > 02:06:46 2009 > @@ -809,7 +809,7 @@ > unsigned AlignMask = CPE.getAlignment() - 1; > Size = (Size + AlignMask) & ~AlignMask; > const Type *Ty = CPE.getType(); > - Size += TD->getTypePaddedSize(Ty); > + Size += TD->getTypeAllocSize(Ty); > } > return Size; > } > @@ -838,7 +838,7 @@ > > unsigned JITEmitter::addSizeOfGlobal(const GlobalVariable *GV, > unsigned Size) { > const Type *ElTy = GV->getType()->getElementType(); > - size_t GVSize = (size_t)TheJIT->getTargetData()- > >getTypePaddedSize(ElTy); > + size_t GVSize = (size_t)TheJIT->getTargetData()- > >getTypeAllocSize(ElTy); > size_t GVAlign = > (size_t)TheJIT->getTargetData()->getPreferredAlignment(GV); > DOUT << "JIT: Adding in size " << GVSize << " alignment " << > GVAlign; > @@ -1322,7 +1322,7 @@ > << std::hex << CAddr << std::dec << "]\n"; > > const Type *Ty = CPE.Val.ConstVal->getType(); > - Offset += TheJIT->getTargetData()->getTypePaddedSize(Ty); > + Offset += TheJIT->getTargetData()->getTypeAllocSize(Ty); > } > } > > > Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Sat May 9 > 02:06:46 2009 > @@ -295,7 +295,7 @@ > > const TargetData &TD = *Fn.getTarget().getTargetData(); > for (unsigned i = 0, e = CPs.size(); i != e; ++i) { > - unsigned Size = TD.getTypePaddedSize(CPs[i].getType()); > + unsigned Size = TD.getTypeAllocSize(CPs[i].getType()); > // Verify that all constant pool entries are a multiple of 4 > bytes. If not, > // we would have to pad them out or something so that > instructions stay > // aligned. > > Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Sat May > 9 02:06:46 2009 > @@ -838,7 +838,7 @@ > std::string name = Mang->getValueName(GVar); > Constant *C = GVar->getInitializer(); > const Type *Type = C->getType(); > - unsigned Size = TD->getTypePaddedSize(Type); > + unsigned Size = TD->getTypeAllocSize(Type); > unsigned Align = TD->getPreferredAlignmentLog(GVar); > bool isDarwin = Subtarget->isTargetDarwin(); > > > Modified: llvm/trunk/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp > (original) > +++ llvm/trunk/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp Sat > May 9 02:06:46 2009 > @@ -224,7 +224,7 @@ > > std::string name = Mang->getValueName(GVar); > Constant *C = GVar->getInitializer(); > - unsigned Size = TD->getTypePaddedSize(C->getType()); > + unsigned Size = TD->getTypeAllocSize(C->getType()); > unsigned Align = TD->getPreferredAlignmentLog(GVar); > > // 0: Switch to section > > Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) > +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Sat May 9 02:06:46 > 2009 > @@ -497,7 +497,7 @@ > const VectorType *VTy = cast(Ty); > return printSimpleType(Out, VTy->getElementType(), isSigned, > " __attribute__((vector_size(" + > - utostr(TD->getTypePaddedSize(VTy)) + " ))) " + > NameSoFar); > + utostr(TD->getTypeAllocSize(VTy)) + " ))) " + > NameSoFar); > } > > default: > @@ -542,7 +542,7 @@ > const VectorType *VTy = cast(Ty); > return printSimpleType(Out, VTy->getElementType(), isSigned, > " __attribute__((vector_size(" + > - utostr(TD->getTypePaddedSize(VTy)) + " ))) " + > NameSoFar); > + utostr(TD->getTypeAllocSize(VTy)) + " ))) " + > NameSoFar); > } > > default: > > Modified: llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp > (original) > +++ llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp Sat > May 9 02:06:46 2009 > @@ -530,7 +530,7 @@ > > Constant *C = GVar->getInitializer(); > const Type *Type = C->getType(); > - unsigned Size = TD->getTypePaddedSize(Type); > + unsigned Size = TD->getTypeAllocSize(Type); > unsigned Align = TD->getPreferredAlignmentLog(GVar); > > SwitchToSection(TAI->SectionForGlobal(GVar)); > > Modified: llvm/trunk/lib/Target/DarwinTargetAsmInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/DarwinTargetAsmInfo.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/DarwinTargetAsmInfo.cpp (original) > +++ llvm/trunk/lib/Target/DarwinTargetAsmInfo.cpp Sat May 9 > 02:06:46 2009 > @@ -117,7 +117,7 @@ > Constant *C = cast(GV)->getInitializer(); > const Type *Ty = cast(C->getType())->getElementType(); > > - unsigned Size = TD->getTypePaddedSize(Ty); > + unsigned Size = TD->getTypeAllocSize(Ty); > if (Size) { > unsigned Align = TD->getPreferredAlignment(GV); > if (Align <= 32) > @@ -138,7 +138,7 @@ > DarwinTargetAsmInfo::MergeableConstSection(const Type *Ty) const { > const TargetData *TD = TM.getTargetData(); > > - unsigned Size = TD->getTypePaddedSize(Ty); > + unsigned Size = TD->getTypeAllocSize(Ty); > if (Size == 4) > return FourByteConstantSection; > else if (Size == 8) > > Modified: llvm/trunk/lib/Target/ELFTargetAsmInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ELFTargetAsmInfo.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ELFTargetAsmInfo.cpp (original) > +++ llvm/trunk/lib/Target/ELFTargetAsmInfo.cpp Sat May 9 02:06:46 > 2009 > @@ -151,7 +151,7 @@ > // FIXME: string here is temporary, until stuff will fully land in. > // We cannot use {Four,Eight,Sixteen}ByteConstantSection here, > since it's > // currently directly used by asmprinter. > - unsigned Size = TD->getTypePaddedSize(Ty); > + unsigned Size = TD->getTypeAllocSize(Ty); > if (Size == 4 || Size == 8 || Size == 16) { > std::string Name = ".rodata.cst" + utostr(Size); > > @@ -169,7 +169,7 @@ > Constant *C = cast(GV)->getInitializer(); > const Type *Ty = cast(C->getType())->getElementType(); > > - unsigned Size = TD->getTypePaddedSize(Ty); > + unsigned Size = TD->getTypeAllocSize(Ty); > if (Size <= 16) { > assert(getCStringSection() && "Should have string section > prefix"); > > > Modified: llvm/trunk/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp > (original) > +++ llvm/trunk/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp Sat > May 9 02:06:46 2009 > @@ -269,7 +269,7 @@ > O << "\n\n"; > std::string name = Mang->getValueName(GVar); > Constant *C = GVar->getInitializer(); > - unsigned Size = TD->getTypePaddedSize(C->getType()); > + unsigned Size = TD->getTypeAllocSize(C->getType()); > unsigned Align = TD->getPreferredAlignmentLog(GVar); > > printVisibility(name, GVar->getVisibility()); > > Modified: llvm/trunk/lib/Target/MSIL/MSILWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSIL/MSILWriter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/MSIL/MSILWriter.cpp (original) > +++ llvm/trunk/lib/Target/MSIL/MSILWriter.cpp Sat May 9 02:06:46 2009 > @@ -385,7 +385,7 @@ > case Type::DoubleTyID: > return "r8"; > case Type::PointerTyID: > - return "i"+utostr(TD->getTypePaddedSize(Ty)); > + return "i"+utostr(TD->getTypeAllocSize(Ty)); > default: > cerr << "TypeID = " << Ty->getTypeID() << '\n'; > assert(0 && "Invalid type in TypeToPostfix()"); > @@ -695,14 +695,14 @@ > uint64_t FieldIndex = cast(IndexValue)- > >getZExtValue(); > // Offset is the sum of all previous structure fields. > for (uint64_t F = 0; F - Size += TD->getTypePaddedSize(StrucTy- > >getContainedType((unsigned)F)); > + Size += TD->getTypeAllocSize(StrucTy- > >getContainedType((unsigned)F)); > printPtrLoad(Size); > printSimpleInstruction("add"); > continue; > } else if (const SequentialType* SeqTy = > dyn_cast(*I)) { > - Size = TD->getTypePaddedSize(SeqTy->getElementType()); > + Size = TD->getTypeAllocSize(SeqTy->getElementType()); > } else { > - Size = TD->getTypePaddedSize(*I); > + Size = TD->getTypeAllocSize(*I); > } > // Add offset of current element to stack top. > if (!isZeroValue(IndexValue)) { > @@ -1027,7 +1027,7 @@ > > > void MSILWriter::printAllocaInstruction(const AllocaInst* Inst) { > - uint64_t Size = TD->getTypePaddedSize(Inst->getAllocatedType()); > + uint64_t Size = TD->getTypeAllocSize(Inst->getAllocatedType()); > // Constant optimization. > if (const ConstantInt* CInt = dyn_cast(Inst- > >getOperand(0))) { > printPtrLoad(CInt->getZExtValue()*Size); > @@ -1443,7 +1443,7 @@ > // Print not duplicated type > if (Printed.insert(Ty).second) { > Out << ".class value explicit ansi sealed '" << Name << "'"; > - Out << " { .pack " << 1 << " .size " << TD- > >getTypePaddedSize(Ty); > + Out << " { .pack " << 1 << " .size " << TD- > >getTypeAllocSize(Ty); > Out << " }\n\n"; > } > } > @@ -1473,7 +1473,7 @@ > const Type* Ty = C->getType(); > // Print zero initialized constant. > if (isa(C) || C->isNullValue()) { > - TySize = TD->getTypePaddedSize(C->getType()); > + TySize = TD->getTypeAllocSize(C->getType()); > Offset += TySize; > Out << "int8 (0) [" << TySize << "]"; > return; > @@ -1481,14 +1481,14 @@ > // Print constant initializer > switch (Ty->getTypeID()) { > case Type::IntegerTyID: { > - TySize = TD->getTypePaddedSize(Ty); > + TySize = TD->getTypeAllocSize(Ty); > const ConstantInt* Int = cast(C); > Out << getPrimitiveTypeName(Ty,true) << "(" << Int- > >getSExtValue() << ")"; > break; > } > case Type::FloatTyID: > case Type::DoubleTyID: { > - TySize = TD->getTypePaddedSize(Ty); > + TySize = TD->getTypeAllocSize(Ty); > const ConstantFP* FP = cast(C); > if (Ty->getTypeID() == Type::FloatTyID) > Out << "int32 (" << > @@ -1507,7 +1507,7 @@ > } > break; > case Type::PointerTyID: > - TySize = TD->getTypePaddedSize(C->getType()); > + TySize = TD->getTypeAllocSize(C->getType()); > // Initialize with global variable address > if (const GlobalVariable *G = dyn_cast(C)) { > std::string name = getValueName(G); > > Modified: llvm/trunk/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp > (original) > +++ llvm/trunk/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp Sat > May 9 02:06:46 2009 > @@ -484,7 +484,7 @@ > std::string name = Mang->getValueName(GVar); > Constant *C = GVar->getInitializer(); > const Type *CTy = C->getType(); > - unsigned Size = TD->getTypePaddedSize(CTy); > + unsigned Size = TD->getTypeAllocSize(CTy); > const ConstantArray *CVA = dyn_cast(C); > bool printSizeAndType = true; > > > Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Sat May 9 > 02:06:46 2009 > @@ -210,7 +210,7 @@ > return false; > > const Type *Ty = GV->getType()->getElementType(); > - unsigned Size = TD->getTypePaddedSize(Ty); > + unsigned Size = TD->getTypeAllocSize(Ty); > > // if this is a internal constant string, there is a special > // section for it, but not in small data/bss. > @@ -551,7 +551,7 @@ > // hacking it. This feature should come soon so we can uncomment the > // stuff below. > //if (!Subtarget->hasABICall() && > - // IsInSmallSection(getTargetData()->getTypePaddedSize(C- > >getType()))) { > + // IsInSmallSection(getTargetData()->getTypeAllocSize(C- > >getType()))) { > // SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, MVT::i32, CP); > // SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32); > // ResNode = DAG.getNode(ISD::ADD, MVT::i32, GOT, GPRelNode); > > Modified: llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp (original) > +++ llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp Sat May 9 > 02:06:46 2009 > @@ -66,7 +66,7 @@ > > if (isa(GV)) { > const TargetData *TD = TM.getTargetData(); > - unsigned Size = TD->getTypePaddedSize(GV->getType()- > >getElementType()); > + unsigned Size = TD->getTypeAllocSize(GV->getType()- > >getElementType()); > unsigned Threshold = Subtarget->getSSectionThreshold(); > > if (Size > 0 && Size <= Threshold) { > > Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp Sat May 9 > 02:06:46 2009 > @@ -286,7 +286,7 @@ > const Type *RetType = F->getReturnType(); > unsigned RetSize = 0; > if (RetType->getTypeID() != Type::VoidTyID) > - RetSize = TD->getTypePaddedSize(RetType); > + RetSize = TD->getTypeAllocSize(RetType); > > //Emit function return value space > if(RetSize > 0) > @@ -300,7 +300,7 @@ > for (Function::const_arg_iterator argi = F->arg_begin(), > arge = F->arg_end(); argi != arge ; ++argi) { > const Type *Ty = argi->getType(); > - ArgSize += TD->getTypePaddedSize(Ty); > + ArgSize += TD->getTypeAllocSize(Ty); > } > O << FunctionLabelBegin << CurrentFnName << ".args. RES " << > ArgSize > << "\n"; > @@ -340,7 +340,7 @@ > I->setSection("fadata." + CurrentFnName + ".#"); > Constant *C = I->getInitializer(); > const Type *Ty = C->getType(); > - unsigned Size = TD->getTypePaddedSize(Ty); > + unsigned Size = TD->getTypeAllocSize(Ty); > FrameSize += Size; > // Emit memory reserve directive. > O << FunctionLabelBegin << VarName << " RES " << Size << "\n"; > @@ -374,7 +374,7 @@ > std::string Name = Mang->getValueName(Items[j]); > Constant *C = Items[j]->getInitializer(); > const Type *Ty = C->getType(); > - unsigned Size = TD->getTypePaddedSize(Ty); > + unsigned Size = TD->getTypeAllocSize(Ty); > > O << Name << " " <<"RES"<< " " << Size ; > O << "\n"; > > Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp (original) > +++ llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp Sat May 9 > 02:06:46 2009 > @@ -72,7 +72,7 @@ > // Find how much space this global needs. > const TargetData *TD = TM.getTargetData(); > const Type *Ty = C->getType(); > - unsigned ValSize = TD->getTypePaddedSize(Ty); > + unsigned ValSize = TD->getTypeAllocSize(Ty); > > // Go through all BSS Sections and assign this variable > // to the first available section having enough space. > @@ -118,7 +118,7 @@ > // Find how much space this global needs. > const TargetData *TD = TM.getTargetData(); > const Type *Ty = C->getType(); > - unsigned ValSize = TD->getTypePaddedSize(Ty); > + unsigned ValSize = TD->getTypeAllocSize(Ty); > > // Go through all IDATA Sections and assign this variable > // to the first available section having enough space. > > Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp > (original) > +++ llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Sat > May 9 02:06:46 2009 > @@ -687,7 +687,7 @@ > > Constant *C = GVar->getInitializer(); > const Type *Type = C->getType(); > - unsigned Size = TD->getTypePaddedSize(Type); > + unsigned Size = TD->getTypeAllocSize(Type); > unsigned Align = TD->getPreferredAlignmentLog(GVar); > > SwitchToSection(TAI->SectionForGlobal(GVar)); > @@ -927,7 +927,7 @@ > > Constant *C = GVar->getInitializer(); > const Type *Type = C->getType(); > - unsigned Size = TD->getTypePaddedSize(Type); > + unsigned Size = TD->getTypeAllocSize(Type); > unsigned Align = TD->getPreferredAlignmentLog(GVar); > > SwitchToSection(TAI->SectionForGlobal(GVar)); > > Modified: llvm/trunk/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp > (original) > +++ llvm/trunk/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp Sat > May 9 02:06:46 2009 > @@ -253,7 +253,7 @@ > O << "\n\n"; > std::string name = Mang->getValueName(GVar); > Constant *C = GVar->getInitializer(); > - unsigned Size = TD->getTypePaddedSize(C->getType()); > + unsigned Size = TD->getTypeAllocSize(C->getType()); > unsigned Align = TD->getPreferredAlignment(GVar); > > printVisibility(name, GVar->getVisibility()); > > Modified: llvm/trunk/lib/Target/Target.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Target.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/Target.cpp (original) > +++ llvm/trunk/lib/Target/Target.cpp Sat May 9 02:06:46 2009 > @@ -53,7 +53,7 @@ > } > > unsigned long long LLVMABISizeOfType(LLVMTargetDataRef TD, > LLVMTypeRef Ty) { > - return unwrap(TD)->getTypePaddedSize(unwrap(Ty)); > + return unwrap(TD)->getTypeAllocSize(unwrap(Ty)); > } > > unsigned LLVMABIAlignmentOfType(LLVMTargetDataRef TD, LLVMTypeRef > Ty) { > > Modified: llvm/trunk/lib/Target/TargetData.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetData.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/TargetData.cpp (original) > +++ llvm/trunk/lib/Target/TargetData.cpp Sat May 9 02:06:46 2009 > @@ -58,7 +58,7 @@ > StructAlignment = std::max(TyAlign, StructAlignment); > > MemberOffsets[i] = StructSize; > - StructSize += TD.getTypePaddedSize(Ty); // Consume space for > this data item > + StructSize += TD.getTypeAllocSize(Ty); // Consume space for > this data item > } > > // Empty structures have alignment of 1 byte. > @@ -425,7 +425,7 @@ > return getPointerSizeInBits(); > case Type::ArrayTyID: { > const ArrayType *ATy = cast(Ty); > - return getTypePaddedSizeInBits(ATy->getElementType())*ATy- > >getNumElements(); > + return getTypeAllocSizeInBits(ATy->getElementType())*ATy- > >getNumElements(); > } > case Type::StructTyID: > // Get the layout annotation... which is lazily created on demand. > @@ -568,7 +568,7 @@ > > // Get the array index and the size of each array element. > int64_t arrayIdx = cast(Indices[CurIDX])- > >getSExtValue(); > - Result += arrayIdx * (int64_t)getTypePaddedSize(Ty); > + Result += arrayIdx * (int64_t)getTypeAllocSize(Ty); > } > } > > > Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp > (original) > +++ llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp Sat > May 9 02:06:46 2009 > @@ -76,7 +76,7 @@ > Ty = cast(Ty)->getElementType(); > > // Size should be aligned to DWORD boundary > - Size += ((TD->getTypePaddedSize(Ty) + 3)/4)*4; > + Size += ((TD->getTypeAllocSize(Ty) + 3)/4)*4; > } > > // We're not supporting tooooo huge arguments :) > @@ -811,7 +811,7 @@ > std::string name = Mang->getValueName(GVar); > Constant *C = GVar->getInitializer(); > const Type *Type = C->getType(); > - unsigned Size = TD->getTypePaddedSize(Type); > + unsigned Size = TD->getTypeAllocSize(Type); > unsigned Align = TD->getPreferredAlignmentLog(GVar); > > printVisibility(name, GVar->getVisibility()); > > Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp > (original) > +++ llvm/trunk/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp Sat > May 9 02:06:46 2009 > @@ -59,7 +59,7 @@ > Ty = cast(Ty)->getElementType(); > > // Size should be aligned to DWORD boundary > - Size += ((TD->getTypePaddedSize(Ty) + 3)/4)*4; > + Size += ((TD->getTypeAllocSize(Ty) + 3)/4)*4; > } > > // We're not supporting tooooo huge arguments :) > > Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Sat May 9 02:06:46 2009 > @@ -393,7 +393,7 @@ > unsigned Idx = cast(Op)->getZExtValue(); > Disp += SL->getElementOffset(Idx); > } else { > - uint64_t S = TD.getTypePaddedSize(GTI.getIndexedType()); > + uint64_t S = TD.getTypeAllocSize(GTI.getIndexedType()); > if (ConstantInt *CI = dyn_cast(Op)) { > // Constant-offset addressing. > Disp += CI->getSExtValue() * S; > @@ -1490,7 +1490,7 @@ > unsigned Align = TD.getPrefTypeAlignment(C->getType()); > if (Align == 0) { > // Alignment of vector types. FIXME! > - Align = TD.getTypePaddedSize(C->getType()); > + Align = TD.getTypeAllocSize(C->getType()); > } > > // x86-32 PIC requires a PIC base register for constant pools. > > Modified: llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp Sat May 9 > 02:06:46 2009 > @@ -220,7 +220,7 @@ > > EmitAlignment(Align, GV, 2); > > - unsigned Size = TD->getTypePaddedSize(C->getType()); > + unsigned Size = TD->getTypeAllocSize(C->getType()); > if (GV->isThreadLocal()) { > Size *= MaxThreads; > } > > Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Sat May 9 > 02:06:46 2009 > @@ -270,7 +270,7 @@ > } > SDValue base = getGlobalAddressWrapper(GA, GV, DAG); > const TargetData *TD = TM.getTargetData(); > - unsigned Size = TD->getTypePaddedSize(Ty); > + unsigned Size = TD->getTypeAllocSize(Ty); > SDValue offset = DAG.getNode(ISD::MUL, dl, MVT::i32, > BuildGetId(DAG, dl), > DAG.getConstant(Size, MVT::i32)); > return DAG.getNode(ISD::ADD, dl, MVT::i32, base, offset); > > Modified: llvm/trunk/lib/Target/XCore/XCoreTargetAsmInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreTargetAsmInfo.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/XCore/XCoreTargetAsmInfo.cpp (original) > +++ llvm/trunk/lib/Target/XCore/XCoreTargetAsmInfo.cpp Sat May 9 > 02:06:46 2009 > @@ -106,7 +106,7 @@ > XCoreTargetAsmInfo::MergeableConstSection(const Type *Ty) const { > const TargetData *TD = TM.getTargetData(); > > - unsigned Size = TD->getTypePaddedSize(Ty); > + unsigned Size = TD->getTypeAllocSize(Ty); > if (Size == 4 || Size == 8 || Size == 16) { > std::string Name = ".cp.const" + utostr(Size); > > > Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) > +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sat May 9 02:06:46 > 2009 > @@ -513,7 +513,7 @@ > return 0; // It's not worth it. > NewGlobals.reserve(NumElements); > > - uint64_t EltSize = TD.getTypePaddedSize(STy->getElementType()); > + uint64_t EltSize = TD.getTypeAllocSize(STy->getElementType()); > unsigned EltAlign = TD.getABITypeAlignment(STy->getElementType()); > for (unsigned i = 0, e = NumElements; i != e; ++i) { > Constant *In = getAggregateConstantElement(Init, > @@ -1448,7 +1448,7 @@ > // (2048 bytes currently), as we don't want to introduce a 16M > global or > // something. > if (NElements->getZExtValue()* > - TD.getTypePaddedSize(MI->getAllocatedType()) < 2048) { > + TD.getTypeAllocSize(MI->getAllocatedType()) < 2048) { > GVI = OptimizeGlobalAddressOfMalloc(GV, MI); > return true; > } > > Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp > (original) > +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Sat > May 9 02:06:46 2009 > @@ -305,11 +305,11 @@ > if (AllocaInst* A = dyn_cast(*I)) { > if (ConstantInt* C = dyn_cast(A- > >getArraySize())) > pointerSize = C->getZExtValue() * > - TD.getTypePaddedSize(A- > >getAllocatedType()); > + TD.getTypeAllocSize(A->getAllocatedType()); > } else { > const PointerType* PT = cast( > cast(*I)- > >getType()); > - pointerSize = TD.getTypePaddedSize(PT->getElementType()); > + pointerSize = TD.getTypeAllocSize(PT->getElementType()); > } > > // See if the call site touches it > @@ -382,10 +382,10 @@ > if (AllocaInst* A = dyn_cast(*I)) { > if (ConstantInt* C = dyn_cast(A->getArraySize())) > pointerSize = C->getZExtValue() * > - TD.getTypePaddedSize(A->getAllocatedType()); > + TD.getTypeAllocSize(A->getAllocatedType()); > } else { > const PointerType* PT = cast(cast(*I)- > >getType()); > - pointerSize = TD.getTypePaddedSize(PT->getElementType()); > + pointerSize = TD.getTypeAllocSize(PT->getElementType()); > } > > // See if this pointer could alias it > > Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp > (original) > +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sat > May 9 02:06:46 2009 > @@ -5202,7 +5202,7 @@ > for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); > i != e; > ++i, ++GTI) { > Value *Op = *i; > - uint64_t Size = TD.getTypePaddedSize(GTI.getIndexedType()) & > PtrSizeMask; > + uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & > PtrSizeMask; > if (ConstantInt *OpC = dyn_cast(Op)) { > if (OpC->isZero()) continue; > > @@ -5294,7 +5294,7 @@ > if (const StructType *STy = dyn_cast(*GTI)) { > Offset += TD.getStructLayout(STy)->getElementOffset(CI- > >getZExtValue()); > } else { > - uint64_t Size = TD.getTypePaddedSize(GTI.getIndexedType()); > + uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()); > Offset += Size*CI->getSExtValue(); > } > } else { > @@ -5310,7 +5310,7 @@ > Value *VariableIdx = GEP->getOperand(i); > // Determine the scale factor of the variable element. For > example, this is > // 4 if the variable index is into an array of i32. > - uint64_t VariableScale = > TD.getTypePaddedSize(GTI.getIndexedType()); > + uint64_t VariableScale = TD.getTypeAllocSize(GTI.getIndexedType()); > > // Verify that there are no other variable indices. If so, emit > the hard way. > for (++i, ++GTI; i != e; ++i, ++GTI) { > @@ -5324,7 +5324,7 @@ > if (const StructType *STy = dyn_cast(*GTI)) { > Offset += TD.getStructLayout(STy)->getElementOffset(CI- > >getZExtValue()); > } else { > - uint64_t Size = TD.getTypePaddedSize(GTI.getIndexedType()); > + uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()); > Offset += Size*CI->getSExtValue(); > } > } > @@ -7606,8 +7606,8 @@ > if (!AI.hasOneUse() && !hasOneUsePlusDeclare(&AI) && > CastElTyAlign == AllocElTyAlign) return 0; > > - uint64_t AllocElTySize = TD->getTypePaddedSize(AllocElTy); > - uint64_t CastElTySize = TD->getTypePaddedSize(CastElTy); > + uint64_t AllocElTySize = TD->getTypeAllocSize(AllocElTy); > + uint64_t CastElTySize = TD->getTypeAllocSize(CastElTy); > if (CastElTySize == 0 || AllocElTySize == 0) return 0; > > // See if we can satisfy the modulus by pulling a scale out of the > array > @@ -7905,7 +7905,7 @@ > // is something like [0 x {int, int}] > const Type *IntPtrTy = TD->getIntPtrType(); > int64_t FirstIdx = 0; > - if (int64_t TySize = TD->getTypePaddedSize(Ty)) { > + if (int64_t TySize = TD->getTypeAllocSize(Ty)) { > FirstIdx = Offset/TySize; > Offset -= FirstIdx*TySize; > > @@ -7937,7 +7937,7 @@ > Offset -= SL->getElementOffset(Elt); > Ty = STy->getElementType(Elt); > } else if (const ArrayType *AT = dyn_cast(Ty)) { > - uint64_t EltSize = TD->getTypePaddedSize(AT->getElementType()); > + uint64_t EltSize = TD->getTypeAllocSize(AT->getElementType()); > assert(EltSize && "Cannot index into a zero-sized array"); > NewIndices.push_back(ConstantInt::get(IntPtrTy,Offset/EltSize)); > Offset %= EltSize; > @@ -8687,7 +8687,7 @@ > // is a single-index GEP. > if (X->getType() == CI.getType()) { > // Get the size of the pointee type. > - uint64_t Size = TD->getTypePaddedSize(DestPointee); > + uint64_t Size = TD->getTypeAllocSize(DestPointee); > > // Convert the constant to intptr type. > APInt Offset = Cst->getValue(); > @@ -8707,7 +8707,7 @@ > // "inttoptr+GEP" instead of "add+intptr". > > // Get the size of the pointee type. > - uint64_t Size = TD->getTypePaddedSize(DestPointee); > + uint64_t Size = TD->getTypeAllocSize(DestPointee); > > // Convert the constant to intptr type. > APInt Offset = Cst->getValue(); > @@ -9811,7 +9811,7 @@ > const Type* DstTy = cast(CI->getType())- > >getElementType(); > if (!SrcTy->isSized() || !DstTy->isSized()) > return false; > - if (TD->getTypePaddedSize(SrcTy) != TD->getTypePaddedSize(DstTy)) > + if (TD->getTypeAllocSize(SrcTy) != TD->getTypeAllocSize(DstTy)) > return false; > return true; > } > @@ -10966,8 +10966,8 @@ > const Type *SrcElTy = cast(X->getType())- > >getElementType(); > const Type *ResElTy=cast(PtrOp->getType())- > >getElementType(); > if (isa(SrcElTy) && > - TD->getTypePaddedSize(cast(SrcElTy)- > >getElementType()) == > - TD->getTypePaddedSize(ResElTy)) { > + TD->getTypeAllocSize(cast(SrcElTy)- > >getElementType()) == > + TD->getTypeAllocSize(ResElTy)) { > Value *Idx[2]; > Idx[0] = Constant::getNullValue(Type::Int32Ty); > Idx[1] = GEP.getOperand(1); > @@ -10984,7 +10984,7 @@ > > if (isa(SrcElTy) && ResElTy == Type::Int8Ty) { > uint64_t ArrayEltSize = > - TD->getTypePaddedSize(cast(SrcElTy)- > >getElementType()); > + TD->getTypeAllocSize(cast(SrcElTy)- > >getElementType()); > > // Check to see if "tmp" is a scale by a multiple of > ArrayEltSize. We > // allow either a mul, shift, or constant here. > @@ -11137,7 +11137,7 @@ > // If alloca'ing a zero byte object, replace the alloca with a > null pointer. > // Note that we only do this for alloca's, because malloc should > allocate > // and return a unique pointer, even for a zero byte allocation. > - if (TD->getTypePaddedSize(AI.getAllocatedType()) == 0) > + if (TD->getTypeAllocSize(AI.getAllocatedType()) == 0) > return ReplaceInstUsesWith(AI, > Constant::getNullValue(AI.getType())); > > // If the alignment is 0 (unspecified), assign it the preferred > alignment. > > Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Sat May 9 > 02:06:46 2009 > @@ -104,7 +104,7 @@ > > // Otherwise, we have a sequential type like an array or > vector. Multiply > // the index by the ElementSize. > - uint64_t Size = TD.getTypePaddedSize(GTI.getIndexedType()); > + uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()); > Offset += Size*OpC->getSExtValue(); > } > > @@ -511,7 +511,7 @@ > if (!srcArraySize) > return false; > > - uint64_t srcSize = TD.getTypePaddedSize(srcAlloca- > >getAllocatedType()) * > + uint64_t srcSize = TD.getTypeAllocSize(srcAlloca- > >getAllocatedType()) * > srcArraySize->getZExtValue(); > > if (cpyLength->getZExtValue() < srcSize) > @@ -526,7 +526,7 @@ > if (!destArraySize) > return false; > > - uint64_t destSize = TD.getTypePaddedSize(A->getAllocatedType()) * > + uint64_t destSize = TD.getTypeAllocSize(A->getAllocatedType()) * > destArraySize->getZExtValue(); > > if (destSize < srcSize) > @@ -538,7 +538,7 @@ > return false; > > const Type* StructTy = cast(A->getType())- > >getElementType(); > - uint64_t destSize = TD.getTypePaddedSize(StructTy); > + uint64_t destSize = TD.getTypeAllocSize(StructTy); > > if (destSize < srcSize) > return false; > > Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp > (original) > +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Sat > May 9 02:06:46 2009 > @@ -252,7 +252,7 @@ > // transform the allocation instruction if it is an array > allocation > // (allocations OF arrays are ok though), and an allocation of a > scalar > // value cannot be decomposed at all. > - uint64_t AllocaSize = TD->getTypePaddedSize(AI- > >getAllocatedType()); > + uint64_t AllocaSize = TD->getTypeAllocSize(AI- > >getAllocatedType()); > > // Do not promote any struct whose size is too big. > if (AllocaSize > SRThreshold) continue; > @@ -601,7 +601,7 @@ > > // If not the whole aggregate, give up. > if (Length->getZExtValue() != > - TD->getTypePaddedSize(AI->getType()->getElementType())) > + TD->getTypeAllocSize(AI->getType()->getElementType())) > return MarkUnsafe(Info); > > // We only know about memcpy/memset/memmove. > @@ -637,8 +637,8 @@ > // cast a {i32,i32}* to i64* and store through it. This is > similar to the > // memcpy case and occurs in various "byval" cases and > emulated memcpys. > if (isa(SI->getOperand(0)->getType()) && > - TD->getTypePaddedSize(SI->getOperand(0)->getType()) == > - TD->getTypePaddedSize(AI->getType()->getElementType())) { > + TD->getTypeAllocSize(SI->getOperand(0)->getType()) == > + TD->getTypeAllocSize(AI->getType()->getElementType())) { > Info.isMemCpyDst = true; > continue; > } > @@ -652,8 +652,8 @@ > // cast a {i32,i32}* to i64* and load through it. This is > similar to the > // memcpy case and occurs in various "byval" cases and > emulated memcpys. > if (isa(LI->getType()) && > - TD->getTypePaddedSize(LI->getType()) == > - TD->getTypePaddedSize(AI->getType()->getElementType())) { > + TD->getTypeAllocSize(LI->getType()) == > + TD->getTypeAllocSize(AI->getType()->getElementType())) { > Info.isMemCpySrc = true; > continue; > } > @@ -782,7 +782,7 @@ > } else { > const Type *EltTy = > cast(OtherPtr->getType())->getElementType(); > - EltOffset = TD->getTypePaddedSize(EltTy)*i; > + EltOffset = TD->getTypeAllocSize(EltTy)*i; > } > > // The alignment of the other pointer is the guaranteed > alignment of the > @@ -865,7 +865,7 @@ > OtherElt = new BitCastInst(OtherElt, BytePtrTy,OtherElt- > >getNameStr(), > MI); > > - unsigned EltSize = TD->getTypePaddedSize(EltTy); > + unsigned EltSize = TD->getTypeAllocSize(EltTy); > > // Finally, insert the meminst for this element. > if (isa(MI)) { > @@ -899,7 +899,7 @@ > // and store the element value to the individual alloca. > Value *SrcVal = SI->getOperand(0); > const Type *AllocaEltTy = AI->getType()->getElementType(); > - uint64_t AllocaSizeBits = TD->getTypePaddedSizeInBits(AllocaEltTy); > + uint64_t AllocaSizeBits = TD->getTypeAllocSizeInBits(AllocaEltTy); > > // If this isn't a store of an integer to the whole alloca, it may > be a store > // to the first element. Just ignore the store in this case and > normal SROA > @@ -922,7 +922,7 @@ > uint64_t Shift = Layout->getElementOffsetInBits(i); > > if (TD->isBigEndian()) > - Shift = AllocaSizeBits-Shift-TD- > >getTypePaddedSizeInBits(FieldTy); > + Shift = AllocaSizeBits-Shift-TD- > >getTypeAllocSizeInBits(FieldTy); > > Value *EltVal = SrcVal; > if (Shift) { > @@ -957,7 +957,7 @@ > } else { > const ArrayType *ATy = cast(AllocaEltTy); > const Type *ArrayEltTy = ATy->getElementType(); > - uint64_t ElementOffset = TD->getTypePaddedSizeInBits(ArrayEltTy); > + uint64_t ElementOffset = TD->getTypeAllocSizeInBits(ArrayEltTy); > uint64_t ElementSizeBits = TD->getTypeSizeInBits(ArrayEltTy); > > uint64_t Shift; > @@ -1012,7 +1012,7 @@ > // Extract each element out of the NewElts according to its > structure offset > // and form the result value. > const Type *AllocaEltTy = AI->getType()->getElementType(); > - uint64_t AllocaSizeBits = TD->getTypePaddedSizeInBits(AllocaEltTy); > + uint64_t AllocaSizeBits = TD->getTypeAllocSizeInBits(AllocaEltTy); > > // If this isn't a load of the whole alloca to an integer, it may > be a load > // of the first element. Just ignore the load in this case and > normal SROA > @@ -1032,7 +1032,7 @@ > Layout = TD->getStructLayout(EltSTy); > } else { > const Type *ArrayEltTy = cast(AllocaEltTy)- > >getElementType(); > - ArrayEltBitOffset = TD->getTypePaddedSizeInBits(ArrayEltTy); > + ArrayEltBitOffset = TD->getTypeAllocSizeInBits(ArrayEltTy); > } > > Value *ResultVal = Constant::getNullValue(LI->getType()); > @@ -1126,7 +1126,7 @@ > } else if (const VectorType *VTy = dyn_cast(Ty)) { > return HasPadding(VTy->getElementType(), TD); > } > - return TD.getTypeSizeInBits(Ty) != TD.getTypePaddedSizeInBits(Ty); > + return TD.getTypeSizeInBits(Ty) != TD.getTypeAllocSizeInBits(Ty); > } > > /// isSafeStructAllocaToScalarRepl - Check to see if the specified > allocation of > @@ -1527,7 +1527,7 @@ > // Otherwise it must be an element access. > unsigned Elt = 0; > if (Offset) { > - unsigned EltSize = TD->getTypePaddedSizeInBits(VTy- > >getElementType()); > + unsigned EltSize = TD->getTypeAllocSizeInBits(VTy- > >getElementType()); > Elt = Offset/EltSize; > assert(EltSize*Elt == Offset && "Invalid modulus in validity > checking"); > } > @@ -1555,7 +1555,7 @@ > } > > if (const ArrayType *AT = dyn_cast(ToType)) { > - uint64_t EltSize = TD->getTypePaddedSizeInBits(AT- > >getElementType()); > + uint64_t EltSize = TD->getTypeAllocSizeInBits(AT- > >getElementType()); > Value *Res = UndefValue::get(AT); > for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) { > Value *Elt = ConvertScalar_ExtractValue(FromVal, AT- > >getElementType(), > @@ -1630,15 +1630,15 @@ > const Type *AllocaType = Old->getType(); > > if (const VectorType *VTy = dyn_cast(AllocaType)) { > - uint64_t VecSize = TD->getTypePaddedSizeInBits(VTy); > - uint64_t ValSize = TD->getTypePaddedSizeInBits(SV->getType()); > + uint64_t VecSize = TD->getTypeAllocSizeInBits(VTy); > + uint64_t ValSize = TD->getTypeAllocSizeInBits(SV->getType()); > > // Changing the whole vector with memset or with an access of a > different > // vector type? > if (ValSize == VecSize) > return Builder.CreateBitCast(SV, AllocaType, "tmp"); > > - uint64_t EltSize = TD->getTypePaddedSizeInBits(VTy- > >getElementType()); > + uint64_t EltSize = TD->getTypeAllocSizeInBits(VTy- > >getElementType()); > > // Must be an element insertion. > unsigned Elt = Offset/EltSize; > @@ -1665,7 +1665,7 @@ > } > > if (const ArrayType *AT = dyn_cast(SV->getType())) { > - uint64_t EltSize = TD->getTypePaddedSizeInBits(AT- > >getElementType()); > + uint64_t EltSize = TD->getTypeAllocSizeInBits(AT- > >getElementType()); > for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) { > Value *Elt = Builder.CreateExtractValue(SV, i, "tmp"); > Old = ConvertScalar_InsertValue(Elt, Old, Offset+i*EltSize, > Builder); > > Modified: llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp (original) > +++ llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp Sat May 9 > 02:06:46 2009 > @@ -225,7 +225,7 @@ > cast(AddrInst->getOperand(i))->getZExtValue(); > ConstantOffset += SL->getElementOffset(Idx); > } else { > - uint64_t TypeSize = TD- > >getTypePaddedSize(GTI.getIndexedType()); > + uint64_t TypeSize = TD- > >getTypeAllocSize(GTI.getIndexedType()); > if (ConstantInt *CI = dyn_cast(AddrInst- > >getOperand(i))) { > ConstantOffset += CI->getSExtValue()*TypeSize; > } else if (TypeSize) { // Scales of zero don't do anything. > > Modified: llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp (original) > +++ llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp Sat May 9 > 02:06:46 2009 > @@ -116,7 +116,7 @@ > Value *MallocArg; > if (LowerMallocArgToInteger) > MallocArg = ConstantInt::get(Type::Int64Ty, > - TD.getTypePaddedSize(AllocTy)); > + TD.getTypeAllocSize(AllocTy)); > else > MallocArg = ConstantExpr::getSizeOf(AllocTy); > MallocArg = > ConstantExpr::getTruncOrBitCast(cast(MallocArg), > > Modified: llvm/trunk/utils/TableGen/CallingConvEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CallingConvEmitter.cpp?rev=71349&r1=71348&r2=71349&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/utils/TableGen/CallingConvEmitter.cpp (original) > +++ llvm/trunk/utils/TableGen/CallingConvEmitter.cpp Sat May 9 > 02:06:46 2009 > @@ -163,7 +163,7 @@ > O << Size << ", "; > else > O << "\n" << IndentStr << " > State.getTarget().getTargetData()" > - "->getTypePaddedSize(LocVT.getTypeForMVT()), "; > + "->getTypeAllocSize(LocVT.getTypeForMVT()), "; > if (Align) > O << Align; > else > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Sat May 9 02:29:34 2009 From: baldrick at free.fr (Duncan Sands) Date: Sat, 9 May 2009 09:29:34 +0200 Subject: [llvm-commits] [llvm] r71238 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp In-Reply-To: <200905081851.n48Ip8PN021912@zion.cs.uiuc.edu> References: <200905081851.n48Ip8PN021912@zion.cs.uiuc.edu> Message-ID: <200905090929.36184.baldrick@free.fr> Hi Anton, > + case ISD::UREM: > + case ISD::SREM: > + if (VT == MVT::i16) > + LC = (isSigned ? RTLIB::SREM_I16 : RTLIB::UREM_I16); > + else if (VT == MVT::i32) > + LC = (isSigned ? RTLIB::SREM_I32 : RTLIB::UREM_I32); > + else if (VT == MVT::i64) > + LC = (isSigned ? RTLIB::SREM_I64 : RTLIB::UREM_I64); > + else if (VT == MVT::i128) > + LC = (isSigned ? RTLIB::SREM_I128 : RTLIB::UREM_I128); how about factoring this kind of logic, into a function that returns the UREM libcall for a given value type, and another for SREM. In fact I think all libcall lookups should be done that way. The advantage is that if a new type size is added (eg: i8 UREM) then only one place has to be modified. I already did this for libcalls that depend on more than one value type, see RTLIB::getFPROUND for example. Ciao, Duncan. From baldrick at free.fr Sat May 9 02:36:01 2009 From: baldrick at free.fr (Duncan Sands) Date: Sat, 09 May 2009 07:36:01 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r71351 - in /llvm-gcc-4.2/trunk/gcc: config/i386/llvm-i386.cpp llvm-abi.h llvm-convert.cpp llvm-types.cpp Message-ID: <200905090736.n497a1qA020450@zion.cs.uiuc.edu> Author: baldrick Date: Sat May 9 02:36:00 2009 New Revision: 71351 URL: http://llvm.org/viewvc/llvm-project?rev=71351&view=rev Log: Correct for renaming PaddedSize -> AllocSize in LLVM. Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp llvm-gcc-4.2/trunk/gcc/llvm-abi.h llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=71351&r1=71350&r2=71351&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Sat May 9 02:36:00 2009 @@ -1074,7 +1074,7 @@ const Type *llvm_x86_scalar_type_for_struct_return(tree type, unsigned *Offset) { *Offset = 0; const Type *Ty = ConvertType(type); - unsigned Size = getTargetData().getTypePaddedSize(Ty); + unsigned Size = getTargetData().getTypeAllocSize(Ty); if (Size == 0) return Type::VoidTy; else if (Size == 1) Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi.h?rev=71351&r1=71350&r2=71351&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Sat May 9 02:36:00 2009 @@ -205,7 +205,7 @@ // target independent implementation. static const Type* getLLVMScalarTypeForStructReturn(tree type, unsigned *Offset) { const Type *Ty = ConvertType(type); - unsigned Size = getTargetData().getTypePaddedSize(Ty); + unsigned Size = getTargetData().getTypeAllocSize(Ty); *Offset = 0; if (Size == 0) return Type::VoidTy; @@ -653,20 +653,20 @@ const StructType *STy = StructType::get(Elts, false); - unsigned Size = getTargetData().getTypePaddedSize(STy); + unsigned Size = getTargetData().getTypeAllocSize(STy); const StructType *InSTy = dyn_cast(Ty); unsigned InSize = 0; // If Ty and STy size does not match then last element is accessing // extra bits. unsigned LastEltSizeDiff = 0; if (InSTy) { - InSize = getTargetData().getTypePaddedSize(InSTy); + InSize = getTargetData().getTypeAllocSize(InSTy); if (InSize < Size) { unsigned N = STy->getNumElements(); const llvm::Type *LastEltTy = STy->getElementType(N-1); if (LastEltTy->isInteger()) LastEltSizeDiff = - getTargetData().getTypePaddedSize(LastEltTy) - (Size - InSize); + getTargetData().getTypeAllocSize(LastEltTy) - (Size - InSize); } } for (unsigned i = 0, e = Elts.size(); i != e; ++i) { Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=71351&r1=71350&r2=71351&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Sat May 9 02:36:00 2009 @@ -1154,7 +1154,7 @@ } } else { const ArrayType *ATy = cast(ElTy); - unsigned EltSize = getTargetData().getTypePaddedSize(ATy->getElementType()); + unsigned EltSize = getTargetData().getTypeAllocSize(ATy->getElementType()); for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) { Value *DElPtr = Builder.CreateStructGEP(DestLoc.Ptr, i); Value *SElPtr = Builder.CreateStructGEP(SrcLoc.Ptr, i); @@ -1265,7 +1265,7 @@ } } else { const ArrayType *ATy = cast(ElTy); - unsigned EltSize = getTargetData().getTypePaddedSize(ATy->getElementType()); + unsigned EltSize = getTargetData().getTypeAllocSize(ATy->getElementType()); for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) { Value *Ptr = Builder.CreateStructGEP(DestLoc.Ptr, i); unsigned Alignment = MinAlign(DestLoc.Alignment, i * EltSize); @@ -3269,7 +3269,7 @@ // We can't get the type size (and thus convert to using a GEP instr) from // pointers to opaque structs if the type isn't abstract. if (ElTy->isSized()) { - int64_t EltSize = TD.getTypePaddedSize(ElTy); + int64_t EltSize = TD.getTypeAllocSize(ElTy); // If EltSize exactly divides Offset, then we know that we can turn this // into a getelementptr instruction. @@ -5681,7 +5681,7 @@ Value *ImagPtr = Builder.CreateStructGEP(SrcComplex.Ptr, 1, "imag"); Imag = Builder.CreateLoad(ImagPtr, SrcComplex.Volatile, "imag"); cast(Imag)->setAlignment( - MinAlign(SrcComplex.Alignment, TD.getTypePaddedSize(Real->getType())) + MinAlign(SrcComplex.Alignment, TD.getTypeAllocSize(Real->getType())) ); } @@ -5696,7 +5696,7 @@ Value *ImagPtr = Builder.CreateStructGEP(DestComplex.Ptr, 1, "imag"); St = Builder.CreateStore(Imag, ImagPtr, DestComplex.Volatile); St->setAlignment( - MinAlign(DestComplex.Alignment, TD.getTypePaddedSize(Real->getType())) + MinAlign(DestComplex.Alignment, TD.getTypeAllocSize(Real->getType())) ); } @@ -6168,7 +6168,7 @@ if (LLVMFieldTy->isInteger() && LLVMFieldTy->getPrimitiveSizeInBits() >= BitStart + BitfieldSize && LLVMFieldTy->getPrimitiveSizeInBits() == - TD.getTypePaddedSizeInBits(LLVMFieldTy)) + TD.getTypeAllocSizeInBits(LLVMFieldTy)) FieldTy = LLVMFieldTy; else // If the field result type T is a bool or some other curiously sized @@ -6178,10 +6178,10 @@ // sized like an i24 there may be trouble: incrementing a T* will move // the position by 32 bits not 24, leaving the upper 8 of those 32 bits // inaccessible. Avoid this by rounding up the size appropriately. - FieldTy = IntegerType::get(TD.getTypePaddedSizeInBits(FieldTy)); + FieldTy = IntegerType::get(TD.getTypeAllocSizeInBits(FieldTy)); assert(FieldTy->getPrimitiveSizeInBits() == - TD.getTypePaddedSizeInBits(FieldTy) && "Field type not sequential!"); + TD.getTypeAllocSizeInBits(FieldTy) && "Field type not sequential!"); // If this is a bitfield, the field may span multiple fields in the LLVM // type. As such, cast the pointer to be a pointer to the declared type. @@ -6258,7 +6258,7 @@ assert(BitSize <= ValueSizeInBits && "ValTy isn't large enough to hold the value loaded!"); - assert(ValueSizeInBits == TD.getTypePaddedSizeInBits(ValTy) && + assert(ValueSizeInBits == TD.getTypeAllocSizeInBits(ValTy) && "FIXME: BIT_FIELD_REF logic is broken for non-round types"); // BIT_FIELD_REF values can have BitStart values that are quite large. We @@ -6295,7 +6295,7 @@ else // IMAGPART alignment = MinAlign(Ptr.Alignment, sizeof field); Alignment = MinAlign(Ptr.Alignment, - TD.getTypePaddedSize(Ptr.Ptr->getType())); + TD.getTypeAllocSize(Ptr.Ptr->getType())); return LValue(Builder.CreateStructGEP(Ptr.Ptr, Idx), Alignment); } @@ -6847,7 +6847,7 @@ // If the alignment doesn't affect the element offset, then the value is ok. // Accept the field and keep moving. if (AlignedEltOffs == EltOffs) { - EltOffs += TD.getTypePaddedSize(Val->getType()); + EltOffs += TD.getTypeAllocSize(Val->getType()); continue; } @@ -6953,7 +6953,7 @@ assert(LLVMNaturalByteOffset*8 == GCCFieldOffsetInBits); ResultElts.push_back(Val); NextFieldByteStart = LLVMNaturalByteOffset; - NextFieldByteStart += TD.getTypePaddedSize(Val->getType()); + NextFieldByteStart += TD.getTypeAllocSize(Val->getType()); } /// AddBitFieldToRecordConstant - Bitfields can span multiple LLVM fields and @@ -7209,7 +7209,7 @@ tree UnionType = TREE_TYPE(exp); if (TYPE_SIZE(UnionType) && TREE_CODE(TYPE_SIZE(UnionType)) == INTEGER_CST) { uint64_t UnionSize = ((uint64_t)TREE_INT_CST_LOW(TYPE_SIZE(UnionType))+7)/8; - uint64_t InitSize = getTargetData().getTypePaddedSize(Elts[0]->getType()); + uint64_t InitSize = getTargetData().getTypeAllocSize(Elts[0]->getType()); if (UnionSize != InitSize) { const Type *FillTy; assert(UnionSize > InitSize && "Init shouldn't be larger than union!"); Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=71351&r1=71350&r2=71351&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Sat May 9 02:36:00 2009 @@ -72,11 +72,11 @@ static const Type * llvm_set_type(tree Tr, const Type *Ty) { // For x86 long double, llvm records the size of the data (80) while - // gcc's TYPE_SIZE including alignment padding. getTypePaddedSizeInBits + // gcc's TYPE_SIZE including alignment padding. getTypeAllocSizeInBits // is used to compensate for this. assert((!TYPE_SIZE(Tr) || !Ty->isSized() || !isInt64(TYPE_SIZE(Tr), true) || getInt64(TYPE_SIZE(Tr), true) == - getTargetData().getTypePaddedSizeInBits(Ty)) + getTargetData().getTypeAllocSizeInBits(Ty)) && "LLVM type size doesn't match GCC type size!"); unsigned &TypeSlot = LTypesMap[Ty]; @@ -1334,7 +1334,7 @@ /// getTypeSize - Return the size of the specified type in bytes. /// uint64_t getTypeSize(const Type *Ty) const { - return TD.getTypePaddedSize(Ty); + return TD.getTypeAllocSize(Ty); } /// getLLVMType - Return the LLVM type for the specified object. @@ -2284,7 +2284,7 @@ } #endif const Type *TheTy = ConvertType(TheGccTy); - unsigned Size = TD.getTypePaddedSize(TheTy); + unsigned Size = TD.getTypeAllocSize(TheTy); unsigned Align = TD.getABITypeAlignment(TheTy); adjustPaddingElement(GccUnionTy, TheGccTy); @@ -2321,7 +2321,7 @@ unsigned EltSize = 0; if (UnionTy) { // Not an empty union. EltAlign = TD.getABITypeAlignment(UnionTy); - EltSize = TD.getTypePaddedSize(UnionTy); + EltSize = TD.getTypeAllocSize(UnionTy); UnionElts.push_back(UnionTy); } From baldrick at free.fr Sat May 9 02:40:09 2009 From: baldrick at free.fr (Duncan Sands) Date: Sat, 9 May 2009 09:40:09 +0200 Subject: [llvm-commits] [llvm] r71349 - in /llvm/trunk: bindings/ocaml/target/ include/llvm-c/ include/llvm/Target/ lib/Analysis/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/ExecutionEngine/ lib/ExecutionEngine/Interpreter/ lib/ExecutionEngine/JIT/ lib/Target/ lib/Target/ARM/ lib/Target/ARM/AsmPrinter/ lib/Target/Alpha/AsmPrinter/ lib/Target/CBackend/ lib/Target/CellSPU/AsmPrinter/ lib/Target/IA64/AsmPrinter/ lib/Target/MSIL/ lib/Target/Mips/ lib/Target/Mips/AsmPrinter/ lib/Target/PIC16/ lib/Target/PowerP... In-Reply-To: References: <200905090706.n4976n4F018353@zion.cs.uiuc.edu> Message-ID: <200905090940.10103.baldrick@free.fr> Hi Bill, > Please make the appropriate changes in llvm-gcc. Thanks! I did of course, but "svn commit" took a long time to complete (heavy system load). Sorry for the breakage. Ciao, Duncan. From isanbard at gmail.com Sat May 9 02:53:59 2009 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 9 May 2009 00:53:59 -0700 Subject: [llvm-commits] [llvm] r71349 - in /llvm/trunk: bindings/ocaml/target/ include/llvm-c/ include/llvm/Target/ lib/Analysis/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/ExecutionEngine/ lib/ExecutionEngine/Interpreter/ lib/ExecutionEngine/JIT/ lib/Target/ lib/Target/ARM/ lib/Target/ARM/AsmPrinter/ lib/Target/Alpha/AsmPrinter/ lib/Target/CBackend/ lib/Target/CellSPU/AsmPrinter/ lib/Target/IA64/AsmPrinter/ lib/Target/MSIL/ lib/Target/Mips/ lib/Target/Mips/AsmPrinter/ lib/Target/PIC16/ lib/Target/PowerP... In-Reply-To: <200905090940.10103.baldrick@free.fr> References: <200905090706.n4976n4F018353@zion.cs.uiuc.edu> <200905090940.10103.baldrick@free.fr> Message-ID: <88CB4A97-1D38-48EF-BE64-766B32075CFC@gmail.com> On May 9, 2009, at 12:40 AM, Duncan Sands wrote: > Hi Bill, > >> Please make the appropriate changes in llvm-gcc. Thanks! > > I did of course, but "svn commit" took a long time to complete > (heavy system load). Sorry for the breakage. > Thanks! -bw From eli.friedman at gmail.com Sat May 9 03:40:27 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Sat, 09 May 2009 08:40:27 -0000 Subject: [llvm-commits] [llvm] r71352 - /llvm/trunk/lib/Target/README.txt Message-ID: <200905090840.n498eTHb031781@zion.cs.uiuc.edu> Author: efriedma Date: Sat May 9 03:40:15 2009 New Revision: 71352 URL: http://llvm.org/viewvc/llvm-project?rev=71352&view=rev Log: Remove a completed optimization. Add a potential optimization I ran into. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=71352&r1=71351&r2=71352&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sat May 9 03:40:15 2009 @@ -909,23 +909,6 @@ //===---------------------------------------------------------------------===// -SROA is not promoting the union on the stack in this example, we should end -up with no allocas. - -union vec2d { - double e[2]; - double v __attribute__((vector_size(16))); -}; -typedef union vec2d vec2d; - -static vec2d a={{1,2}}, b={{3,4}}; - -vec2d foo () { - return (vec2d){ .v = a.v + b.v * (vec2d){{5,5}}.v }; -} - -//===---------------------------------------------------------------------===// - Better mod/ref analysis for scanf would allow us to eliminate the vtable and a bunch of other stuff from this example (see PR1604): @@ -1725,3 +1708,12 @@ stuff much more precise. //===---------------------------------------------------------------------===// + +The following functions should be optimized to use a select instead of a +branch (from gcc PR40072): + +char char_int(int m) {if(m>7) return 0; return m;} +int int_char(char m) {if(m>7) return 0; return m;} + +//===---------------------------------------------------------------------===// + From asl at math.spbu.ru Sat May 9 04:26:48 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sat, 9 May 2009 13:26:48 +0400 (MSD) Subject: [llvm-commits] =?koi8-r?b?W2xsdm1dIHI3MTIzOCAtIC9sbHZtL3RydW5r?= =?koi8-r?b?L2xpYi9Db2RlR2VuL1NlbGVjdGlvbkRBRy9MZWdhbGl6ZURBRy5j?= =?koi8-r?b?cHA=?= Message-ID: <200905090926.n499QmIB053811@star.math.spbu.ru> Hi, Duncan > how about factoring this kind of logic, into a function that > returns the UREM libcall for a given value type, and another > for SREM. Yeah, that's my plan :) -- WBR, Anton Korobeynikov From eli.friedman at gmail.com Sat May 9 07:32:47 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Sat, 09 May 2009 12:32:47 -0000 Subject: [llvm-commits] [llvm] r71354 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll Message-ID: <200905091232.n49CWmUt006860@zion.cs.uiuc.edu> Author: efriedma Date: Sat May 9 07:32:42 2009 New Revision: 71354 URL: http://llvm.org/viewvc/llvm-project?rev=71354&view=rev Log: Allow scalar evolution to compute iteration counts for loops with a pointer-based condition. This fixes PR3171. Added: llvm/trunk/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71354&r1=71353&r2=71354&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Sat May 9 07:32:42 2009 @@ -2372,10 +2372,8 @@ ICmpInst *ExitCond = dyn_cast(ExitBr->getCondition()); - // If it's not an integer comparison then compute it the hard way. - // Note that ICmpInst deals with pointer comparisons too so we must check - // the type of the operand. - if (ExitCond == 0 || isa(ExitCond->getOperand(0)->getType())) + // If it's not an integer or pointer comparison then compute it the hard way. + if (ExitCond == 0) return ComputeBackedgeTakenCountExhaustively(L, ExitBr->getCondition(), ExitBr->getSuccessor(0) == ExitBlock); @@ -2416,21 +2414,12 @@ if (const SCEVConstant *RHSC = dyn_cast(RHS)) if (const SCEVAddRecExpr *AddRec = dyn_cast(LHS)) if (AddRec->getLoop() == L) { - // Form the comparison range using the constant of the correct type so - // that the ConstantRange class knows to do a signed or unsigned - // comparison. - ConstantInt *CompVal = RHSC->getValue(); - const Type *RealTy = ExitCond->getOperand(0)->getType(); - CompVal = dyn_cast( - ConstantExpr::getBitCast(CompVal, RealTy)); - if (CompVal) { - // Form the constant range. - ConstantRange CompRange( - ICmpInst::makeConstantRange(Cond, CompVal->getValue())); + // Form the constant range. + ConstantRange CompRange( + ICmpInst::makeConstantRange(Cond, RHSC->getValue()->getValue())); - SCEVHandle Ret = AddRec->getNumIterationsInRange(CompRange, *this); - if (!isa(Ret)) return Ret; - } + SCEVHandle Ret = AddRec->getNumIterationsInRange(CompRange, *this); + if (!isa(Ret)) return Ret; } switch (Cond) { Added: llvm/trunk/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll?rev=71354&view=auto ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll (added) +++ llvm/trunk/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll Sat May 9 07:32:42 2009 @@ -0,0 +1,27 @@ +; RUN: llvm-as < %s | opt -analyze -scalar-evolution | grep {count is 2} +; PR3171 + + %struct.Foo = type { i32 } + %struct.NonPod = type { [2 x %struct.Foo] } + +define void @_Z3foov() nounwind { +entry: + %x = alloca %struct.NonPod, align 8 ; <%struct.NonPod*> [#uses=2] + %0 = getelementptr %struct.NonPod* %x, i32 0, i32 0 ; <[2 x %struct.Foo]*> [#uses=1] + %1 = getelementptr [2 x %struct.Foo]* %0, i32 1, i32 0 ; <%struct.Foo*> [#uses=1] + br label %bb1.i + +bb1.i: ; preds = %bb2.i, %entry + %.0.i = phi %struct.Foo* [ %1, %entry ], [ %4, %bb2.i ] ; <%struct.Foo*> [#uses=2] + %2 = getelementptr %struct.NonPod* %x, i32 0, i32 0, i32 0 ; <%struct.Foo*> [#uses=1] + %3 = icmp eq %struct.Foo* %.0.i, %2 ; [#uses=1] + br i1 %3, label %_ZN6NonPodD1Ev.exit, label %bb2.i + +bb2.i: ; preds = %bb1.i + %4 = getelementptr %struct.Foo* %.0.i, i32 -1 ; <%struct.Foo*> [#uses=1] + br label %bb1.i + +_ZN6NonPodD1Ev.exit: ; preds = %bb1.i + ret void +} + From nicholas at mxc.ca Sat May 9 11:34:25 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 09 May 2009 09:34:25 -0700 Subject: [llvm-commits] [llvm] r71262 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp In-Reply-To: <200905090857.27046.baldrick@free.fr> References: <200905082058.n48KwdGu026892@zion.cs.uiuc.edu> <200905090857.27046.baldrick@free.fr> Message-ID: <4A05B091.2000109@mxc.ca> Duncan Sands wrote: > Hi Dan, > >> Fix another bug in r71252. This code supports GetElementPtr >> constant exprs as well as instructions. > ... >> - SCEVHandle createNodeForGEP(GetElementPtrInst *GEP); >> + SCEVHandle createNodeForGEP(User *GEP); > > can't you use a Value* here? That covers instructions as > well as constants. Hm? Both Constants and Instructions are derived from User. How does moving to Value help? Nick From baldrick at free.fr Sat May 9 12:00:55 2009 From: baldrick at free.fr (Duncan Sands) Date: Sat, 9 May 2009 19:00:55 +0200 Subject: [llvm-commits] =?iso-8859-1?q?=5Bllvm=5D_r71262_-_in_/llvm/trunk?= =?iso-8859-1?q?=3A=09include/llvm/Analysis/ScalarEvolution=2Eh_lib/Analys?= =?iso-8859-1?q?is/ScalarEvolution=2Ecpp?= In-Reply-To: <4A05B091.2000109@mxc.ca> References: <200905082058.n48KwdGu026892@zion.cs.uiuc.edu> <200905090857.27046.baldrick@free.fr> <4A05B091.2000109@mxc.ca> Message-ID: <200905091900.56045.baldrick@free.fr> > Hm? Both Constants and Instructions are derived from User. How does > moving to Value help? My mistake, I thought Value was derived from User rather than the other way round. Sorry for the noise. Ciao, Duncan. From sabre at nondot.org Sat May 9 13:11:50 2009 From: sabre at nondot.org (Chris Lattner) Date: Sat, 09 May 2009 18:11:50 -0000 Subject: [llvm-commits] [llvm] r71362 - /llvm/trunk/docs/LangRef.html Message-ID: <200905091811.n49IBoOC017517@zion.cs.uiuc.edu> Author: lattner Date: Sat May 9 13:11:50 2009 New Revision: 71362 URL: http://llvm.org/viewvc/llvm-project?rev=71362&view=rev Log: fix typo Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=71362&r1=71361&r2=71362&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Sat May 9 13:11:50 2009 @@ -2240,7 +2240,7 @@ to the 'iftrue' label argument. If "cond" is false, control flows to the 'iffalse' label argument.

    Example:
    -
    Test:
    %cond = icmp eq, i32 %a, %b
    br i1 %cond, label %IfEqual, label %IfUnequal
    IfEqual:
    Test:
    %cond =
    icmp eq i32 %a, %b
    br i1 %cond, label %IfEqual, label %IfUnequal
    IfEqual:
    ret i32 1
    IfUnequal:
    ret i32 0
    From nicholas at mxc.ca Sat May 9 13:41:12 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 09 May 2009 11:41:12 -0700 Subject: [llvm-commits] patch: use CallbackVH for metadata In-Reply-To: References: <4A012B04.9060101@mxc.ca> Message-ID: <4A05CE48.9040609@mxc.ca> Chris Lattner wrote: > On May 5, 2009, at 11:15 PM, Nick Lewycky wrote: > >> This patch switches MDNode to using CallbackVH and adds a special >> typeless "null" keyword that means "(Value*)0" within a metadata >> node. Also change MDNode construction to accept Value* even though >> we don't really permit non-Constant values yet. > > Looks nice. Please split MDNode (and the VH.h #include) out to a new > MDNode.h file. Done. I've attached the updated patch. Okay to commit? > In ElementVH, what is the right behavior when RAUW and delete are > called? Shouldn't these go back through to be recursively uniqued, > like what happens for Constants? The comment block on MDNode says so. ElementVH's delete and RAUW implementations call MDNode::replaceElement which uses MDNode::get to find the replacement and uncheckedReplaceAllUsesWith to affect it. You can see that it works from the last two tests in MetadataTest. Nick -------------- next part -------------- A non-text attachment was scrubbed... Name: metadata-callbackvh2.patch Type: text/x-diff Size: 21322 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090509/817dbefc/attachment.bin From evan.cheng at apple.com Sat May 9 14:18:02 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 09 May 2009 19:18:02 -0000 Subject: [llvm-commits] [llvm] r71363 - /llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Message-ID: <200905091918.n49JI2p3019592@zion.cs.uiuc.edu> Author: evancheng Date: Sat May 9 14:18:01 2009 New Revision: 71363 URL: http://llvm.org/viewvc/llvm-project?rev=71363&view=rev Log: Oops. Don't forget to align single bb loops. Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp?rev=71363&r1=71362&r2=71363&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp (original) +++ llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Sat May 9 14:18:01 2009 @@ -248,7 +248,7 @@ for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), PE = MBB->pred_end(); PI != PE; ++PI) { MachineBasicBlock *PredMBB = *PI; - if (PredMBB->getNumber() > MBB->getNumber()) + if (PredMBB == MBB || PredMBB->getNumber() > MBB->getNumber()) return true; } return false; From kremenek at apple.com Sat May 9 14:19:42 2009 From: kremenek at apple.com (Ted Kremenek) Date: Sat, 09 May 2009 19:19:42 -0000 Subject: [llvm-commits] [llvm] r71365 - /llvm/tags/checker/checker-0.197/ Message-ID: <200905091919.n49JJg3E019649@zion.cs.uiuc.edu> Author: kremenek Date: Sat May 9 14:19:41 2009 New Revision: 71365 URL: http://llvm.org/viewvc/llvm-project?rev=71365&view=rev Log: Removing checker-0.197. Removed: llvm/tags/checker/checker-0.197/ From kremenek at apple.com Sat May 9 14:19:59 2009 From: kremenek at apple.com (Ted Kremenek) Date: Sat, 09 May 2009 19:19:59 -0000 Subject: [llvm-commits] [llvm] r71367 - /llvm/tags/checker/checker-0.197/ Message-ID: <200905091919.n49JJxMD019678@zion.cs.uiuc.edu> Author: kremenek Date: Sat May 9 14:19:59 2009 New Revision: 71367 URL: http://llvm.org/viewvc/llvm-project?rev=71367&view=rev Log: Tagging checker-0.197. Added: llvm/tags/checker/checker-0.197/ - copied from r71366, llvm/trunk/ From isanbard at gmail.com Sat May 9 18:51:36 2009 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 09 May 2009 23:51:36 -0000 Subject: [llvm-commits] [llvm] r71370 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200905092351.n49NpbFR027804@zion.cs.uiuc.edu> Author: void Date: Sat May 9 18:51:35 2009 New Revision: 71370 URL: http://llvm.org/viewvc/llvm-project?rev=71370&view=rev Log: A debug function start was not being recorded when the optimization level wasn't None. However, we were always recording the region end. There's no longer a good reason for this code to be separated out between the different opt levels, as it was doing pretty much the same thing anyway. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=71370&r1=71369&r2=71370&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Sat May 9 18:51:35 2009 @@ -3960,70 +3960,46 @@ return 0; MachineFunction &MF = DAG.getMachineFunction(); - if (OptLevel == CodeGenOpt::None) { - // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what - // (most?) gdb expects. - DebugLoc PrevLoc = CurDebugLoc; - DISubprogram Subprogram(cast(SP)); - DICompileUnit CompileUnit = Subprogram.getCompileUnit(); - - if (!Subprogram.describes(MF.getFunction())) { - // This is a beginning of an inlined function. - - // If llvm.dbg.func.start is seen in a new block before any - // llvm.dbg.stoppoint intrinsic then the location info is unknown. - // FIXME : Why DebugLoc is reset at the beginning of each block ? - if (PrevLoc.isUnknown()) - return 0; - - // Record the source line. - unsigned Line = Subprogram.getLineNumber(); - setCurDebugLoc(DebugLoc::get( - MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0))); - if (DW && DW->ShouldEmitDwarfDebug()) { - DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); - unsigned LabelID = DW->RecordInlinedFnStart(Subprogram, - DICompileUnit(PrevLocTpl.CompileUnit), - PrevLocTpl.Line, - PrevLocTpl.Col); - DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), - getRoot(), LabelID)); - } - } else { - // Record the source line. - unsigned Line = Subprogram.getLineNumber(); - MF.setDefaultDebugLoc(DebugLoc::get( - MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0))); - if (DW && DW->ShouldEmitDwarfDebug()) { - // llvm.dbg.func_start also defines beginning of function scope. - DW->RecordRegionStart(cast(FSI.getSubprogram())); - } - } - } else { - DISubprogram Subprogram(cast(SP)); - - std::string SPName; - Subprogram.getLinkageName(SPName); - if (!SPName.empty() - && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) { - // This is beginning of inlined function. Debugging information for - // inlined function is not handled yet (only supported by FastISel). + // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what + // (most?) gdb expects. + DebugLoc PrevLoc = CurDebugLoc; + DISubprogram Subprogram(cast(SP)); + DICompileUnit CompileUnit = Subprogram.getCompileUnit(); + + if (!Subprogram.describes(MF.getFunction())) { + // This is a beginning of an inlined function. + + // If llvm.dbg.func.start is seen in a new block before any + // llvm.dbg.stoppoint intrinsic then the location info is unknown. + // FIXME : Why DebugLoc is reset at the beginning of each block ? + if (PrevLoc.isUnknown()) return 0; - } - // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is - // what (most?) gdb expects. - DICompileUnit CompileUnit = Subprogram.getCompileUnit(); - - // Record the source line but does not create a label for the normal - // function start. It will be emitted at asm emission time. However, - // create a label if this is a beginning of inlined function. + // Record the source line. unsigned Line = Subprogram.getLineNumber(); setCurDebugLoc(DebugLoc::get( MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0))); - // FIXME - Start new region because llvm.dbg.func_start also defines - // beginning of function scope. + + if (DW && DW->ShouldEmitDwarfDebug()) { + DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); + unsigned LabelID = + DW->RecordInlinedFnStart(Subprogram, + DICompileUnit(PrevLocTpl.CompileUnit), + PrevLocTpl.Line, + PrevLocTpl.Col); + DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), + getRoot(), LabelID)); + } + } else { + // Record the source line. + unsigned Line = Subprogram.getLineNumber(); + MF.setDefaultDebugLoc(DebugLoc::get( + MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0))); + if (DW && DW->ShouldEmitDwarfDebug()) { + // llvm.dbg.func_start also defines beginning of function scope. + DW->RecordRegionStart(cast(FSI.getSubprogram())); + } } return 0; From isanbard at gmail.com Sat May 9 19:10:50 2009 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 10 May 2009 00:10:50 -0000 Subject: [llvm-commits] [llvm] r71373 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200905100010.n4A0AogI028985@zion.cs.uiuc.edu> Author: void Date: Sat May 9 19:10:50 2009 New Revision: 71373 URL: http://llvm.org/viewvc/llvm-project?rev=71373&view=rev Log: --- Reverse-merging r71370 into '.': U lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Revert r71370. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=71373&r1=71372&r2=71373&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Sat May 9 19:10:50 2009 @@ -3960,46 +3960,70 @@ return 0; MachineFunction &MF = DAG.getMachineFunction(); + if (OptLevel == CodeGenOpt::None) { + // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what + // (most?) gdb expects. + DebugLoc PrevLoc = CurDebugLoc; + DISubprogram Subprogram(cast(SP)); + DICompileUnit CompileUnit = Subprogram.getCompileUnit(); + + if (!Subprogram.describes(MF.getFunction())) { + // This is a beginning of an inlined function. + + // If llvm.dbg.func.start is seen in a new block before any + // llvm.dbg.stoppoint intrinsic then the location info is unknown. + // FIXME : Why DebugLoc is reset at the beginning of each block ? + if (PrevLoc.isUnknown()) + return 0; + + // Record the source line. + unsigned Line = Subprogram.getLineNumber(); + setCurDebugLoc(DebugLoc::get( + MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0))); - // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what - // (most?) gdb expects. - DebugLoc PrevLoc = CurDebugLoc; - DISubprogram Subprogram(cast(SP)); - DICompileUnit CompileUnit = Subprogram.getCompileUnit(); - - if (!Subprogram.describes(MF.getFunction())) { - // This is a beginning of an inlined function. - - // If llvm.dbg.func.start is seen in a new block before any - // llvm.dbg.stoppoint intrinsic then the location info is unknown. - // FIXME : Why DebugLoc is reset at the beginning of each block ? - if (PrevLoc.isUnknown()) + if (DW && DW->ShouldEmitDwarfDebug()) { + DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); + unsigned LabelID = DW->RecordInlinedFnStart(Subprogram, + DICompileUnit(PrevLocTpl.CompileUnit), + PrevLocTpl.Line, + PrevLocTpl.Col); + DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), + getRoot(), LabelID)); + } + } else { + // Record the source line. + unsigned Line = Subprogram.getLineNumber(); + MF.setDefaultDebugLoc(DebugLoc::get( + MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0))); + if (DW && DW->ShouldEmitDwarfDebug()) { + // llvm.dbg.func_start also defines beginning of function scope. + DW->RecordRegionStart(cast(FSI.getSubprogram())); + } + } + } else { + DISubprogram Subprogram(cast(SP)); + + std::string SPName; + Subprogram.getLinkageName(SPName); + if (!SPName.empty() + && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) { + // This is beginning of inlined function. Debugging information for + // inlined function is not handled yet (only supported by FastISel). return 0; + } - // Record the source line. + // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is + // what (most?) gdb expects. + DICompileUnit CompileUnit = Subprogram.getCompileUnit(); + + // Record the source line but does not create a label for the normal + // function start. It will be emitted at asm emission time. However, + // create a label if this is a beginning of inlined function. unsigned Line = Subprogram.getLineNumber(); setCurDebugLoc(DebugLoc::get( MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0))); - - if (DW && DW->ShouldEmitDwarfDebug()) { - DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc); - unsigned LabelID = - DW->RecordInlinedFnStart(Subprogram, - DICompileUnit(PrevLocTpl.CompileUnit), - PrevLocTpl.Line, - PrevLocTpl.Col); - DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), - getRoot(), LabelID)); - } - } else { - // Record the source line. - unsigned Line = Subprogram.getLineNumber(); - MF.setDefaultDebugLoc(DebugLoc::get( - MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0))); - if (DW && DW->ShouldEmitDwarfDebug()) { - // llvm.dbg.func_start also defines beginning of function scope. - DW->RecordRegionStart(cast(FSI.getSubprogram())); - } + // FIXME - Start new region because llvm.dbg.func_start also defines + // beginning of function scope. } return 0; From evan.cheng at apple.com Sat May 9 20:54:21 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 10 May 2009 01:54:21 -0000 Subject: [llvm-commits] [test-suite] r71374 - /test-suite/trunk/Makefile.rules Message-ID: <200905100154.n4A1sL24002606@zion.cs.uiuc.edu> Author: evancheng Date: Sat May 9 20:54:21 2009 New Revision: 71374 URL: http://llvm.org/viewvc/llvm-project?rev=71374&view=rev Log: Run llc / lli at -O3 to match gcc optimization level. Modified: test-suite/trunk/Makefile.rules Modified: test-suite/trunk/Makefile.rules URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.rules?rev=71374&r1=71373&r2=71374&view=diff ============================================================================== --- test-suite/trunk/Makefile.rules (original) +++ test-suite/trunk/Makefile.rules Sat May 9 20:54:21 2009 @@ -354,6 +354,10 @@ CFLAGS += -mieee endif +# Set llc / lli optimization level to -O3 to match gcc. +LLC_OPTFLAGS := -O3 +LLI_OPTFLAGS := -O3 + # gcc / llvm-gcc default is -fPIC -fno-omit-frame-pointer # llc / lli default is equal to -mdynamic-no-pic -fomit-frame-pointer ifdef PIC_CODEGEN From nicholas at mxc.ca Sat May 9 23:44:02 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 09 May 2009 21:44:02 -0700 Subject: [llvm-commits] fix poolallocate Message-ID: <4A065B92.4000609@mxc.ca> The change from PaddedSize to AllocSize broke the pool-alloc branch. The attached patch makes it build again. Please commit. Nick -------------- next part -------------- A non-text attachment was scrubbed... Name: fix-pa.patch Type: text/x-diff Size: 8356 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090509/f5dfb2a9/attachment.bin From kremenek at apple.com Sun May 10 00:11:37 2009 From: kremenek at apple.com (Ted Kremenek) Date: Sun, 10 May 2009 05:11:37 -0000 Subject: [llvm-commits] [llvm] r71384 - /llvm/tags/checker/checker-0.198/ Message-ID: <200905100511.n4A5BbIm007941@zion.cs.uiuc.edu> Author: kremenek Date: Sun May 10 00:11:37 2009 New Revision: 71384 URL: http://llvm.org/viewvc/llvm-project?rev=71384&view=rev Log: Tagging checker-0.198. Added: llvm/tags/checker/checker-0.198/ - copied from r71383, llvm/trunk/ From sanjiv.gupta at microchip.com Sun May 10 00:23:47 2009 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Sun, 10 May 2009 05:23:47 -0000 Subject: [llvm-commits] [llvm] r71386 - in /llvm/trunk/lib/Target/PIC16: PIC16.h PIC16AsmPrinter.cpp PIC16ISelLowering.cpp PIC16InstrInfo.cpp PIC16MemSelOpt.cpp PIC16TargetAsmInfo.cpp PIC16TargetAsmInfo.h Message-ID: <200905100523.n4A5NlJQ008252@zion.cs.uiuc.edu> Author: sgupta Date: Sun May 10 00:23:47 2009 New Revision: 71386 URL: http://llvm.org/viewvc/llvm-project?rev=71386&view=rev Log: Changed lowering and asmprinter to use ABI Names class called PAN. Modified: llvm/trunk/lib/Target/PIC16/PIC16.h llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h Modified: llvm/trunk/lib/Target/PIC16/PIC16.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16.h?rev=71386&r1=71385&r2=71386&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16.h Sun May 10 00:23:47 2009 @@ -18,6 +18,7 @@ #include "llvm/Target/TargetMachine.h" #include #include +#include #include #include @@ -41,19 +42,22 @@ UGE }; } - // A Central object to manage all ABI naming conventions. - class PIC16ABINames { + // A Central class to manage all ABI naming conventions. + // PAN - [P]ic16 [A]BI [N]ames + class PAN { public: // Map the name of the symbol to its section name. // Current ABI: + // ----------------------------------------------------- + // ALL Names are prefixed with the symobl '@'. // ------------------------------------------------------ // Global variables do not have any '.' in their names. - // they are prefixed with @ // These are maily function names and global variable names. + // Example - @foo, @i // ------------------------------------------------------- // Functions and auto variables. - // Names are mangled as .. - // Where prefix is a special char '@' and id is any one of + // Names are mangled as .. + // Where is '@' and is any one of // the following // .auto. - an automatic var of a function. // .temp. - temproray data of a function. @@ -74,106 +78,218 @@ // To pass args: @sra_i8.args. // To return val: @sra_i8.ret. //---------------------------------------------- + // SECTION Names + // uninitialized globals - @udata..# + // initialized globals - @idata..# + // Function frame - @.frame_section. + // Function autos - @.autos_section. + // Declarations - @section.0 + //---------------------------------------------------------- - enum IDs { + // Tags used to mangle different names. + enum TAGS { PREFIX_SYMBOL, - - FUNC_AUTOS, - FUNC_FRAME, - FUNC_RET, - FUNC_ARGS, - FUNC_TEMPS, + GLOBAL, + STATIC_LOCAL, + AUTOS_LABEL, + FRAME_LABEL, + RET_LABEL, + ARGS_LABEL, + TEMPS_LABEL, LIBCALL, FRAME_SECTION, - AUTOS_SECTION + AUTOS_SECTION, + CODE_SECTION }; - inline static const char *getIDName(IDs id) { - switch (id) { - default: assert(0 && "Unknown id"); + // Textual names of the tags. + inline static const char *getTagName(TAGS tag) { + switch (tag) { + default: return ""; case PREFIX_SYMBOL: return "@"; - case FUNC_AUTOS: return ".auto."; - case FUNC_FRAME: return ".frame."; - case FUNC_TEMPS: return ".temp."; - case FUNC_ARGS: return ".args."; - case FUNC_RET: return ".ret."; - case FRAME_SECTION: return "fpdata"; - case AUTOS_SECTION: return "fadata"; + case AUTOS_LABEL: return ".auto."; + case FRAME_LABEL: return ".frame."; + case TEMPS_LABEL: return ".temp."; + case ARGS_LABEL: return ".args."; + case RET_LABEL: return ".ret."; + case LIBCALL: return ".lib."; + case FRAME_SECTION: return ".fpdata."; + case AUTOS_SECTION: return ".fadata."; + case CODE_SECTION: return "code"; } } - inline static IDs getID(const std::string &Sym) { - if (Sym.find(getIDName(FUNC_TEMPS))) - return FUNC_TEMPS; + // Get tag type for the Symbol. + inline static TAGS getSymbolTag(const std::string &Sym) { + if (Sym.find(getTagName(TEMPS_LABEL)) != std::string::npos) + return TEMPS_LABEL; - if (Sym.find(getIDName(FUNC_FRAME))) - return FUNC_FRAME; + if (Sym.find(getTagName(FRAME_LABEL)) != std::string::npos) + return FRAME_LABEL; - if (Sym.find(getIDName(FUNC_RET))) - return FUNC_RET; + if (Sym.find(getTagName(RET_LABEL)) != std::string::npos) + return RET_LABEL; - if (Sym.find(getIDName(FUNC_ARGS))) - return FUNC_ARGS; + if (Sym.find(getTagName(ARGS_LABEL)) != std::string::npos) + return ARGS_LABEL; - if (Sym.find(getIDName(FUNC_AUTOS))) - return FUNC_AUTOS; + if (Sym.find(getTagName(AUTOS_LABEL)) != std::string::npos) + return AUTOS_LABEL; - if (Sym.find(getIDName(LIBCALL))) + if (Sym.find(getTagName(LIBCALL)) != std::string::npos) return LIBCALL; - // It does not have any ID. So its a global. - assert (0 && "Could not determine ID symbol type"); + // It does not have any Tag. So its a true global or static local. + if (Sym.find(".") == std::string::npos) + return GLOBAL; + + // If a . is there, then it may be static local. + // We should mangle these as well in clang. + if (Sym.find(".") != std::string::npos) + return STATIC_LOCAL; + + assert (0 && "Could not determine Symbol's tag"); } - // Get func name from a mangled name. + // addPrefix - add prefix symbol to a name if there isn't one already. + inline static std::string addPrefix (const std::string &Name) { + std::string prefix = getTagName (PREFIX_SYMBOL); + + // If this name already has a prefix, nothing to do. + if (Name.compare(0, prefix.size(), prefix) == 0) + return Name; + + return prefix + Name; + } + + // Get mangled func name from a mangled sym name. // In all cases func name is the first component before a '.'. - static inline std::string getFuncNameForSym(const std::string &Sym) { - const char *prefix = getIDName (PREFIX_SYMBOL); + static inline std::string getFuncNameForSym(const std::string &Sym1) { + assert (getSymbolTag(Sym1) != GLOBAL && "not belongs to a function"); - // If this name has a prefix, func name start after prfix in that case. - size_t func_name_start = 0; - if (Sym.find(prefix, 0, strlen(prefix)) != std::string::npos) - func_name_start = strlen(prefix); + std::string Sym = addPrefix(Sym1); // Position of the . after func name. That's where func name ends. - size_t func_name_end = Sym.find ('.', func_name_start); + size_t func_name_end = Sym.find ('.'); + + return Sym.substr (0, func_name_end); + } + + // Get Frame start label for a func. + static std::string getFrameLabel(const std::string &Func) { + std::string Func1 = addPrefix(Func); + std::string tag = getTagName(FRAME_LABEL); + return Func1 + tag; + } + + static std::string getRetvalLabel(const std::string &Func) { + std::string Func1 = addPrefix(Func); + std::string tag = getTagName(RET_LABEL); + return Func1 + tag; + } + + static std::string getArgsLabel(const std::string &Func) { + std::string Func1 = addPrefix(Func); + std::string tag = getTagName(ARGS_LABEL); + return Func1 + tag; + } + + static std::string getTempdataLabel(const std::string &Func) { + std::string Func1 = addPrefix(Func); + std::string tag = getTagName(TEMPS_LABEL); + return Func1 + tag; + } + + static std::string getFrameSectionName(const std::string &Func) { + std::string Func1 = addPrefix(Func); + std::string tag = getTagName(FRAME_SECTION); + return Func1 + tag + " UDATA_OVR"; + } + + static std::string getAutosSectionName(const std::string &Func) { + std::string Func1 = addPrefix(Func); + std::string tag = getTagName(AUTOS_SECTION); + return Func1 + tag + " UDATA_OVR"; + } + + static std::string getCodeSectionName(const std::string &Func) { + std::string Func1 = addPrefix(Func); + std::string tag = getTagName(CODE_SECTION); + return Func1 + tag + " CODE"; + } + + // udata and idata section names are generated by a given number. + // @udata..# + static std::string getUdataSectionName(unsigned num) { + std::ostringstream o; + o << getTagName(PREFIX_SYMBOL) << "udata." << num << ".# UDATA"; + return o.str(); + } + + static std::string getIdataSectionName(unsigned num) { + std::ostringstream o; + o << getTagName(PREFIX_SYMBOL) << "idata." << num << ".# IDATA"; + return o.str(); + } - return Sym.substr (func_name_start, func_name_end); + inline static bool isLocalName (const std::string &Name) { + if (getSymbolTag(Name) == AUTOS_LABEL) + return true; + + return false; } - // Form a section name given the section type and func name. - static std::string - getSectionNameForFunc (const std::string &Fname, const IDs sec_id) { - std::string sec_id_string = getIDName(sec_id); - return sec_id_string + "." + Fname + ".#"; + inline static bool isLocalToFunc (std::string &Func, std::string &Var) { + if (! isLocalName(Var)) return false; + + std::string Func1 = addPrefix(Func); + // Extract func name of the varilable. + const std::string &fname = getFuncNameForSym(Var); + + if (fname.compare(Func1) == 0) + return true; + + return false; } + // Get the section for the given external symbol names. - // This tries to find the type (ID) of the symbol from its mangled name + // This tries to find the type (Tag) of the symbol from its mangled name // and return appropriate section name for it. - static inline std::string getSectionNameForSym(const std::string &Sym) { + static inline std::string getSectionNameForSym(const std::string &Sym1) { + std::string Sym = addPrefix(Sym1); + std::string SectionName; - IDs id = getID (Sym); std::string Fname = getFuncNameForSym (Sym); + TAGS id = getSymbolTag (Sym); switch (id) { default : assert (0 && "Could not determine external symbol type"); - case FUNC_FRAME: - case FUNC_RET: - case FUNC_TEMPS: - case FUNC_ARGS: { - return getSectionNameForFunc (Fname, FRAME_SECTION); + case FRAME_LABEL: + case RET_LABEL: + case TEMPS_LABEL: + case ARGS_LABEL: { + return getFrameSectionName(Fname); } - case FUNC_AUTOS: { - return getSectionNameForFunc (Fname, AUTOS_SECTION); + case AUTOS_LABEL: { + return getAutosSectionName(Fname); } } } - }; // class PIC16ABINames. + }; // class PAN. + + + // External symbol names require memory to live till the program end. + // So we have to allocate it and keep. + inline static const char *createESName (const std::string &name) { + char *tmpName = new char[name.size() + 1]; + strcpy (tmpName, name.c_str()); + return tmpName; + } @@ -218,7 +334,6 @@ bool Verbose); // Banksel optimzer pass. FunctionPass *createPIC16MemSelOptimizerPass(); - std::string getSectionNameForSym(const std::string &Sym); } // end namespace llvm; // Defines symbolic names for PIC16 registers. This defines a mapping from Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp?rev=71386&r1=71385&r2=71386&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp Sun May 10 00:23:47 2009 @@ -28,22 +28,6 @@ #include "PIC16GenAsmWriter.inc" -inline static bool isLocalToFunc (std::string &FuncName, std::string &VarName) { - if (VarName.find(FuncName + ".auto.") != std::string::npos - || VarName.find(FuncName + ".arg.") != std::string::npos) - return true; - - return false; -} - -inline static bool isLocalName (std::string &Name) { - if (Name.find(".auto.") != std::string::npos - || Name.find(".arg.") != std::string::npos) - return true; - - return false; -} - bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) { printInstruction(MI); return true; @@ -65,18 +49,20 @@ // Emit the function variables. emitFunctionData(MF); - std::string codeSection; - codeSection = "code." + CurrentFnName + ".# " + "CODE"; - const Section *fCodeSection = TAI->getNamedSection(codeSection.c_str(), - SectionFlags::Code); + const char *codeSection = PAN::getCodeSectionName(CurrentFnName).c_str(); + + const Section *fCodeSection = TAI->getNamedSection(codeSection, + SectionFlags::Code); O << "\n"; + // Start the Code Section. SwitchToSection (fCodeSection); // Emit the frame address of the function at the beginning of code. - O << " retlw low(" << FunctionLabelBegin<< CurrentFnName << ".frame.)\n"; - O << " retlw high(" << FunctionLabelBegin<< CurrentFnName << ".frame.)\n"; - O << CurrentFnName << ":\n"; + O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnName) << ")\n"; + O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnName) << ")\n"; + // Emit function start label. + O << CurrentFnName << ":\n"; // Print out code for the function. for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); @@ -136,19 +122,12 @@ return; case MachineOperand::MO_GlobalAddress: { - std::string Name = Mang->getValueName(MO.getGlobal()); - if (isLocalName(Name)) - O << FunctionLabelBegin << Mang->getValueName(MO.getGlobal()); - else - O << Mang->getValueName(MO.getGlobal()); + O << Mang->getValueName(MO.getGlobal()); break; } case MachineOperand::MO_ExternalSymbol: { std::string Name = MO.getSymbolName(); - if (Name.find("__intrinsics.") != std::string::npos) - O << MO.getSymbolName(); - else - O << FunctionLabelBegin << MO.getSymbolName(); + O << MO.getSymbolName(); break; } case MachineOperand::MO_MachineBasicBlock: @@ -189,41 +168,44 @@ O << "section.0" <<"\n"; for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) { std::string Name = Mang->getValueName(I); - if (Name.compare("abort") == 0) + if (Name.compare("@abort") == 0) continue; // If it is llvm intrinsic call then don't emit if (Name.find("llvm.") != std::string::npos) continue; - if (I->isDeclaration()) { - O << "\textern " <hasExternalLinkage()) { - O << "\tglobal " << Name << "\n"; - O << "\tglobal " << FunctionLabelBegin << Name << ".ret.\n"; - O << "\tglobal " << FunctionLabelBegin<< Name << ".args.\n"; - } + assert ((I->isDeclaration() || I->hasExternalLinkage()) + && "Not an extern function declaration or definition"); + + const char *directive = I->isDeclaration() ? TAI->getExternDirective() : + TAI->getGlobalDirective(); + + O << directive << Name << "\n"; + O << directive << PAN::getRetvalLabel(Name) << "\n"; + O << directive << PAN::getArgsLabel(Name) << "\n"; } // Emit header file to include declaration of library functions + // FIXME: find out libcall names. O << "\t#include C16IntrinsicCalls.INC\n"; - // Emit declarations for external globals. + // Emit declarations for external variable declarations and definitions. for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; I++) { // Any variables reaching here with ".auto." in its name is a local scope // variable and should not be printed in global data section. std::string Name = Mang->getValueName(I); - if (isLocalName (Name)) + if (PAN::isLocalName(Name)) continue; - if (I->isDeclaration()) - O << "\textern "<< Name << "\n"; - else if (I->hasCommonLinkage() || I->hasExternalLinkage()) - O << "\tglobal "<< Name << "\n"; + if (!(I->isDeclaration() || I->hasExternalLinkage() || + I->hasCommonLinkage())) + continue; + + const char *directive = I->isDeclaration() ? TAI->getExternDirective() : + TAI->getGlobalDirective(); + O << directive << Name << "\n"; } } @@ -247,7 +229,7 @@ // Any variables reaching here with "." in its name is a local scope // variable and should not be printed in global data section. std::string name = Mang->getValueName(I); - if (name.find(".") != std::string::npos) + if (PAN::isLocalName(name)) continue; I->setSection(TAI->getReadOnlySection()->getName()); @@ -273,15 +255,14 @@ unsigned FrameSize = 0; // Emit the data section name. O << "\n"; - std::string SectionName = "fpdata." + CurrentFnName + ".# " + "UDATA_OVR"; + const char *SectionName = PAN::getFrameSectionName(CurrentFnName).c_str(); - const Section *fPDataSection = TAI->getNamedSection(SectionName.c_str(), + const Section *fPDataSection = TAI->getNamedSection(SectionName, SectionFlags::Writeable); SwitchToSection(fPDataSection); - // Emit function frame label - O << FunctionLabelBegin << CurrentFnName << ".frame.:\n"; + O << PAN::getFrameLabel(CurrentFnName) << ":\n"; const Type *RetType = F->getReturnType(); unsigned RetSize = 0; @@ -289,11 +270,13 @@ RetSize = TD->getTypeAllocSize(RetType); //Emit function return value space + // FIXME: Do not emit RetvalLable when retsize is zero. To do this + // we will need to avoid printing a global directive for Retval label + // in emitExternandGloblas. if(RetSize > 0) - O << FunctionLabelBegin << CurrentFnName << ".ret. RES " << RetSize - << "\n"; + O << PAN::getRetvalLabel(CurrentFnName) << " RES " << RetSize << "\n"; else - O << FunctionLabelBegin << CurrentFnName << ".ret.:\n"; + O << PAN::getRetvalLabel(CurrentFnName) << ": \n"; // Emit variable to hold the space for function arguments unsigned ArgSize = 0; @@ -302,20 +285,19 @@ const Type *Ty = argi->getType(); ArgSize += TD->getTypeAllocSize(Ty); } - O << FunctionLabelBegin << CurrentFnName << ".args. RES " << ArgSize - << "\n"; + + O << PAN::getArgsLabel(CurrentFnName) << " RES " << ArgSize << "\n"; // Emit temporary space int TempSize = PTLI->GetTmpSize(); if (TempSize > 0 ) - O << FunctionLabelBegin << CurrentFnName << ".temp. RES " << TempSize - <<"\n"; + O << PAN::getTempdataLabel(CurrentFnName) << " RES " << TempSize <<"\n"; // Emit the section name for local variables. O << "\n"; - std::string SecNameLocals = "fadata." + CurrentFnName + ".# " + "UDATA_OVR"; + const char* SecNameLocals = PAN::getAutosSectionName(CurrentFnName).c_str() ; - const Section *fADataSection = TAI->getNamedSection(SecNameLocals.c_str(), + const Section *fADataSection = TAI->getNamedSection(SecNameLocals, SectionFlags::Writeable); SwitchToSection(fADataSection); @@ -334,26 +316,32 @@ // Static local varilabes of a function does not have .auto. in their // name. They are not printed as part of function data but module // level global data. - if (! isLocalToFunc(FuncName, VarName)) + if (! PAN::isLocalToFunc(FuncName, VarName)) continue; - I->setSection("fadata." + CurrentFnName + ".#"); + I->setSection(TAI->SectionForGlobal(I)->getName()); Constant *C = I->getInitializer(); const Type *Ty = C->getType(); unsigned Size = TD->getTypeAllocSize(Ty); FrameSize += Size; // Emit memory reserve directive. - O << FunctionLabelBegin << VarName << " RES " << Size << "\n"; + O << VarName << " RES " << Size << "\n"; } } void PIC16AsmPrinter::EmitGlobalData (Module &M) { + // Set the section names for all globals. + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { + I->setSection(TAI->SectionForGlobal(I)->getName()); + } + const PIC16TargetAsmInfo *PTAI = static_cast(TAI); - const_cast(PTAI)->SetSectionForGVs(M); const TargetData *TD = TM.getTargetData(); - std::vector IDATASections = PTAI->getIDATASections(); + // Now print all IDATA sections. + std::vector IDATASections = PTAI->IDATASections; for (unsigned i = 0; i < IDATASections.size(); i++) { SwitchToSection(IDATASections[i]->S_); std::vector Items = IDATASections[i]->Items; @@ -366,7 +354,8 @@ } } - std::vector BSSSections = PTAI->getBSSSections(); + // Now print all BSS sections. + std::vector BSSSections = PTAI->BSSSections; for (unsigned i = 0; i < BSSSections.size(); i++) { SwitchToSection(BSSSections[i]->S_); std::vector Items = BSSSections[i]->Items; Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=71386&r1=71385&r2=71386&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Sun May 10 00:23:47 2009 @@ -23,12 +23,10 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include using namespace llvm; - // PIC16TargetLowering Constructor. PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM) : TargetLowering(TM), TmpSize(0) { @@ -41,24 +39,24 @@ setShiftAmountFlavor(Extend); // SRA library call names - setPIC16LibcallName(PIC16ISD::SRA_I8, "__intrinsics.sra.i8"); - setLibcallName(RTLIB::SRA_I16, "__intrinsics.sra.i16"); - setLibcallName(RTLIB::SRA_I32, "__intrinsics.sra.i32"); + setPIC16LibcallName(PIC16ISD::SRA_I8, "@__intrinsics.sra.i8"); + setLibcallName(RTLIB::SRA_I16, "@__intrinsics.sra.i16"); + setLibcallName(RTLIB::SRA_I32, "@__intrinsics.sra.i32"); // SHL library call names - setPIC16LibcallName(PIC16ISD::SLL_I8, "__intrinsics.sll.i8"); - setLibcallName(RTLIB::SHL_I16, "__intrinsics.sll.i16"); - setLibcallName(RTLIB::SHL_I32, "__intrinsics.sll.i32"); + setPIC16LibcallName(PIC16ISD::SLL_I8, "@__intrinsics.sll.i8"); + setLibcallName(RTLIB::SHL_I16, "@__intrinsics.sll.i16"); + setLibcallName(RTLIB::SHL_I32, "@__intrinsics.sll.i32"); // SRL library call names - setPIC16LibcallName(PIC16ISD::SRL_I8, "__intrinsics.srl.i8"); - setLibcallName(RTLIB::SRL_I16, "__intrinsics.srl.i16"); - setLibcallName(RTLIB::SRL_I32, "__intrinsics.srl.i32"); + setPIC16LibcallName(PIC16ISD::SRL_I8, "@__intrinsics.srl.i8"); + setLibcallName(RTLIB::SRL_I16, "@__intrinsics.srl.i16"); + setLibcallName(RTLIB::SRL_I32, "@__intrinsics.srl.i32"); // MUL Library call names - setPIC16LibcallName(PIC16ISD::MUL_I8, "__intrinsics.mul.i8"); - setLibcallName(RTLIB::MUL_I16, "__intrinsics.mul.i16"); - setLibcallName(RTLIB::MUL_I32, "__intrinsics.mul.i32"); + setPIC16LibcallName(PIC16ISD::MUL_I8, "@__intrinsics.mul.i8"); + setLibcallName(RTLIB::MUL_I16, "@__intrinsics.mul.i16"); + setLibcallName(RTLIB::MUL_I32, "@__intrinsics.mul.i32"); setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); @@ -529,9 +527,9 @@ // with, we need to traverse all the FrameIndices available earlier in // the list and add their requested size. unsigned FIndex = FR->getIndex(); - char *tmpName = new char [strlen(Name.c_str()) + 8]; + const char *tmpName; if (FIndex < ReservedFrameCount) { - sprintf(tmpName, "%s.frame.", Name.c_str()); + tmpName = createESName(PAN::getFrameLabel(Name)); ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); Offset = 0; for (unsigned i=0; igetObjectSize(FIndex)); } @@ -845,12 +843,11 @@ const Function *Func = MF.getFunction(); const std::string FuncName = Func->getName(); - char *tmpName = new char [strlen(FuncName.c_str()) + 8]; // Put the value on stack. // Get a stack slot index and convert to es. int FI = MF.getFrameInfo()->CreateStackObject(1, 1); - sprintf(tmpName, "%s.temp.", FuncName.c_str()); + const char *tmpName = createESName(PAN::getTempdataLabel(FuncName)); SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); // Store the value to ES. @@ -1064,8 +1061,7 @@ const Function *F = MF.getFunction(); std::string FuncName = F->getName(); - char *tmpName = new char [strlen(FuncName.c_str()) + 8]; - sprintf(tmpName, "%s.frame.", FuncName.c_str()); + const char *tmpName = createESName(PAN::getFrameLabel(FuncName)); SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Other); SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); SDValue BS = DAG.getConstant(1, MVT::i8); @@ -1258,13 +1254,11 @@ } // Label for argument passing - char *argFrame = new char [strlen(Name.c_str()) + 8]; - sprintf(argFrame, "%s.args.", Name.c_str()); + const char *argFrame = createESName(PAN::getArgsLabel(Name)); ArgLabel = DAG.getTargetExternalSymbol(argFrame, MVT::i8); // Label for reading return value - char *retName = new char [strlen(Name.c_str()) + 8]; - sprintf(retName, "%s.ret.", Name.c_str()); + const char *retName = createESName(PAN::getRetvalLabel(Name)); RetLabel = DAG.getTargetExternalSymbol(retName, MVT::i8); } else { // if indirect call @@ -1460,8 +1454,7 @@ InitReservedFrameCount(F); // Create the .args external symbol. - char *tmpName = new char [strlen(FuncName.c_str()) + 8]; - sprintf(tmpName, "%s.args.", FuncName.c_str()); + const char *tmpName = createESName(PAN::getArgsLabel(FuncName)); SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); // Load arg values from the label + offset. Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp?rev=71386&r1=71385&r2=71386&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp Sun May 10 00:23:47 2009 @@ -76,8 +76,7 @@ const Function *Func = MBB.getParent()->getFunction(); const std::string FuncName = Func->getName(); - char *tmpName = new char [strlen(FuncName.c_str()) + 10]; - sprintf(tmpName, "%s.temp.", FuncName.c_str()); + const char *tmpName = createESName(PAN::getTempdataLabel(FuncName)); // On the order of operands here: think "movwf SrcReg, tmp_slot, offset". if (RC == PIC16::GPRRegisterClass) { @@ -119,8 +118,7 @@ const Function *Func = MBB.getParent()->getFunction(); const std::string FuncName = Func->getName(); - char *tmpName = new char [strlen(FuncName.c_str()) + 10]; - sprintf(tmpName, "%s.temp.", FuncName.c_str()); + const char *tmpName = createESName(PAN::getTempdataLabel(FuncName)); // On the order of operands here: think "movf FrameIndex, W". if (RC == PIC16::GPRRegisterClass) { Modified: llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp?rev=71386&r1=71385&r2=71386&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp Sun May 10 00:23:47 2009 @@ -145,7 +145,7 @@ // External Symbol is generated for temp data and arguments. They are // in fpdata..# section. std::string Sym = Op.getSymbolName(); - NewBank = PIC16ABINames::getSectionNameForSym(Sym); + NewBank = PAN::getSectionNameForSym(Sym); } // If the previous and new section names are same, we don't need to Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp?rev=71386&r1=71385&r2=71386&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp Sun May 10 00:23:47 2009 @@ -23,6 +23,10 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM) : TargetAsmInfo(TM) { CommentString = ";"; + GlobalPrefix = PAN::getTagName(PAN::PREFIX_SYMBOL); + GlobalDirective = "\tglobal\t"; + ExternDirective = "\textern\t"; + Data8bitsDirective = " db "; Data16bitsDirective = " dw "; Data32bitsDirective = " dl "; @@ -86,9 +90,8 @@ // No BSS section spacious enough was found. Crate a new one. if (! FoundBSS) { - char *name = new char[32]; - sprintf (name, "udata.%d.# UDATA", (int)BSSSections.size()); - const Section *NewSection = getNamedSection (name); + std::string name = PAN::getUdataSectionName(BSSSections.size()); + const Section *NewSection = getNamedSection (name.c_str()); FoundBSS = new PIC16Section(NewSection); @@ -132,9 +135,8 @@ // No IDATA section spacious enough was found. Crate a new one. if (! FoundIDATA) { - char *name = new char[32]; - sprintf (name, "idata.%d.# IDATA", (int)IDATASections.size()); - const Section *NewSection = getNamedSection (name); + std::string name = PAN::getIdataSectionName(IDATASections.size()); + const Section *NewSection = getNamedSection (name.c_str()); FoundIDATA = new PIC16Section(NewSection); @@ -158,19 +160,20 @@ PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1) const { // We select the section based on the initializer here, so it really // has to be a GlobalVariable. - if (!isa(GV1)) + const GlobalVariable *GV = dyn_cast(GV1); + if (!GV1 || ! GV->hasInitializer()) return TargetAsmInfo::SelectSectionForGlobal(GV1); - const GlobalVariable *GV = dyn_cast(GV1); - // We are only dealing with true globals here. So names with a "." - // are local globals. Also declarations are not entertained. - std::string name = GV->getName(); - if (name.find(".auto.") != std::string::npos - || name.find(".arg.") != std::string::npos || !GV->hasInitializer()) - return TargetAsmInfo::SelectSectionForGlobal(GV); + // First, if this is an automatic variable for a function, get the section + // name for it and return. + const std::string name = GV->getName(); + if (PAN::isLocalName(name)) { + const std::string Sec_Name = PAN::getSectionNameForSym(name); + return getNamedSection(Sec_Name.c_str()); + } - const Constant *C = GV->getInitializer(); // See if this is an uninitialized global. + const Constant *C = GV->getInitializer(); if (C->isNullValue()) return getBSSSectionForGlobal(GV); @@ -178,30 +181,11 @@ if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) return getIDATASectionForGlobal(GV); + // Else let the default implementation take care of it. return TargetAsmInfo::SelectSectionForGlobal(GV); } -void PIC16TargetAsmInfo::SetSectionForGVs(Module &M) { - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - if (!I->hasInitializer()) // External global require no code. - continue; - - // Any variables reaching here with "." in its name is a local scope - // variable and should not be printed in global data section. - std::string name = I->getName(); - if (name.find(".auto.") != std::string::npos - || name.find(".args.") != std::string::npos) - continue; - int AddrSpace = I->getType()->getAddressSpace(); - - if (AddrSpace == PIC16ISD::RAM_SPACE) - I->setSection(SectionForGlobal(I)->getName()); - } -} - - PIC16TargetAsmInfo::~PIC16TargetAsmInfo() { for (unsigned i = 0; i < BSSSections.size(); i++) { Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h?rev=71386&r1=71385&r2=71386&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h Sun May 10 00:23:47 2009 @@ -41,11 +41,11 @@ struct PIC16TargetAsmInfo : public TargetAsmInfo { std::string getSectionNameForSym(const std::string &Sym) const; PIC16TargetAsmInfo(const PIC16TargetMachine &TM); - virtual ~PIC16TargetAsmInfo(); - private: mutable std::vector BSSSections; mutable std::vector IDATASections; - + virtual ~PIC16TargetAsmInfo(); + + private: const char *RomData8bitsDirective; const char *RomData16bitsDirective; const char *RomData32bitsDirective; From kremenek at apple.com Sun May 10 01:26:17 2009 From: kremenek at apple.com (Ted Kremenek) Date: Sun, 10 May 2009 06:26:17 -0000 Subject: [llvm-commits] [llvm] r71389 - /llvm/tags/checker/checker-0.199/ Message-ID: <200905100626.n4A6QHAi009803@zion.cs.uiuc.edu> Author: kremenek Date: Sun May 10 01:26:17 2009 New Revision: 71389 URL: http://llvm.org/viewvc/llvm-project?rev=71389&view=rev Log: Tagging checker-0.199. Added: llvm/tags/checker/checker-0.199/ - copied from r71388, llvm/trunk/ From nicolas.geoffray at lip6.fr Sun May 10 04:56:33 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Sun, 10 May 2009 11:56:33 +0200 Subject: [llvm-commits] [llvm] r71349 - in /llvm/trunk: bindings/ocaml/target/ include/llvm-c/ include/llvm/Target/ lib/Analysis/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/ExecutionEngine/ lib/ExecutionEngine/Interpreter/ lib/ExecutionEngine/JIT/ lib/Target/ lib/Target/ARM/ lib/Target/ARM/AsmPrinter/ lib/Target/Alpha/AsmPrinter/ lib/Target/CBackend/ lib/Target/CellSPU/AsmPrinter/ lib/Target/IA64/AsmPrinter/ lib/Target/MSIL/ lib/Target/Mips/ lib/Target/Mips/AsmPrinter/ lib/Target/PIC16/ lib/Target/PowerP... In-Reply-To: <88CB4A97-1D38-48EF-BE64-766B32075CFC@gmail.com> References: <200905090706.n4976n4F018353@zion.cs.uiuc.edu> <200905090940.10103.baldrick@free.fr> <88CB4A97-1D38-48EF-BE64-766B32075CFC@gmail.com> Message-ID: <4A06A4D1.70601@lip6.fr> Do we have a BreakageNotes somewhere for the next version of LLVM? It'd be nice to remember that getTypePaddedSize now is getTypeAllocSize, so that tools following LLVM releases won't have to figure that by themselves. Nicolas Bill Wendling wrote: > On May 9, 2009, at 12:40 AM, Duncan Sands wrote: > > >> Hi Bill, >> >> >>> Please make the appropriate changes in llvm-gcc. Thanks! >>> >> I did of course, but "svn commit" took a long time to complete >> (heavy system load). Sorry for the breakage. >> >> > Thanks! > > -bw > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From asl at math.spbu.ru Sun May 10 09:48:44 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sun, 10 May 2009 14:48:44 -0000 Subject: [llvm-commits] [llvm] r71392 - in /llvm/trunk/test/CodeGen/MSP430: ./ 2009-05-10-CyclicDAG.ll dg.exp Message-ID: <200905101448.n4AEmkpI026745@zion.cs.uiuc.edu> Author: asl Date: Sun May 10 09:48:36 2009 New Revision: 71392 URL: http://llvm.org/viewvc/llvm-project?rev=71392&view=rev Log: Add MSP430 test for PR4136 Added: llvm/trunk/test/CodeGen/MSP430/ llvm/trunk/test/CodeGen/MSP430/2009-05-10-CyclicDAG.ll llvm/trunk/test/CodeGen/MSP430/dg.exp Added: llvm/trunk/test/CodeGen/MSP430/2009-05-10-CyclicDAG.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MSP430/2009-05-10-CyclicDAG.ll?rev=71392&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/MSP430/2009-05-10-CyclicDAG.ll (added) +++ llvm/trunk/test/CodeGen/MSP430/2009-05-10-CyclicDAG.ll Sun May 10 09:48:36 2009 @@ -0,0 +1,32 @@ +; RUN: llvm-as < %s | llc +; PR4136 + +target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8" +target triple = "msp430-unknown-linux-gnu" + at uip_len = external global i16 ; [#uses=2] + +define void @uip_arp_arpin() nounwind { +entry: + %tmp = volatile load i16* @uip_len ; [#uses=1] + %cmp = icmp ult i16 %tmp, 42 ; [#uses=1] + volatile store i16 0, i16* @uip_len + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + ret void + +if.end: ; preds = %entry + switch i16 0, label %return [ + i16 256, label %sw.bb + i16 512, label %sw.bb18 + ] + +sw.bb: ; preds = %if.end + ret void + +sw.bb18: ; preds = %if.end + ret void + +return: ; preds = %if.end + ret void +} Added: llvm/trunk/test/CodeGen/MSP430/dg.exp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MSP430/dg.exp?rev=71392&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/MSP430/dg.exp (added) +++ llvm/trunk/test/CodeGen/MSP430/dg.exp Sun May 10 09:48:36 2009 @@ -0,0 +1,5 @@ +load_lib llvm.exp + +if { [llvm_supports_target MSP430] } { + RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] +} From asl at math.spbu.ru Sun May 10 09:49:01 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sun, 10 May 2009 14:49:01 -0000 Subject: [llvm-commits] [llvm] r71393 - /llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td Message-ID: <200905101449.n4AEn2Pu026765@zion.cs.uiuc.edu> Author: asl Date: Sun May 10 09:49:00 2009 New Revision: 71393 URL: http://llvm.org/viewvc/llvm-project?rev=71393&view=rev Log: Add imm-reg and imm-mem patters for cmp on msp430 (imm is allowed to be source operand, not dest...) Modified: llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td Modified: llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td?rev=71393&r1=71392&r2=71393&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td Sun May 10 09:49:00 2009 @@ -708,6 +708,20 @@ "cmp.w\t{$src1, $src2}", [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>; +def CMP8ir : Pseudo<(outs), (ins i8imm:$src1, GR8:$src2), + "cmp.b\t{$src1, $src2}", + [(MSP430cmp imm:$src1, GR8:$src2), (implicit SRW)]>; +def CMP16ir : Pseudo<(outs), (ins i16imm:$src1, GR16:$src2), + "cmp.w\t{$src1, $src2}", + [(MSP430cmp imm:$src1, GR16:$src2), (implicit SRW)]>; + +def CMP8im : Pseudo<(outs), (ins i8imm:$src1, memsrc:$src2), + "cmp.b\t{$src1, $src2}", + [(MSP430cmp (i8 imm:$src1), (load addr:$src2)), (implicit SRW)]>; +def CMP16im : Pseudo<(outs), (ins i16imm:$src1, memsrc:$src2), + "cmp.w\t{$src1, $src2}", + [(MSP430cmp (i16 imm:$src1), (load addr:$src2)), (implicit SRW)]>; + // FIXME: imm is allowed only on src operand, not on dst. //def CMP8ri : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2), From sanjiv.gupta at microchip.com Sun May 10 11:18:40 2009 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Sun, 10 May 2009 16:18:40 -0000 Subject: [llvm-commits] [llvm] r71394 - /llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp Message-ID: <200905101618.n4AGIegH029326@zion.cs.uiuc.edu> Author: sgupta Date: Sun May 10 11:18:39 2009 New Revision: 71394 URL: http://llvm.org/viewvc/llvm-project?rev=71394&view=rev Log: Module iterator contains list of filescope functions as well, we don't need to emit and global declarations for them. This was working earlier and was broken during one of the recent commit for PIC16 naming. Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp?rev=71394&r1=71393&r2=71394&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp Sun May 10 11:18:39 2009 @@ -175,8 +175,8 @@ if (Name.find("llvm.") != std::string::npos) continue; - assert ((I->isDeclaration() || I->hasExternalLinkage()) - && "Not an extern function declaration or definition"); + if (! (I->isDeclaration() || I->hasExternalLinkage())) + continue; const char *directive = I->isDeclaration() ? TAI->getExternDirective() : TAI->getGlobalDirective(); From kremenek at apple.com Sun May 10 11:53:12 2009 From: kremenek at apple.com (Ted Kremenek) Date: Sun, 10 May 2009 16:53:12 -0000 Subject: [llvm-commits] [llvm] r71400 - /llvm/tags/checker/checker-0.199/ Message-ID: <200905101653.n4AGrDUV030730@zion.cs.uiuc.edu> Author: kremenek Date: Sun May 10 11:53:08 2009 New Revision: 71400 URL: http://llvm.org/viewvc/llvm-project?rev=71400&view=rev Log: Removing checker-0.199. Removed: llvm/tags/checker/checker-0.199/ From kremenek at apple.com Sun May 10 11:50:58 2009 From: kremenek at apple.com (Ted Kremenek) Date: Sun, 10 May 2009 16:50:58 -0000 Subject: [llvm-commits] [llvm] r71395 - /llvm/tags/checker/checker-0.199/ Message-ID: <200905101650.n4AGowN9030640@zion.cs.uiuc.edu> Author: kremenek Date: Sun May 10 11:50:55 2009 New Revision: 71395 URL: http://llvm.org/viewvc/llvm-project?rev=71395&view=rev Log: Removing checker-0.199. Removed: llvm/tags/checker/checker-0.199/ From kremenek at apple.com Sun May 10 11:52:37 2009 From: kremenek at apple.com (Ted Kremenek) Date: Sun, 10 May 2009 16:52:37 -0000 Subject: [llvm-commits] [llvm] r71398 - /llvm/tags/checker/checker-0.199/ Message-ID: <200905101652.n4AGqdrt030702@zion.cs.uiuc.edu> Author: kremenek Date: Sun May 10 11:52:35 2009 New Revision: 71398 URL: http://llvm.org/viewvc/llvm-project?rev=71398&view=rev Log: Tagging checker-0.199. Added: llvm/tags/checker/checker-0.199/ - copied from r71397, llvm/trunk/ From kremenek at apple.com Sun May 10 11:53:34 2009 From: kremenek at apple.com (Ted Kremenek) Date: Sun, 10 May 2009 16:53:34 -0000 Subject: [llvm-commits] [llvm] r71402 - /llvm/tags/checker/checker-0.199/ Message-ID: <200905101653.n4AGraOv030756@zion.cs.uiuc.edu> Author: kremenek Date: Sun May 10 11:53:33 2009 New Revision: 71402 URL: http://llvm.org/viewvc/llvm-project?rev=71402&view=rev Log: Tagging checker-0.199. Added: llvm/tags/checker/checker-0.199/ - copied from r71401, llvm/trunk/ From baldrick at free.fr Sun May 10 12:53:55 2009 From: baldrick at free.fr (Duncan Sands) Date: Sun, 10 May 2009 19:53:55 +0200 Subject: [llvm-commits] =?iso-8859-1?q?=5Bllvm=5D_r71349_-_in_/llvm/trunk?= =?iso-8859-1?q?=3A=09bindings/ocaml/target/_include/llvm-c/_include/llvm/?= =?iso-8859-1?q?Target/=09lib/Analysis/_lib/CodeGen/_lib/CodeGen/AsmPrinte?= =?iso-8859-1?q?r/_lib/CodeGen/SelectionDAG/_lib/ExecutionEngine/=09lib/Ex?= =?iso-8859-1?q?ecutionEngine/Interpreter/_lib/ExecutionEngine/JIT/=09lib/?= =?iso-8859-1?q?Target/_lib/Target/ARM/_lib/Target/ARM/AsmPrinter/_lib/Tar?= =?iso-8859-1?q?get/Alpha/AsmPrinter/_lib/Target/CBackend/=09lib/Target/Ce?= =?iso-8859-1?q?llSPU/AsmPrinter/_lib/Target/IA64/AsmPrinter/=09lib/Target?= =?iso-8859-1?q?/MSIL/_lib/Target/Mips/_lib/Target/Mips/AsmPrinter/_lib/Ta?= =?iso-8859-1?q?rget/PIC16/_lib/Target/PowerP=2E=2E=2E?= In-Reply-To: <4A06A4D1.70601@lip6.fr> References: <200905090706.n4976n4F018353@zion.cs.uiuc.edu> <88CB4A97-1D38-48EF-BE64-766B32075CFC@gmail.com> <4A06A4D1.70601@lip6.fr> Message-ID: <200905101953.56237.baldrick@free.fr> Hi, > Do we have a BreakageNotes somewhere for the next version of LLVM? It'd > be nice to remember that getTypePaddedSize now is getTypeAllocSize, so > that tools following LLVM releases won't have to figure that by themselves. this seems appropriate for the release notes. But I guess a continuously updated document (BreakageNotes) might be more useful. Shall I start one? Ciao, Duncan. From nicholas at mxc.ca Sun May 10 15:57:09 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 10 May 2009 20:57:09 -0000 Subject: [llvm-commits] [llvm] r71407 - in /llvm/trunk: docs/LangRef.html include/llvm/Constants.h include/llvm/MDNode.h lib/AsmParser/LLParser.cpp lib/AsmParser/LLParser.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Writer/BitcodeWriter.cpp lib/Bitcode/Writer/ValueEnumerator.cpp lib/VMCore/AsmWriter.cpp lib/VMCore/Constants.cpp test/Feature/embeddedmetadata.ll unittests/VMCore/MetadataTest.cpp Message-ID: <200905102057.n4AKv9Da006315@zion.cs.uiuc.edu> Author: nicholas Date: Sun May 10 15:57:05 2009 New Revision: 71407 URL: http://llvm.org/viewvc/llvm-project?rev=71407&view=rev Log: Make MDNode use CallbackVH. Also change MDNode to store Value* instead of Constant* in preperation of a future change to support holding non-Constants in an MDNode. Added: llvm/trunk/include/llvm/MDNode.h Modified: llvm/trunk/docs/LangRef.html llvm/trunk/include/llvm/Constants.h llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/AsmParser/LLParser.h llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp llvm/trunk/lib/VMCore/AsmWriter.cpp llvm/trunk/lib/VMCore/Constants.cpp llvm/trunk/test/Feature/embeddedmetadata.ll llvm/trunk/unittests/VMCore/MetadataTest.cpp Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=71407&r1=71406&r2=71407&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Sun May 10 15:57:05 2009 @@ -2061,6 +2061,10 @@ exclamation point). For example: "!{ { } !"test\00", i32 10}".

    +

    A metadata node will attempt to track changes to the values it holds. In +the event that a value is deleted, it will be replaced with a typeless +"null", such as "{ } !{null, i32 0}".

    +

    Optimizations may rely on metadata to provide additional information about the program that isn't available in the instructions, or that isn't easily computable. Similarly, the code generator may expect a certain metadata format Modified: llvm/trunk/include/llvm/Constants.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=71407&r1=71406&r2=71407&view=diff ============================================================================== --- llvm/trunk/include/llvm/Constants.h (original) +++ llvm/trunk/include/llvm/Constants.h Sun May 10 15:57:05 2009 @@ -26,7 +26,6 @@ #include "llvm/OperandTraits.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/APFloat.h" -#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallVector.h" namespace llvm { @@ -877,55 +876,6 @@ } }; -//===----------------------------------------------------------------------===// -/// MDNode - a tuple of other values. -/// These contain a list of the Constants that represent the metadata. -/// -class MDNode : public Constant, public FoldingSetNode { - MDNode(const MDNode &); // DO NOT IMPLEMENT -protected: - explicit MDNode(Constant*const* Vals, unsigned NumVals); -public: - /// get() - Static factory methods - Return objects of the specified value. - /// - static MDNode *get(Constant*const* Vals, unsigned NumVals); - - // Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); - - /// getType() specialization - Type is always an empty struct. - /// - inline const Type *getType() const { - return Type::EmptyStructTy; - } - - /// isNullValue - Return true if this is the value that would be returned by - /// getNullValue. This always returns false because getNullValue will never - /// produce metadata. - virtual bool isNullValue() const { - return false; - } - - /// Profile - calculate a unique identifier for this MDNode to collapse - /// duplicates - void Profile(FoldingSetNodeID &ID); - - virtual void destroyConstant(); - virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MDNode *) { return true; } - static bool classof(const Value *V) { - return V->getValueID() == MDNodeVal; - } -}; - -template <> -struct OperandTraits : VariadicOperandTraits<> { -}; - -DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(MDNode, Constant) - } // End llvm namespace #endif Added: llvm/trunk/include/llvm/MDNode.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MDNode.h?rev=71407&view=auto ============================================================================== --- llvm/trunk/include/llvm/MDNode.h (added) +++ llvm/trunk/include/llvm/MDNode.h Sun May 10 15:57:05 2009 @@ -0,0 +1,130 @@ +//===-- llvm/Metadata.h - Constant class subclass definitions ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// @file +/// This file contains the declarations for the subclasses of Constant, +/// which represent the different flavors of constant values that live in LLVM. +/// Note that Constants are immutable (once created they never change) and are +/// fully shared by structural equivalence. This means that two structurally +/// equivalent constants will always have the same address. Constant's are +/// created on demand as needed and never deleted: thus clients don't have to +/// worry about the lifetime of the objects. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MDNODE_H +#define LLVM_MDNODE_H + +#include "llvm/Constant.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/ValueHandle.h" + +namespace llvm { + +//===----------------------------------------------------------------------===// +/// MDNode - a tuple of other values. +/// These contain a list of the Constants that represent the metadata. The +/// operand list is always empty, query the element list instead. +/// +/// This class will attempt to keep track of values as they are modified. When +/// a value is replaced the element will be replaced with it, and when the +/// value is deleted the element is set to a null pointer. In order to preserve +/// structural equivalence while the elements mutate, the MDNode may call +/// replaceAllUsesWith on itself. Because of this, users of MDNode must use a +/// WeakVH or CallbackVH to hold the node pointer if there is a chance that one +/// of the elements held by the node may change. +/// +class MDNode : public Constant, public FoldingSetNode { + MDNode(const MDNode &); // DO NOT IMPLEMENT + + friend class ElementVH; + struct ElementVH : public CallbackVH { + MDNode *OwningNode; + + ElementVH(Value *V, MDNode *Parent) + : CallbackVH(V), OwningNode(Parent) {} + + ~ElementVH() {} + + /// deleted - Set this entry in the MDNode to 'null'. This will reallocate + /// the MDNode. + virtual void deleted() { + OwningNode->replaceElement(this->operator Value*(), 0); + } + + /// allUsesReplacedWith - Modify the MDNode by replacing this entry with + /// new_value. This will reallocate the MDNode. + virtual void allUsesReplacedWith(Value *new_value) { + OwningNode->replaceElement(this->operator Value*(), new_value); + } + }; + + void replaceElement(Value *From, Value *To); + + SmallVector Node; + typedef SmallVectorImpl::iterator elem_iterator; +protected: + explicit MDNode(Value*const* Vals, unsigned NumVals); +public: + typedef SmallVectorImpl::const_iterator const_elem_iterator; + + /// get() - Static factory methods - Return objects of the specified value. + /// + static MDNode *get(Value*const* Vals, unsigned NumVals); + + Value *getElement(unsigned i) const { + return Node[i]; + } + + unsigned getNumElements() const { + return Node.size(); + } + + const_elem_iterator elem_begin() const { + return Node.begin(); + } + + const_elem_iterator elem_end() const { + return Node.end(); + } + + /// getType() specialization - Type is always an empty struct. + /// + inline const Type *getType() const { + return Type::EmptyStructTy; + } + + /// isNullValue - Return true if this is the value that would be returned by + /// getNullValue. This always returns false because getNullValue will never + /// produce metadata. + virtual bool isNullValue() const { + return false; + } + + /// Profile - calculate a unique identifier for this MDNode to collapse + /// duplicates + void Profile(FoldingSetNodeID &ID) const; + + virtual void destroyConstant(); + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { + assert(0 && "This should never be called because MDNodes have no ops"); + abort(); + } + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const MDNode *) { return true; } + static bool classof(const Value *V) { + return V->getValueID() == MDNodeVal; + } +}; + +} // end llvm namespace + +#endif Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=71407&r1=71406&r2=71407&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Sun May 10 15:57:05 2009 @@ -18,6 +18,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" +#include "llvm/MDNode.h" #include "llvm/Module.h" #include "llvm/ValueSymbolTable.h" #include "llvm/ADT/SmallPtrSet.h" @@ -1571,13 +1572,11 @@ ID.Kind = ValID::t_Constant; Lex.Lex(); if (Lex.getKind() == lltok::lbrace) { - // MDNode: - // ::= '!' '{' TypeAndValue (',' TypeAndValue)* '}' - SmallVector Elts; + SmallVector Elts; if (ParseMDNodeVector(Elts) || ParseToken(lltok::rbrace, "expected end of metadata node")) return true; - + ID.ConstantVal = MDNode::get(&Elts[0], Elts.size()); return false; } @@ -3257,14 +3256,23 @@ //===----------------------------------------------------------------------===// /// ParseMDNodeVector -/// ::= TypeAndValue (',' TypeAndValue)* -bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts) { +/// ::= Element (',' Element)* +/// Element +/// ::= 'null' | TypeAndValue +bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts) { assert(Lex.getKind() == lltok::lbrace); Lex.Lex(); do { - Constant *C; - if (ParseGlobalTypeAndValue(C)) return true; - Elts.push_back(C); + Value *V; + if (Lex.getKind() == lltok::kw_null) { + Lex.Lex(); + V = 0; + } else { + Constant *C; + if (ParseGlobalTypeAndValue(C)) return true; + V = C; + } + Elts.push_back(V); } while (EatIfPresent(lltok::comma)); return false; Modified: llvm/trunk/lib/AsmParser/LLParser.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=71407&r1=71406&r2=71407&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.h (original) +++ llvm/trunk/lib/AsmParser/LLParser.h Sun May 10 15:57:05 2009 @@ -158,7 +158,7 @@ bool ParseGlobalValue(const Type *Ty, Constant *&V); bool ParseGlobalTypeAndValue(Constant *&V); bool ParseGlobalValueVector(SmallVectorImpl &Elts); - bool ParseMDNodeVector(SmallVectorImpl &); + bool ParseMDNodeVector(SmallVectorImpl &); // Function Semantic Analysis. Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=71407&r1=71406&r2=71407&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Sun May 10 15:57:05 2009 @@ -17,6 +17,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" +#include "llvm/MDNode.h" #include "llvm/Module.h" #include "llvm/AutoUpgrade.h" #include "llvm/ADT/SmallString.h" @@ -287,12 +288,10 @@ UserCS->getType()->isPacked()); } else if (isa(UserC)) { NewC = ConstantVector::get(&NewOps[0], NewOps.size()); - } else if (isa(UserC)) { + } else { + assert(isa(UserC) && "Must be a ConstantExpr."); NewC = cast(UserC)->getWithOperands(&NewOps[0], NewOps.size()); - } else { - assert(isa(UserC) && "Must be a metadata node."); - NewC = MDNode::get(&NewOps[0], NewOps.size()); } UserC->replaceAllUsesWith(NewC); @@ -300,6 +299,8 @@ NewOps.clear(); } + // Update all ValueHandles, they should be the only users at this point. + Placeholder->replaceAllUsesWith(RealVal); delete Placeholder; } } @@ -1017,10 +1018,13 @@ return Error("Invalid CST_MDNODE record"); unsigned Size = Record.size(); - SmallVector Elts; + SmallVector Elts; for (unsigned i = 0; i != Size; i += 2) { const Type *Ty = getTypeByID(Record[i], false); - Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], Ty)); + if (Ty != Type::VoidTy) + Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], Ty)); + else + Elts.push_back(NULL); } V = MDNode::get(&Elts[0], Elts.size()); break; Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=71407&r1=71406&r2=71407&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Sun May 10 15:57:05 2009 @@ -19,6 +19,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" +#include "llvm/MDNode.h" #include "llvm/Module.h" #include "llvm/TypeSymbolTable.h" #include "llvm/ValueSymbolTable.h" @@ -706,9 +707,14 @@ } } else if (const MDNode *N = dyn_cast(C)) { Code = bitc::CST_CODE_MDNODE; - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - Record.push_back(VE.getTypeID(N->getOperand(i)->getType())); - Record.push_back(VE.getValueID(N->getOperand(i))); + for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) { + if (N->getElement(i)) { + Record.push_back(VE.getTypeID(N->getElement(i)->getType())); + Record.push_back(VE.getValueID(N->getElement(i))); + } else { + Record.push_back(VE.getTypeID(Type::VoidTy)); + Record.push_back(0); + } } } else { assert(0 && "Unknown constant!"); Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=71407&r1=71406&r2=71407&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Sun May 10 15:57:05 2009 @@ -14,6 +14,7 @@ #include "ValueEnumerator.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/MDNode.h" #include "llvm/Module.h" #include "llvm/TypeSymbolTable.h" #include "llvm/ValueSymbolTable.h" @@ -203,6 +204,18 @@ Values.push_back(std::make_pair(V, 1U)); ValueMap[V] = Values.size(); return; + } else if (const MDNode *N = dyn_cast(C)) { + for (MDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end(); + I != E; ++I) { + if (*I) + EnumerateValue(*I); + else + EnumerateType(Type::VoidTy); + } + + Values.push_back(std::make_pair(V, 1U)); + ValueMap[V] = Values.size(); + return; } } @@ -244,6 +257,11 @@ // them. for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) EnumerateOperandType(C->getOperand(i)); + + if (const MDNode *N = dyn_cast(V)) { + for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) + EnumerateOperandType(N->getElement(i)); + } } } Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=71407&r1=71406&r2=71407&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Sun May 10 15:57:05 2009 @@ -23,6 +23,7 @@ #include "llvm/InlineAsm.h" #include "llvm/Instruction.h" #include "llvm/Instructions.h" +#include "llvm/MDNode.h" #include "llvm/Module.h" #include "llvm/ValueSymbolTable.h" #include "llvm/TypeSymbolTable.h" @@ -945,10 +946,16 @@ if (const MDNode *N = dyn_cast(CV)) { Out << "!{"; - for (MDNode::const_op_iterator I = N->op_begin(), E = N->op_end(); I != E;){ - TypePrinter.print((*I)->getType(), Out); - Out << ' '; - WriteAsOperandInternal(Out, *I, TypePrinter, Machine); + for (MDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end(); + I != E;) { + if (!*I) { + Out << "null"; + } else { + TypePrinter.print((*I)->getType(), Out); + Out << ' '; + WriteAsOperandInternal(Out, *I, TypePrinter, Machine); + } + if (++I != E) Out << ", "; } Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=71407&r1=71406&r2=71407&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Sun May 10 15:57:05 2009 @@ -16,6 +16,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/GlobalValue.h" #include "llvm/Instructions.h" +#include "llvm/MDNode.h" #include "llvm/Module.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/StringExtras.h" @@ -1687,18 +1688,18 @@ static ManagedStatic > MDNodeSet; -MDNode::MDNode(Constant*const* Vals, unsigned NumVals) - : Constant(Type::EmptyStructTy, MDNodeVal, - OperandTraits::op_end(this) - NumVals, NumVals) { - std::copy(Vals, Vals + NumVals, OperandList); +MDNode::MDNode(Value*const* Vals, unsigned NumVals) + : Constant(Type::EmptyStructTy, MDNodeVal, 0, 0) { + for (unsigned i = 0; i != NumVals; ++i) + Node.push_back(ElementVH(Vals[i], this)); } -void MDNode::Profile(FoldingSetNodeID &ID) { - for (op_iterator I = op_begin(), E = op_end(); I != E; ++I) +void MDNode::Profile(FoldingSetNodeID &ID) const { + for (const_elem_iterator I = elem_begin(), E = elem_end(); I != E; ++I) ID.AddPointer(*I); } -MDNode *MDNode::get(Constant*const* Vals, unsigned NumVals) { +MDNode *MDNode::get(Value*const* Vals, unsigned NumVals) { FoldingSetNodeID ID; for (unsigned i = 0; i != NumVals; ++i) ID.AddPointer(Vals[i]); @@ -1708,12 +1709,13 @@ return N; // InsertPoint will have been set by the FindNodeOrInsertPos call. - MDNode *N = new(NumVals) MDNode(Vals, NumVals); + MDNode *N = new(0) MDNode(Vals, NumVals); MDNodeSet->InsertNode(N, InsertPoint); return N; } void MDNode::destroyConstant() { + MDNodeSet->RemoveNode(this); destroyConstantImpl(); } @@ -2801,23 +2803,19 @@ destroyConstant(); } -void MDNode::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { - assert(isa(To) && "Cannot make Constant refer to non-constant!"); - - SmallVector Values; - Values.reserve(getNumOperands()); // Build replacement array... - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - Constant *Val = getOperand(i); - if (Val == From) Val = cast(To); +void MDNode::replaceElement(Value *From, Value *To) { + SmallVector Values; + Values.reserve(getNumElements()); // Build replacement array... + for (unsigned i = 0, e = getNumElements(); i != e; ++i) { + Value *Val = getElement(i); + if (Val == From) Val = To; Values.push_back(Val); } - - Constant *Replacement = MDNode::get(&Values[0], Values.size()); + + MDNode *Replacement = MDNode::get(&Values[0], Values.size()); assert(Replacement != this && "I didn't contain From!"); - - // Everyone using this now uses the replacement. + uncheckedReplaceAllUsesWith(Replacement); - - // Delete the old constant! + destroyConstant(); } Modified: llvm/trunk/test/Feature/embeddedmetadata.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/embeddedmetadata.ll?rev=71407&r1=71406&r2=71407&view=diff ============================================================================== --- llvm/trunk/test/Feature/embeddedmetadata.ll (original) +++ llvm/trunk/test/Feature/embeddedmetadata.ll Sun May 10 15:57:05 2009 @@ -2,7 +2,7 @@ declare i8 @llvm.something({ } %a) - at llvm.foo = internal constant { } !{i17 123, { } !"foobar"} + at llvm.foo = internal constant { } !{i17 123, null, { } !"foobar"} define void @foo() { %x = call i8 @llvm.something({ } !{{ } !"f\00oa", i42 123}) Modified: llvm/trunk/unittests/VMCore/MetadataTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/VMCore/MetadataTest.cpp?rev=71407&r1=71406&r2=71407&view=diff ============================================================================== --- llvm/trunk/unittests/VMCore/MetadataTest.cpp (original) +++ llvm/trunk/unittests/VMCore/MetadataTest.cpp Sun May 10 15:57:05 2009 @@ -9,6 +9,10 @@ #include "gtest/gtest.h" #include "llvm/Constants.h" +#include "llvm/Instructions.h" +#include "llvm/MDNode.h" +#include "llvm/Type.h" +#include "llvm/Support/ValueHandle.h" #include using namespace llvm; @@ -59,7 +63,7 @@ } // Test the two constructors, and containing other Constants. -TEST(MDNodeTest, Everything) { +TEST(MDNodeTest, Simple) { char x[3] = { 'a', 'b', 'c' }; char y[3] = { '1', '2', '3' }; @@ -67,25 +71,25 @@ MDString *s2 = MDString::get(&y[0], &y[3]); ConstantInt *CI = ConstantInt::get(APInt(8, 0)); - std::vector V; + std::vector V; V.push_back(s1); V.push_back(CI); V.push_back(s2); MDNode *n1 = MDNode::get(&V[0], 3); - Constant *const c1 = n1; + Value *const c1 = n1; MDNode *n2 = MDNode::get(&c1, 1); MDNode *n3 = MDNode::get(&V[0], 3); EXPECT_NE(n1, n2); EXPECT_EQ(n1, n3); - EXPECT_EQ(3u, n1->getNumOperands()); - EXPECT_EQ(s1, n1->getOperand(0)); - EXPECT_EQ(CI, n1->getOperand(1)); - EXPECT_EQ(s2, n1->getOperand(2)); + EXPECT_EQ(3u, n1->getNumElements()); + EXPECT_EQ(s1, n1->getElement(0)); + EXPECT_EQ(CI, n1->getElement(1)); + EXPECT_EQ(s2, n1->getElement(2)); - EXPECT_EQ(1u, n2->getNumOperands()); - EXPECT_EQ(n1, n2->getOperand(0)); + EXPECT_EQ(1u, n2->getNumElements()); + EXPECT_EQ(n1, n2->getElement(0)); std::ostringstream oss1, oss2; n1->print(oss1); @@ -94,4 +98,40 @@ EXPECT_STREQ("{ } !{{ } !{{ } !\"abc\", i8 0, { } !\"123\"}}", oss2.str().c_str()); } + +TEST(MDNodeTest, RAUW) { + Constant *C = ConstantInt::get(Type::Int32Ty, 1); + Instruction *I = new BitCastInst(C, Type::Int32Ty); + + Value *const V1 = I; + MDNode *n1 = MDNode::get(&V1, 1); + WeakVH wn1 = n1; + + Value *const V2 = C; + MDNode *n2 = MDNode::get(&V2, 1); + WeakVH wn2 = n2; + + EXPECT_NE(wn1, wn2); + + I->replaceAllUsesWith(C); + + EXPECT_EQ(wn1, wn2); +} + +TEST(MDNodeTest, Delete) { + Constant *C = ConstantInt::get(Type::Int32Ty, 1); + Instruction *I = new BitCastInst(C, Type::Int32Ty); + + Value *const V = I; + MDNode *n = MDNode::get(&V, 1); + WeakVH wvh = n; + + EXPECT_EQ(n, wvh); + + delete I; + + std::ostringstream oss; + wvh->print(oss); + EXPECT_STREQ("{ } !{null}", oss.str().c_str()); +} } From isanbard at gmail.com Sun May 10 18:07:13 2009 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 10 May 2009 16:07:13 -0700 Subject: [llvm-commits] [llvm] r71407 - in /llvm/trunk: docs/LangRef.html include/llvm/Constants.h include/llvm/MDNode.h lib/AsmParser/LLParser.cpp lib/AsmParser/LLParser.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Writer/BitcodeWriter.cpp lib/Bitcode/Writer/ValueEnumerator.cpp lib/VMCore/AsmWriter.cpp lib/VMCore/Constants.cpp test/Feature/embeddedmetadata.ll unittests/VMCore/MetadataTest.cpp In-Reply-To: <200905102057.n4AKv9Da006315@zion.cs.uiuc.edu> References: <200905102057.n4AKv9Da006315@zion.cs.uiuc.edu> Message-ID: <343DE12B-8D9D-400D-B2FA-B4E7A7F9C3A3@gmail.com> Did you forget a file in this commit? :-) /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/ llvmCore~obj/src/lib/VMCore/Verifier.cpp: In function 'bool isMetadata(llvm::Value*)': /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/ llvmCore~obj/src/lib/VMCore/Verifier.cpp:354: error: 'MDNode' was not declared in this scope /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/ llvmCore~obj/src/lib/VMCore/Verifier.cpp:354: error: no matching function for call to 'isa(llvm::Value*&)' -bw On May 10, 2009, at 1:57 PM, Nick Lewycky wrote: > Author: nicholas > Date: Sun May 10 15:57:05 2009 > New Revision: 71407 > > URL: http://llvm.org/viewvc/llvm-project?rev=71407&view=rev > Log: > Make MDNode use CallbackVH. Also change MDNode to store Value* > instead of > Constant* in preperation of a future change to support holding non- > Constants > in an MDNode. > > Added: > llvm/trunk/include/llvm/MDNode.h > Modified: > llvm/trunk/docs/LangRef.html > llvm/trunk/include/llvm/Constants.h > llvm/trunk/lib/AsmParser/LLParser.cpp > llvm/trunk/lib/AsmParser/LLParser.h > llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp > llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp > llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp > llvm/trunk/lib/VMCore/AsmWriter.cpp > llvm/trunk/lib/VMCore/Constants.cpp > llvm/trunk/test/Feature/embeddedmetadata.ll > llvm/trunk/unittests/VMCore/MetadataTest.cpp > > Modified: llvm/trunk/docs/LangRef.html > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=71407&r1=71406&r2=71407&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/docs/LangRef.html (original) > +++ llvm/trunk/docs/LangRef.html Sun May 10 15:57:05 2009 > @@ -2061,6 +2061,10 @@ > exclamation point). For example: "!{ { } !"test\00", i32 10} tt>". >

    > > +

    A metadata node will attempt to track changes to the values it > holds. In > +the event that a value is deleted, it will be replaced with a > typeless > +"null", such as "{ } !{null, i32 0}".

    > + >

    Optimizations may rely on metadata to provide additional > information about > the program that isn't available in the instructions, or that isn't > easily > computable. Similarly, the code generator may expect a certain > metadata format > > Modified: llvm/trunk/include/llvm/Constants.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=71407&r1=71406&r2=71407&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Constants.h (original) > +++ llvm/trunk/include/llvm/Constants.h Sun May 10 15:57:05 2009 > @@ -26,7 +26,6 @@ > #include "llvm/OperandTraits.h" > #include "llvm/ADT/APInt.h" > #include "llvm/ADT/APFloat.h" > -#include "llvm/ADT/FoldingSet.h" > #include "llvm/ADT/SmallVector.h" > > namespace llvm { > @@ -877,55 +876,6 @@ > } > }; > > -// > = > = > = > ----------------------------------------------------------------------= > ==// > -/// MDNode - a tuple of other values. > -/// These contain a list of the Constants that represent the > metadata. > -/// > -class MDNode : public Constant, public FoldingSetNode { > - MDNode(const MDNode &); // DO NOT IMPLEMENT > -protected: > - explicit MDNode(Constant*const* Vals, unsigned NumVals); > -public: > - /// get() - Static factory methods - Return objects of the > specified value. > - /// > - static MDNode *get(Constant*const* Vals, unsigned NumVals); > - > - // Transparently provide more efficient getOperand methods. > - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); > - > - /// getType() specialization - Type is always an empty struct. > - /// > - inline const Type *getType() const { > - return Type::EmptyStructTy; > - } > - > - /// isNullValue - Return true if this is the value that would be > returned by > - /// getNullValue. This always returns false because getNullValue > will never > - /// produce metadata. > - virtual bool isNullValue() const { > - return false; > - } > - > - /// Profile - calculate a unique identifier for this MDNode to > collapse > - /// duplicates > - void Profile(FoldingSetNodeID &ID); > - > - virtual void destroyConstant(); > - virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, > Use *U); > - > - /// Methods for support type inquiry through isa, cast, and > dyn_cast: > - static inline bool classof(const MDNode *) { return true; } > - static bool classof(const Value *V) { > - return V->getValueID() == MDNodeVal; > - } > -}; > - > -template <> > -struct OperandTraits : VariadicOperandTraits<> { > -}; > - > -DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(MDNode, Constant) > - > } // End llvm namespace > > #endif > > Added: llvm/trunk/include/llvm/MDNode.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MDNode.h?rev=71407&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/MDNode.h (added) > +++ llvm/trunk/include/llvm/MDNode.h Sun May 10 15:57:05 2009 > @@ -0,0 +1,130 @@ > +//===-- llvm/Metadata.h - Constant class subclass definitions ---*- > C++ -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open > Source > +// License. See LICENSE.TXT for details. > +// > +// > = > = > = > ----------------------------------------------------------------------= > ==// > +// > +/// @file > +/// This file contains the declarations for the subclasses of > Constant, > +/// which represent the different flavors of constant values that > live in LLVM. > +/// Note that Constants are immutable (once created they never > change) and are > +/// fully shared by structural equivalence. This means that two > structurally > +/// equivalent constants will always have the same address. > Constant's are > +/// created on demand as needed and never deleted: thus clients > don't have to > +/// worry about the lifetime of the objects. > +// > +// > = > = > = > ----------------------------------------------------------------------= > ==// > + > +#ifndef LLVM_MDNODE_H > +#define LLVM_MDNODE_H > + > +#include "llvm/Constant.h" > +#include "llvm/ADT/FoldingSet.h" > +#include "llvm/ADT/SmallVector.h" > +#include "llvm/Support/ValueHandle.h" > + > +namespace llvm { > + > +// > = > = > = > ----------------------------------------------------------------------= > ==// > +/// MDNode - a tuple of other values. > +/// These contain a list of the Constants that represent the > metadata. The > +/// operand list is always empty, query the element list instead. > +/// > +/// This class will attempt to keep track of values as they are > modified. When > +/// a value is replaced the element will be replaced with it, and > when the > +/// value is deleted the element is set to a null pointer. In order > to preserve > +/// structural equivalence while the elements mutate, the MDNode > may call > +/// replaceAllUsesWith on itself. Because of this, users of MDNode > must use a > +/// WeakVH or CallbackVH to hold the node pointer if there is a > chance that one > +/// of the elements held by the node may change. > +/// > +class MDNode : public Constant, public FoldingSetNode { > + MDNode(const MDNode &); // DO NOT IMPLEMENT > + > + friend class ElementVH; > + struct ElementVH : public CallbackVH { > + MDNode *OwningNode; > + > + ElementVH(Value *V, MDNode *Parent) > + : CallbackVH(V), OwningNode(Parent) {} > + > + ~ElementVH() {} > + > + /// deleted - Set this entry in the MDNode to 'null'. This will > reallocate > + /// the MDNode. > + virtual void deleted() { > + OwningNode->replaceElement(this->operator Value*(), 0); > + } > + > + /// allUsesReplacedWith - Modify the MDNode by replacing this > entry with > + /// new_value. This will reallocate the MDNode. > + virtual void allUsesReplacedWith(Value *new_value) { > + OwningNode->replaceElement(this->operator Value*(), new_value); > + } > + }; > + > + void replaceElement(Value *From, Value *To); > + > + SmallVector Node; > + typedef SmallVectorImpl::iterator elem_iterator; > +protected: > + explicit MDNode(Value*const* Vals, unsigned NumVals); > +public: > + typedef SmallVectorImpl::const_iterator > const_elem_iterator; > + > + /// get() - Static factory methods - Return objects of the > specified value. > + /// > + static MDNode *get(Value*const* Vals, unsigned NumVals); > + > + Value *getElement(unsigned i) const { > + return Node[i]; > + } > + > + unsigned getNumElements() const { > + return Node.size(); > + } > + > + const_elem_iterator elem_begin() const { > + return Node.begin(); > + } > + > + const_elem_iterator elem_end() const { > + return Node.end(); > + } > + > + /// getType() specialization - Type is always an empty struct. > + /// > + inline const Type *getType() const { > + return Type::EmptyStructTy; > + } > + > + /// isNullValue - Return true if this is the value that would be > returned by > + /// getNullValue. This always returns false because getNullValue > will never > + /// produce metadata. > + virtual bool isNullValue() const { > + return false; > + } > + > + /// Profile - calculate a unique identifier for this MDNode to > collapse > + /// duplicates > + void Profile(FoldingSetNodeID &ID) const; > + > + virtual void destroyConstant(); > + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, > Use *U) { > + assert(0 && "This should never be called because MDNodes have > no ops"); > + abort(); > + } > + > + /// Methods for support type inquiry through isa, cast, and > dyn_cast: > + static inline bool classof(const MDNode *) { return true; } > + static bool classof(const Value *V) { > + return V->getValueID() == MDNodeVal; > + } > +}; > + > +} // end llvm namespace > + > +#endif > > Modified: llvm/trunk/lib/AsmParser/LLParser.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=71407&r1=71406&r2=71407&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) > +++ llvm/trunk/lib/AsmParser/LLParser.cpp Sun May 10 15:57:05 2009 > @@ -18,6 +18,7 @@ > #include "llvm/DerivedTypes.h" > #include "llvm/InlineAsm.h" > #include "llvm/Instructions.h" > +#include "llvm/MDNode.h" > #include "llvm/Module.h" > #include "llvm/ValueSymbolTable.h" > #include "llvm/ADT/SmallPtrSet.h" > @@ -1571,13 +1572,11 @@ > ID.Kind = ValID::t_Constant; > Lex.Lex(); > if (Lex.getKind() == lltok::lbrace) { > - // MDNode: > - // ::= '!' '{' TypeAndValue (',' TypeAndValue)* '}' > - SmallVector Elts; > + SmallVector Elts; > if (ParseMDNodeVector(Elts) || > ParseToken(lltok::rbrace, "expected end of metadata node")) > return true; > - > + > ID.ConstantVal = MDNode::get(&Elts[0], Elts.size()); > return false; > } > @@ -3257,14 +3256,23 @@ > // > = > = > = > ----------------------------------------------------------------------= > ==// > > /// ParseMDNodeVector > -/// ::= TypeAndValue (',' TypeAndValue)* > -bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts) { > +/// ::= Element (',' Element)* > +/// Element > +/// ::= 'null' | TypeAndValue > +bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts) { > assert(Lex.getKind() == lltok::lbrace); > Lex.Lex(); > do { > - Constant *C; > - if (ParseGlobalTypeAndValue(C)) return true; > - Elts.push_back(C); > + Value *V; > + if (Lex.getKind() == lltok::kw_null) { > + Lex.Lex(); > + V = 0; > + } else { > + Constant *C; > + if (ParseGlobalTypeAndValue(C)) return true; > + V = C; > + } > + Elts.push_back(V); > } while (EatIfPresent(lltok::comma)); > > return false; > > Modified: llvm/trunk/lib/AsmParser/LLParser.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=71407&r1=71406&r2=71407&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/AsmParser/LLParser.h (original) > +++ llvm/trunk/lib/AsmParser/LLParser.h Sun May 10 15:57:05 2009 > @@ -158,7 +158,7 @@ > bool ParseGlobalValue(const Type *Ty, Constant *&V); > bool ParseGlobalTypeAndValue(Constant *&V); > bool ParseGlobalValueVector(SmallVectorImpl &Elts); > - bool ParseMDNodeVector(SmallVectorImpl &); > + bool ParseMDNodeVector(SmallVectorImpl &); > > > // Function Semantic Analysis. > > Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=71407&r1=71406&r2=71407&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) > +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Sun May 10 > 15:57:05 2009 > @@ -17,6 +17,7 @@ > #include "llvm/DerivedTypes.h" > #include "llvm/InlineAsm.h" > #include "llvm/Instructions.h" > +#include "llvm/MDNode.h" > #include "llvm/Module.h" > #include "llvm/AutoUpgrade.h" > #include "llvm/ADT/SmallString.h" > @@ -287,12 +288,10 @@ > UserCS->getType()->isPacked()); > } else if (isa(UserC)) { > NewC = ConstantVector::get(&NewOps[0], NewOps.size()); > - } else if (isa(UserC)) { > + } else { > + assert(isa(UserC) && "Must be a > ConstantExpr."); > NewC = cast(UserC)->getWithOperands(&NewOps[0], > > NewOps.size()); > - } else { > - assert(isa(UserC) && "Must be a metadata node."); > - NewC = MDNode::get(&NewOps[0], NewOps.size()); > } > > UserC->replaceAllUsesWith(NewC); > @@ -300,6 +299,8 @@ > NewOps.clear(); > } > > + // Update all ValueHandles, they should be the only users at > this point. > + Placeholder->replaceAllUsesWith(RealVal); > delete Placeholder; > } > } > @@ -1017,10 +1018,13 @@ > return Error("Invalid CST_MDNODE record"); > > unsigned Size = Record.size(); > - SmallVector Elts; > + SmallVector Elts; > for (unsigned i = 0; i != Size; i += 2) { > const Type *Ty = getTypeByID(Record[i], false); > - Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], Ty)); > + if (Ty != Type::VoidTy) > + Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], > Ty)); > + else > + Elts.push_back(NULL); > } > V = MDNode::get(&Elts[0], Elts.size()); > break; > > Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=71407&r1=71406&r2=71407&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) > +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Sun May 10 > 15:57:05 2009 > @@ -19,6 +19,7 @@ > #include "llvm/DerivedTypes.h" > #include "llvm/InlineAsm.h" > #include "llvm/Instructions.h" > +#include "llvm/MDNode.h" > #include "llvm/Module.h" > #include "llvm/TypeSymbolTable.h" > #include "llvm/ValueSymbolTable.h" > @@ -706,9 +707,14 @@ > } > } else if (const MDNode *N = dyn_cast(C)) { > Code = bitc::CST_CODE_MDNODE; > - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { > - Record.push_back(VE.getTypeID(N->getOperand(i)->getType())); > - Record.push_back(VE.getValueID(N->getOperand(i))); > + for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) { > + if (N->getElement(i)) { > + Record.push_back(VE.getTypeID(N->getElement(i)- > >getType())); > + Record.push_back(VE.getValueID(N->getElement(i))); > + } else { > + Record.push_back(VE.getTypeID(Type::VoidTy)); > + Record.push_back(0); > + } > } > } else { > assert(0 && "Unknown constant!"); > > Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=71407&r1=71406&r2=71407&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original) > +++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Sun May 10 > 15:57:05 2009 > @@ -14,6 +14,7 @@ > #include "ValueEnumerator.h" > #include "llvm/Constants.h" > #include "llvm/DerivedTypes.h" > +#include "llvm/MDNode.h" > #include "llvm/Module.h" > #include "llvm/TypeSymbolTable.h" > #include "llvm/ValueSymbolTable.h" > @@ -203,6 +204,18 @@ > Values.push_back(std::make_pair(V, 1U)); > ValueMap[V] = Values.size(); > return; > + } else if (const MDNode *N = dyn_cast(C)) { > + for (MDNode::const_elem_iterator I = N->elem_begin(), E = N- > >elem_end(); > + I != E; ++I) { > + if (*I) > + EnumerateValue(*I); > + else > + EnumerateType(Type::VoidTy); > + } > + > + Values.push_back(std::make_pair(V, 1U)); > + ValueMap[V] = Values.size(); > + return; > } > } > > @@ -244,6 +257,11 @@ > // them. > for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) > EnumerateOperandType(C->getOperand(i)); > + > + if (const MDNode *N = dyn_cast(V)) { > + for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) > + EnumerateOperandType(N->getElement(i)); > + } > } > } > > > Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=71407&r1=71406&r2=71407&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) > +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Sun May 10 15:57:05 2009 > @@ -23,6 +23,7 @@ > #include "llvm/InlineAsm.h" > #include "llvm/Instruction.h" > #include "llvm/Instructions.h" > +#include "llvm/MDNode.h" > #include "llvm/Module.h" > #include "llvm/ValueSymbolTable.h" > #include "llvm/TypeSymbolTable.h" > @@ -945,10 +946,16 @@ > > if (const MDNode *N = dyn_cast(CV)) { > Out << "!{"; > - for (MDNode::const_op_iterator I = N->op_begin(), E = N- > >op_end(); I != E;){ > - TypePrinter.print((*I)->getType(), Out); > - Out << ' '; > - WriteAsOperandInternal(Out, *I, TypePrinter, Machine); > + for (MDNode::const_elem_iterator I = N->elem_begin(), E = N- > >elem_end(); > + I != E;) { > + if (!*I) { > + Out << "null"; > + } else { > + TypePrinter.print((*I)->getType(), Out); > + Out << ' '; > + WriteAsOperandInternal(Out, *I, TypePrinter, Machine); > + } > + > if (++I != E) > Out << ", "; > } > > Modified: llvm/trunk/lib/VMCore/Constants.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=71407&r1=71406&r2=71407&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/VMCore/Constants.cpp (original) > +++ llvm/trunk/lib/VMCore/Constants.cpp Sun May 10 15:57:05 2009 > @@ -16,6 +16,7 @@ > #include "llvm/DerivedTypes.h" > #include "llvm/GlobalValue.h" > #include "llvm/Instructions.h" > +#include "llvm/MDNode.h" > #include "llvm/Module.h" > #include "llvm/ADT/FoldingSet.h" > #include "llvm/ADT/StringExtras.h" > @@ -1687,18 +1688,18 @@ > > static ManagedStatic > MDNodeSet; > > -MDNode::MDNode(Constant*const* Vals, unsigned NumVals) > - : Constant(Type::EmptyStructTy, MDNodeVal, > - OperandTraits::op_end(this) - NumVals, > NumVals) { > - std::copy(Vals, Vals + NumVals, OperandList); > +MDNode::MDNode(Value*const* Vals, unsigned NumVals) > + : Constant(Type::EmptyStructTy, MDNodeVal, 0, 0) { > + for (unsigned i = 0; i != NumVals; ++i) > + Node.push_back(ElementVH(Vals[i], this)); > } > > -void MDNode::Profile(FoldingSetNodeID &ID) { > - for (op_iterator I = op_begin(), E = op_end(); I != E; ++I) > +void MDNode::Profile(FoldingSetNodeID &ID) const { > + for (const_elem_iterator I = elem_begin(), E = elem_end(); I != > E; ++I) > ID.AddPointer(*I); > } > > -MDNode *MDNode::get(Constant*const* Vals, unsigned NumVals) { > +MDNode *MDNode::get(Value*const* Vals, unsigned NumVals) { > FoldingSetNodeID ID; > for (unsigned i = 0; i != NumVals; ++i) > ID.AddPointer(Vals[i]); > @@ -1708,12 +1709,13 @@ > return N; > > // InsertPoint will have been set by the FindNodeOrInsertPos call. > - MDNode *N = new(NumVals) MDNode(Vals, NumVals); > + MDNode *N = new(0) MDNode(Vals, NumVals); > MDNodeSet->InsertNode(N, InsertPoint); > return N; > } > > void MDNode::destroyConstant() { > + MDNodeSet->RemoveNode(this); > destroyConstantImpl(); > } > > @@ -2801,23 +2803,19 @@ > destroyConstant(); > } > > -void MDNode::replaceUsesOfWithOnConstant(Value *From, Value *To, > Use *U) { > - assert(isa(To) && "Cannot make Constant refer to non- > constant!"); > - > - SmallVector Values; > - Values.reserve(getNumOperands()); // Build replacement array... > - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { > - Constant *Val = getOperand(i); > - if (Val == From) Val = cast(To); > +void MDNode::replaceElement(Value *From, Value *To) { > + SmallVector Values; > + Values.reserve(getNumElements()); // Build replacement array... > + for (unsigned i = 0, e = getNumElements(); i != e; ++i) { > + Value *Val = getElement(i); > + if (Val == From) Val = To; > Values.push_back(Val); > } > - > - Constant *Replacement = MDNode::get(&Values[0], Values.size()); > + > + MDNode *Replacement = MDNode::get(&Values[0], Values.size()); > assert(Replacement != this && "I didn't contain From!"); > - > - // Everyone using this now uses the replacement. > + > uncheckedReplaceAllUsesWith(Replacement); > - > - // Delete the old constant! > + > destroyConstant(); > } > > Modified: llvm/trunk/test/Feature/embeddedmetadata.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/embeddedmetadata.ll?rev=71407&r1=71406&r2=71407&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/Feature/embeddedmetadata.ll (original) > +++ llvm/trunk/test/Feature/embeddedmetadata.ll Sun May 10 15:57:05 > 2009 > @@ -2,7 +2,7 @@ > > declare i8 @llvm.something({ } %a) > > - at llvm.foo = internal constant { } !{i17 123, { } !"foobar"} > + at llvm.foo = internal constant { } !{i17 123, null, { } !"foobar"} > > define void @foo() { > %x = call i8 @llvm.something({ } !{{ } !"f\00oa", i42 123}) > > Modified: llvm/trunk/unittests/VMCore/MetadataTest.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/VMCore/MetadataTest.cpp?rev=71407&r1=71406&r2=71407&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/unittests/VMCore/MetadataTest.cpp (original) > +++ llvm/trunk/unittests/VMCore/MetadataTest.cpp Sun May 10 15:57:05 > 2009 > @@ -9,6 +9,10 @@ > > #include "gtest/gtest.h" > #include "llvm/Constants.h" > +#include "llvm/Instructions.h" > +#include "llvm/MDNode.h" > +#include "llvm/Type.h" > +#include "llvm/Support/ValueHandle.h" > #include > > using namespace llvm; > @@ -59,7 +63,7 @@ > } > > // Test the two constructors, and containing other Constants. > -TEST(MDNodeTest, Everything) { > +TEST(MDNodeTest, Simple) { > char x[3] = { 'a', 'b', 'c' }; > char y[3] = { '1', '2', '3' }; > > @@ -67,25 +71,25 @@ > MDString *s2 = MDString::get(&y[0], &y[3]); > ConstantInt *CI = ConstantInt::get(APInt(8, 0)); > > - std::vector V; > + std::vector V; > V.push_back(s1); > V.push_back(CI); > V.push_back(s2); > > MDNode *n1 = MDNode::get(&V[0], 3); > - Constant *const c1 = n1; > + Value *const c1 = n1; > MDNode *n2 = MDNode::get(&c1, 1); > MDNode *n3 = MDNode::get(&V[0], 3); > EXPECT_NE(n1, n2); > EXPECT_EQ(n1, n3); > > - EXPECT_EQ(3u, n1->getNumOperands()); > - EXPECT_EQ(s1, n1->getOperand(0)); > - EXPECT_EQ(CI, n1->getOperand(1)); > - EXPECT_EQ(s2, n1->getOperand(2)); > + EXPECT_EQ(3u, n1->getNumElements()); > + EXPECT_EQ(s1, n1->getElement(0)); > + EXPECT_EQ(CI, n1->getElement(1)); > + EXPECT_EQ(s2, n1->getElement(2)); > > - EXPECT_EQ(1u, n2->getNumOperands()); > - EXPECT_EQ(n1, n2->getOperand(0)); > + EXPECT_EQ(1u, n2->getNumElements()); > + EXPECT_EQ(n1, n2->getElement(0)); > > std::ostringstream oss1, oss2; > n1->print(oss1); > @@ -94,4 +98,40 @@ > EXPECT_STREQ("{ } !{{ } !{{ } !\"abc\", i8 0, { } !\"123\"}}", > oss2.str().c_str()); > } > + > +TEST(MDNodeTest, RAUW) { > + Constant *C = ConstantInt::get(Type::Int32Ty, 1); > + Instruction *I = new BitCastInst(C, Type::Int32Ty); > + > + Value *const V1 = I; > + MDNode *n1 = MDNode::get(&V1, 1); > + WeakVH wn1 = n1; > + > + Value *const V2 = C; > + MDNode *n2 = MDNode::get(&V2, 1); > + WeakVH wn2 = n2; > + > + EXPECT_NE(wn1, wn2); > + > + I->replaceAllUsesWith(C); > + > + EXPECT_EQ(wn1, wn2); > +} > + > +TEST(MDNodeTest, Delete) { > + Constant *C = ConstantInt::get(Type::Int32Ty, 1); > + Instruction *I = new BitCastInst(C, Type::Int32Ty); > + > + Value *const V = I; > + MDNode *n = MDNode::get(&V, 1); > + WeakVH wvh = n; > + > + EXPECT_EQ(n, wvh); > + > + delete I; > + > + std::ostringstream oss; > + wvh->print(oss); > + EXPECT_STREQ("{ } !{null}", oss.str().c_str()); > +} > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Sun May 10 18:14:38 2009 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 10 May 2009 23:14:38 -0000 Subject: [llvm-commits] [llvm] r71410 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Message-ID: <200905102314.n4ANEdP9010260@zion.cs.uiuc.edu> Author: void Date: Sun May 10 18:14:38 2009 New Revision: 71410 URL: http://llvm.org/viewvc/llvm-project?rev=71410&view=rev Log: This is a large rewrite of how Dwarf info for inlined functions is handled. The DwarfWriter expects DbgScopes and DIEs to behave themselves according to DwarfWriter's rules. However, inlined functions violate these rules. There are two different types of DIEs associated with an inlined function: an abstract instance, which has information about the original source code for the function being inlined; and concrete instances, which are created for each place the function was inlined and point back to the abstract instance. This patch tries to stay true to this schema. It bypasses how regular DbgScopes and DIEs are created and used when necessary. It provides special handling for DIEs of abstract and concrete instances. This doesn't take care of all of the problems with debug info for inlined functions, but it's a step in the right direction. For one thing, llvm-gcc generates wrong IR (it's missing some llvm.dbg intrinsics at the point where the function's inlined) for this example: #include static __inline__ __attribute__((always_inline)) int bar(int x) { return 4; } void foo() { long long b = 1; int Y = bar(4); printf("%d\n", Y); } while clang generates correct IR. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=71410&r1=71409&r2=71410&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Sun May 10 18:14:38 2009 @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/DwarfWriter.cpp - Dwarf Framework ----------*- C++ -*-===// +//===-- llvm/CodeGen/DwarfWriter.cpp - Dwarf Framework --------------------===// // // The LLVM Compiler Infrastructure // @@ -200,6 +200,7 @@ //===----------------------------------------------------------------------===// /// DIE - A structured debug information entry. Has an abbreviation which /// describes it's organization. +class CompileUnit; class DIE : public FoldingSetNode { protected: /// Abbrev - Buffer for constructing abbreviation. @@ -222,6 +223,8 @@ /// SmallVector Values; + /// Abstract compile unit. + CompileUnit *AbstractCU; public: explicit DIE(unsigned Tag) : Abbrev(Tag, DW_CHILDREN_no), Offset(0), Size(0) {} @@ -237,9 +240,12 @@ unsigned getSize() const { return Size; } const std::vector &getChildren() const { return Children; } SmallVector &getValues() { return Values; } + CompileUnit *getAbstractCompileUnit() const { return AbstractCU; } + void setTag(unsigned Tag) { Abbrev.setTag(Tag); } void setOffset(unsigned O) { Offset = O; } void setSize(unsigned S) { Size = S; } + void setAbstractCompileUnit(CompileUnit *CU) { AbstractCU = CU; } /// AddValue - Add a value and attributes to a DIE. /// @@ -1107,6 +1113,7 @@ //===----------------------------------------------------------------------===// /// DbgScope - This class is used to track scope information. /// +class DbgConcreteScope; class DbgScope { DbgScope *Parent; // Parent to this scope. DIDescriptor Desc; // Debug info descriptor for scope. @@ -1115,14 +1122,11 @@ unsigned EndLabelID; // Label ID of the end of scope. SmallVector Scopes; // Scopes defined in scope. SmallVector Variables;// Variables declared in scope. + SmallVector ConcreteInsts;// Concrete insts of funcs. public: DbgScope(DbgScope *P, DIDescriptor D) - : Parent(P), Desc(D), StartLabelID(0), EndLabelID(0) - {} - virtual ~DbgScope() { - for (unsigned i = 0, N = Scopes.size(); i < N; ++i) delete Scopes[i]; - for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j]; - } + : Parent(P), Desc(D), StartLabelID(0), EndLabelID(0) {} + virtual ~DbgScope(); // Accessors. DbgScope *getParent() const { return Parent; } @@ -1131,6 +1135,7 @@ unsigned getEndLabelID() const { return EndLabelID; } SmallVector &getScopes() { return Scopes; } SmallVector &getVariables() { return Variables; } + SmallVector &getConcreteInsts() { return ConcreteInsts; } void setStartLabelID(unsigned S) { StartLabelID = S; } void setEndLabelID(unsigned E) { EndLabelID = E; } @@ -1142,10 +1147,9 @@ /// void AddVariable(DbgVariable *V) { Variables.push_back(V); } - virtual bool isInlinedSubroutine() { return false; } - virtual unsigned getLine() { assert ( 0 && "Unexpected scope!"); return 0; } - virtual unsigned getColumn() { assert ( 0 && "Unexpected scope!"); return 0; } - virtual unsigned getFile() { assert ( 0 && "Unexpected scope!"); return 0; } + /// AddConcreteInst - Add a concrete instance to the scope. + /// + void AddConcreteInst(DbgConcreteScope *C) { ConcreteInsts.push_back(C); } #ifndef NDEBUG void dump() const; @@ -1171,25 +1175,29 @@ #endif //===----------------------------------------------------------------------===// -/// DbgInlinedSubroutineScope - This class is used to track inlined subroutine -/// scope information. -/// -class DbgInlinedSubroutineScope : public DbgScope { - unsigned Src; - unsigned Line; - unsigned Col; +/// DbgConcreteScope - This class is used to track a scope that holds concrete +/// instance information. +/// +class DbgConcreteScope : public DbgScope { + CompileUnit *Unit; + DIE *Die; // Debug info for this concrete scope. public: - DbgInlinedSubroutineScope(DbgScope *P, DIDescriptor D, - unsigned S, unsigned L, unsigned C) - : DbgScope(P, D), Src(S), Line(L), Col(C) - {} + DbgConcreteScope(DIDescriptor D) : DbgScope(NULL, D) {} - unsigned getLine() { return Line; } - unsigned getColumn() { return Col; } - unsigned getFile() { return Src; } - bool isInlinedSubroutine() { return true; } + // Accessors. + DIE *getDie() const { return Die; } + void setDie(DIE *D) { Die = D; } }; +DbgScope::~DbgScope() { + for (unsigned i = 0, N = Scopes.size(); i < N; ++i) + delete Scopes[i]; + for (unsigned j = 0, M = Variables.size(); j < M; ++j) + delete Variables[j]; + for (unsigned k = 0, O = ConcreteInsts.size(); k < O; ++k) + delete ConcreteInsts[k]; +} + //===----------------------------------------------------------------------===// /// DwarfDebug - Emits Dwarf debug directives. /// @@ -1278,17 +1286,32 @@ /// DbgScopeMap - Tracks the scopes in the current function. DenseMap DbgScopeMap; - /// DbgInlinedScopeMap - Tracks inlined scopes in the current function. - DenseMap > DbgInlinedScopeMap; + /// DbgConcreteScopeMap - Tracks inlined scopes in the current function. + DenseMap > DbgConcreteScopeMap; - /// InlineInfo - Keep track of inlined functions and their location. - /// This information is used to populate debug_inlined section. + /// InlineInfo - Keep track of inlined functions and their location. This + /// information is used to populate debug_inlined section. DenseMap > InlineInfo; /// InlinedVariableScopes - Scopes information for the inlined subroutine /// variables. DenseMap InlinedVariableScopes; + /// AbstractInstanceRootMap - Map of abstract instance roots of inlined + /// functions. These are subroutine entries that contain a DW_AT_inline + /// attribute. + DenseMap AbstractInstanceRootMap; + + /// AbstractInstanceRootList - List of abstract instance roots of inlined + /// functions. These are subroutine entries that contain a DW_AT_inline + /// attribute. + SmallVector AbstractInstanceRootList; + + /// LexicalScopeStack - A stack of lexical scopes. The top one is the current + /// scope. + SmallVector LexicalScopeStack; + /// CompileUnitOffsets - A vector of the offsets of the compile units. This is /// used when calculating the "origin" of a concrete instance of an inlined /// function. @@ -1775,7 +1798,7 @@ if (Element.getTag() == dwarf::DW_TAG_subprogram) ElemDie = CreateSubprogramDIE(DW_Unit, DISubprogram(Element.getGV())); - else if (Element.getTag() == dwarf::DW_TAG_variable) // ??? + else if (Element.getTag() == dwarf::DW_TAG_variable) // ?? ElemDie = CreateGlobalVariableDIE(DW_Unit, DIGlobalVariable(Element.getGV())); else @@ -2039,6 +2062,13 @@ DbgScope *Parent = NULL; DIBlock Block(V); + // Don't create a new scope if we already created one for an inlined + // function. + DenseMap::iterator + II = AbstractInstanceRootMap.find(V); + if (II != AbstractInstanceRootMap.end()) + return LexicalScopeStack.back(); + if (!Block.isNull()) { DIDescriptor ParentDesc = Block.getContext(); Parent = @@ -2056,21 +2086,6 @@ return Slot; } - /// createInlinedSubroutineScope - Returns the scope associated with the - /// inlined subroutine. - /// - DbgScope *createInlinedSubroutineScope(DISubprogram SP, unsigned Src, - unsigned Line, unsigned Col) { - DbgScope *Scope = - new DbgInlinedSubroutineScope(NULL, SP, Src, Line, Col); - - // FIXME - Add inlined function scopes to the root so we can delete them - // later. - assert (FunctionDbgScope && "Function scope info missing!"); - FunctionDbgScope->AddScope(Scope); - return Scope; - } - /// ConstructDbgScope - Construct the components of a scope. /// void ConstructDbgScope(DbgScope *ParentScope, @@ -2083,6 +2098,33 @@ if (VariableDie) ParentDie->AddChild(VariableDie); } + // Add concrete instances to scope. + SmallVector &ConcreteInsts = ParentScope->getConcreteInsts(); + for (unsigned i = 0, N = ConcreteInsts.size(); i < N; ++i) { + DbgConcreteScope *ConcreteInst = ConcreteInsts[i]; + DIE *Die = ConcreteInst->getDie(); + + unsigned StartID = ConcreteInst->getStartLabelID(); + unsigned EndID = ConcreteInst->getEndLabelID(); + + // Add the scope bounds. + if (StartID) + AddLabel(Die, DW_AT_low_pc, DW_FORM_addr, + DWLabel("label", StartID)); + else + AddLabel(Die, DW_AT_low_pc, DW_FORM_addr, + DWLabel("func_begin", SubprogramCount)); + + if (EndID) + AddLabel(Die, DW_AT_high_pc, DW_FORM_addr, + DWLabel("label", EndID)); + else + AddLabel(Die, DW_AT_high_pc, DW_FORM_addr, + DWLabel("func_end", SubprogramCount)); + + ParentDie->AddChild(Die); + } + // Add nested scopes. SmallVector &Scopes = ParentScope->getScopes(); for (unsigned j = 0, M = Scopes.size(); j < M; ++j) { @@ -2093,29 +2135,19 @@ unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID()); // Ignore empty scopes. - // Do not ignore inlined scope even if it does not have any - // variables or scopes. if (StartID == EndID && StartID != 0) continue; - if (!Scope->isInlinedSubroutine() - && Scope->getScopes().empty() && Scope->getVariables().empty()) + + // Do not ignore inlined scopes even if they don't have any variables or + // scopes. + if (Scope->getScopes().empty() && Scope->getVariables().empty() && + Scope->getConcreteInsts().empty()) continue; if (StartID == ParentStartID && EndID == ParentEndID) { // Just add stuff to the parent scope. ConstructDbgScope(Scope, ParentStartID, ParentEndID, ParentDie, Unit); } else { - DIE *ScopeDie = NULL; - if (MainCU && TAI->doesDwarfUsesInlineInfoSection() - && Scope->isInlinedSubroutine()) { - ScopeDie = new DIE(DW_TAG_inlined_subroutine); - DIE *Origin = MainCU->getDieMapSlotFor(Scope->getDesc().getGV()); - AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin); - AddUInt(ScopeDie, DW_AT_call_file, 0, Scope->getFile()); - AddUInt(ScopeDie, DW_AT_call_line, 0, Scope->getLine()); - AddUInt(ScopeDie, DW_AT_call_column, 0, Scope->getColumn()); - } else { - ScopeDie = new DIE(DW_TAG_lexical_block); - } + DIE *ScopeDie = new DIE(DW_TAG_lexical_block); // Add the scope bounds. if (StartID) @@ -2132,7 +2164,7 @@ AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr, DWLabel("func_end", SubprogramCount)); - // Add the scope contents. + // Add the scope's contents. ConstructDbgScope(Scope, StartID, EndID, ScopeDie, Unit); ParentDie->AddChild(ScopeDie); } @@ -2171,6 +2203,32 @@ ConstructDbgScope(RootScope, 0, 0, SPDie, Unit); } + /// ConstructFunctionDbgScope - Construct the scope for the abstract debug + /// scope. + /// + void ConstructAbstractDbgScope(DbgScope *AbsScope) { + // Exit if there is no root scope. + if (!AbsScope) return; + + DIDescriptor Desc = AbsScope->getDesc(); + if (Desc.isNull()) + return; + + // Get the subprogram debug information entry. + DISubprogram SPD(Desc.getGV()); + + // Get the compile unit context. + CompileUnit *Unit = MainCU; + if (!Unit) + Unit = &FindCompileUnit(SPD.getCompileUnit()); + + // Get the subprogram die. + DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV()); + assert(SPDie && "Missing subprogram descriptor"); + + ConstructDbgScope(AbsScope, 0, 0, SPDie, Unit); + } + /// ConstructDefaultDbgScope - Construct a default scope for the subprogram. /// void ConstructDefaultDbgScope(MachineFunction *MF) { @@ -2289,16 +2347,24 @@ assert(Form && "Too many attributes for DIE (check abbreviation)"); switch (Attr) { - case DW_AT_sibling: { + case DW_AT_sibling: Asm->EmitInt32(Die->SiblingOffset()); break; + case DW_AT_abstract_origin: { + DIEntry *E = cast(Values[i]); + DIE *Origin = E->getEntry(); + unsigned Addr = + CompileUnitOffsets[Die->getAbstractCompileUnit()] + + Origin->getOffset(); + + Asm->EmitInt32(Addr); + break; } - default: { + default: // Emit an attribute using the defined form. Values[i]->EmitValue(*this, Form); break; } - } Asm->EOL(AttributeString(Attr)); } @@ -3144,6 +3210,11 @@ for (unsigned j = 0, M = Values.size(); j < M; ++j) delete Values[j]; + for (DenseMap::iterator + I = AbstractInstanceRootMap.begin(), + E = AbstractInstanceRootMap.end(); I != E;++I) + delete I->second; + delete DebugTimer; } @@ -3336,6 +3407,12 @@ Lines.begin(), Lines.end()); } + // Construct the DbgScope for abstract instances. + for (SmallVector::iterator + I = AbstractInstanceRootList.begin(), + E = AbstractInstanceRootList.end(); I != E; ++I) + ConstructAbstractDbgScope(*I); + // Construct scopes for subprogram. if (FunctionDbgScope) ConstructFunctionDbgScope(FunctionDbgScope); @@ -3357,9 +3434,11 @@ if (FunctionDbgScope) { delete FunctionDbgScope; DbgScopeMap.clear(); - DbgInlinedScopeMap.clear(); + DbgConcreteScopeMap.clear(); InlinedVariableScopes.clear(); FunctionDbgScope = NULL; + LexicalScopeStack.clear(); + AbstractInstanceRootList.clear(); } Lines.clear(); @@ -3437,6 +3516,7 @@ DbgScope *Scope = getOrCreateScope(V); unsigned ID = MMI->NextLabelID(); if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID); + LexicalScopeStack.push_back(Scope); if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -3452,6 +3532,8 @@ DbgScope *Scope = getOrCreateScope(V); unsigned ID = MMI->NextLabelID(); Scope->setEndLabelID(ID); + if (LexicalScopeStack.size() != 0) + LexicalScopeStack.pop_back(); if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -3476,13 +3558,23 @@ DenseMap::iterator SI = InlinedVariableScopes.find(MI); - if (SI != InlinedVariableScopes.end()) { + if (SI != InlinedVariableScopes.end()) { // or GV is an inlined local variable. Scope = SI->second; } else { - // or GV is a local variable. DIVariable DV(GV); - Scope = getOrCreateScope(DV.getContext().getGV()); + GlobalVariable *V = DV.getContext().getGV(); + + // FIXME: The code that checks for the inlined local variable is a hack! + DenseMap::iterator + AI = AbstractInstanceRootMap.find(V); + + if (AI != AbstractInstanceRootMap.end()) + // or GV is an inlined local variable. + Scope = AI->second; + else + // or GV is a local variable. + Scope = getOrCreateScope(V); } } @@ -3505,28 +3597,66 @@ if (TimePassesIsEnabled) DebugTimer->startTimer(); - std::string Dir, Fn; - unsigned Src = GetOrCreateSourceID(CU.getDirectory(Dir), - CU.getFilename(Fn)); - DbgScope *Scope = createInlinedSubroutineScope(SP, Src, Line, Col); - Scope->setStartLabelID(LabelID); - MMI->RecordUsedDbgLabel(LabelID); GlobalVariable *GV = SP.getGV(); + DenseMap::iterator + II = AbstractInstanceRootMap.find(GV); - DenseMap >::iterator - SI = DbgInlinedScopeMap.find(GV); + if (II == AbstractInstanceRootMap.end()) { + // Create an abstract instance entry for this inlined function if it + // doesn't already exist. + DbgScope *Scope = new DbgScope(NULL, DIDescriptor(GV)); + + // Get the compile unit context. + CompileUnit *Unit = &FindCompileUnit(SP.getCompileUnit()); + DIE *SPDie = Unit->getDieMapSlotFor(GV); + if (!SPDie) + SPDie = CreateSubprogramDIE(Unit, SP); + + // Mark as being inlined. This makes this subprogram entry an abstract + // instance root. + // FIXME: Our debugger doesn't care about the value of DW_AT_inline, only + // that it's defined. It probably won't change in the future, but this + // could be more elegant. + AddUInt(SPDie, DW_AT_inline, 0, DW_INL_declared_not_inlined); + + // Track the start label for this inlined function. + DenseMap >::iterator + I = InlineInfo.find(GV); - if (SI == DbgInlinedScopeMap.end()) - DbgInlinedScopeMap[GV].push_back(Scope); - else - SI->second.push_back(Scope); + if (I == InlineInfo.end()) + InlineInfo[GV].push_back(LabelID); + else + I->second.push_back(LabelID); + + AbstractInstanceRootMap[GV] = Scope; + AbstractInstanceRootList.push_back(Scope); + } + + // Create a concrete inlined instance for this inlined function. + DbgConcreteScope *ConcreteScope = new DbgConcreteScope(DIDescriptor(GV)); + DIE *ScopeDie = new DIE(DW_TAG_inlined_subroutine); + CompileUnit *Unit = &FindCompileUnit(SP.getCompileUnit()); + ScopeDie->setAbstractCompileUnit(Unit); + + DIE *Origin = Unit->getDieMapSlotFor(GV); + AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin); + AddUInt(ScopeDie, DW_AT_call_file, 0, Unit->getID()); + AddUInt(ScopeDie, DW_AT_call_line, 0, Line); + AddUInt(ScopeDie, DW_AT_call_column, 0, Col); + + ConcreteScope->setDie(ScopeDie); + ConcreteScope->setStartLabelID(LabelID); + + LexicalScopeStack.back()->AddConcreteInst(ConcreteScope); + + // Keep track of the scope that's inlined into this function. + DenseMap >::iterator + SI = DbgConcreteScopeMap.find(GV); - DenseMap >::iterator - I = InlineInfo.find(GV); - if (I == InlineInfo.end()) - InlineInfo[GV].push_back(LabelID); + if (SI == DbgConcreteScopeMap.end()) + DbgConcreteScopeMap[GV].push_back(ConcreteScope); else - I->second.push_back(LabelID); + SI->second.push_back(ConcreteScope); if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -3543,19 +3673,19 @@ DebugTimer->startTimer(); GlobalVariable *GV = SP.getGV(); - DenseMap >::iterator - I = DbgInlinedScopeMap.find(GV); + DenseMap >::iterator + I = DbgConcreteScopeMap.find(GV); - if (I == DbgInlinedScopeMap.end()) { + if (I == DbgConcreteScopeMap.end()) { if (TimePassesIsEnabled) DebugTimer->stopTimer(); return 0; } - SmallVector &Scopes = I->second; + SmallVector &Scopes = I->second; assert(!Scopes.empty() && "We should have at least one debug scope!"); - DbgScope *Scope = Scopes.back(); Scopes.pop_back(); + DbgConcreteScope *Scope = Scopes.back(); Scopes.pop_back(); unsigned ID = MMI->NextLabelID(); MMI->RecordUsedDbgLabel(ID); @@ -3584,9 +3714,9 @@ return; } - DenseMap >::iterator - I = DbgInlinedScopeMap.find(SP.getGV()); - if (I != DbgInlinedScopeMap.end()) + DenseMap >::iterator + I = DbgConcreteScopeMap.find(SP.getGV()); + if (I != DbgConcreteScopeMap.end()) InlinedVariableScopes[DeclareMI] = I->second.back(); if (TimePassesIsEnabled) From fvbommel at wxs.nl Sun May 10 18:21:42 2009 From: fvbommel at wxs.nl (Frits van Bommel) Date: Mon, 11 May 2009 01:21:42 +0200 Subject: [llvm-commits] [llvm] r71407 - in /llvm/trunk: docs/LangRef.html include/llvm/Constants.h include/llvm/MDNode.h lib/AsmParser/LLParser.cpp lib/AsmParser/LLParser.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Writer/BitcodeWriter.cpp lib/Bitcode/Writer/ValueEnumerator.cpp lib/VMCore/AsmWriter.cpp lib/VMCore/Constants.cpp test/Feature/embeddedmetadata.ll unittests/VMCore/MetadataTest.cpp In-Reply-To: <343DE12B-8D9D-400D-B2FA-B4E7A7F9C3A3@gmail.com> References: <200905102057.n4AKv9Da006315@zion.cs.uiuc.edu> <343DE12B-8D9D-400D-B2FA-B4E7A7F9C3A3@gmail.com> Message-ID: <4A076186.7040206@wxs.nl> Bill Wendling wrote: > Did you forget a file in this commit? :-) > > /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/ > llvmCore~obj/src/lib/VMCore/Verifier.cpp: In function 'bool > isMetadata(llvm::Value*)': > /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/ > llvmCore~obj/src/lib/VMCore/Verifier.cpp:354: error: 'MDNode' was not > declared in this scope > /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/ > llvmCore~obj/src/lib/VMCore/Verifier.cpp:354: error: no matching > function for call to 'isa(llvm::Value*&)' There are some missing #includes. See attached patch. (LLVM will build without #including Type.h from MDNode.h, but only by accident: a file with MDNode.h as its first #include fails) -------------- next part -------------- A non-text attachment was scrubbed... Name: mdnode-includes.patch Type: text/x-patch Size: 793 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090511/ca5fd8df/attachment.bin From isanbard at gmail.com Sun May 10 18:27:42 2009 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 10 May 2009 23:27:42 -0000 Subject: [llvm-commits] [llvm] r71413 - in /llvm/trunk: include/llvm/MDNode.h lib/VMCore/Verifier.cpp Message-ID: <200905102327.n4ANRgWX010651@zion.cs.uiuc.edu> Author: void Date: Sun May 10 18:27:41 2009 New Revision: 71413 URL: http://llvm.org/viewvc/llvm-project?rev=71413&view=rev Log: Needed #includes. Thanks Fritz van Bommel! Modified: llvm/trunk/include/llvm/MDNode.h llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/include/llvm/MDNode.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MDNode.h?rev=71413&r1=71412&r2=71413&view=diff ============================================================================== --- llvm/trunk/include/llvm/MDNode.h (original) +++ llvm/trunk/include/llvm/MDNode.h Sun May 10 18:27:41 2009 @@ -22,6 +22,7 @@ #define LLVM_MDNODE_H #include "llvm/Constant.h" +#include "llvm/Type.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ValueHandle.h" Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=71413&r1=71412&r2=71413&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Sun May 10 18:27:41 2009 @@ -45,6 +45,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/IntrinsicInst.h" +#include "llvm/MDNode.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" #include "llvm/Pass.h" From isanbard at gmail.com Sun May 10 18:27:48 2009 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 10 May 2009 16:27:48 -0700 Subject: [llvm-commits] [llvm] r71407 - in /llvm/trunk: docs/LangRef.html include/llvm/Constants.h include/llvm/MDNode.h lib/AsmParser/LLParser.cpp lib/AsmParser/LLParser.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Writer/BitcodeWriter.cpp lib/Bitcode/Writer/ValueEnumerator.cpp lib/VMCore/AsmWriter.cpp lib/VMCore/Constants.cpp test/Feature/embeddedmetadata.ll unittests/VMCore/MetadataTest.cpp In-Reply-To: <4A076186.7040206@wxs.nl> References: <200905102057.n4AKv9Da006315@zion.cs.uiuc.edu> <343DE12B-8D9D-400D-B2FA-B4E7A7F9C3A3@gmail.com> <4A076186.7040206@wxs.nl> Message-ID: <0512338D-9420-456E-995D-DCC84E9C1C84@gmail.com> Applied. Thanks! -bw On May 10, 2009, at 4:21 PM, Frits van Bommel wrote: > Bill Wendling wrote: >> Did you forget a file in this commit? :-) >> /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/ >> llvmCore~obj/src/lib/VMCore/Verifier.cpp: In function 'bool >> isMetadata(llvm::Value*)': >> /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/ >> llvmCore~obj/src/lib/VMCore/Verifier.cpp:354: error: 'MDNode' was >> not declared in this scope >> /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/ >> llvmCore~obj/src/lib/VMCore/Verifier.cpp:354: error: no matching >> function for call to 'isa(llvm::Value*&)' > > There are some missing #includes. See attached patch. > (LLVM will build without #including Type.h from MDNode.h, but only > by accident: a file with MDNode.h as its first #include fails) > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Sun May 10 18:35:26 2009 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 10 May 2009 16:35:26 -0700 Subject: [llvm-commits] [llvm] r71413 - in /llvm/trunk: include/llvm/MDNode.h lib/VMCore/Verifier.cpp In-Reply-To: <200905102327.n4ANRgWX010651@zion.cs.uiuc.edu> References: <200905102327.n4ANRgWX010651@zion.cs.uiuc.edu> Message-ID: On May 10, 2009, at 4:27 PM, Bill Wendling wrote: > Author: void > Date: Sun May 10 18:27:41 2009 > New Revision: 71413 > > URL: http://llvm.org/viewvc/llvm-project?rev=71413&view=rev > Log: > Needed #includes. Thanks Fritz van Bommel! > And by "Fritz" I meant Frits... -bw From isanbard at gmail.com Sun May 10 18:43:26 2009 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 10 May 2009 23:43:26 -0000 Subject: [llvm-commits] [llvm] r71414 - /llvm/tags/Apple/llvmCore-2109/ Message-ID: <200905102343.n4ANhQGl011128@zion.cs.uiuc.edu> Author: void Date: Sun May 10 18:43:26 2009 New Revision: 71414 URL: http://llvm.org/viewvc/llvm-project?rev=71414&view=rev Log: Creating llvmCore-2109 branch Added: llvm/tags/Apple/llvmCore-2109/ - copied from r71413, llvm/branches/Apple/Dib/ From isanbard at gmail.com Sun May 10 18:43:34 2009 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 10 May 2009 23:43:34 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r71415 - /llvm-gcc-4.2/tags/Apple/llvmgcc42-2109/ Message-ID: <200905102343.n4ANhYSu011143@zion.cs.uiuc.edu> Author: void Date: Sun May 10 18:43:34 2009 New Revision: 71415 URL: http://llvm.org/viewvc/llvm-project?rev=71415&view=rev Log: Creating llvmgcc42-2109 branch Added: llvm-gcc-4.2/tags/Apple/llvmgcc42-2109/ - copied from r71414, llvm-gcc-4.2/branches/Apple/Dib/ From nicholas at mxc.ca Sun May 10 19:09:04 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 10 May 2009 17:09:04 -0700 Subject: [llvm-commits] [llvm] r71407 - in /llvm/trunk: docs/LangRef.html include/llvm/Constants.h include/llvm/MDNode.h lib/AsmParser/LLParser.cpp lib/AsmParser/LLParser.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Writer/BitcodeWriter.cpp lib/Bitcode/Writer/ValueEnumerator.cpp lib/VMCore/AsmWriter.cpp lib/VMCore/Constants.cpp test/Feature/embeddedmetadata.ll unittests/VMCore/MetadataTest.cpp In-Reply-To: <0512338D-9420-456E-995D-DCC84E9C1C84@gmail.com> References: <200905102057.n4AKv9Da006315@zion.cs.uiuc.edu> <343DE12B-8D9D-400D-B2FA-B4E7A7F9C3A3@gmail.com> <4A076186.7040206@wxs.nl> <0512338D-9420-456E-995D-DCC84E9C1C84@gmail.com> Message-ID: <4A076CA0.3030508@mxc.ca> Bill and Frits, thanks for the fix! I picked a very very bad time to be AFK for a while. Sorry! Nick Bill Wendling wrote: > Applied. Thanks! > > -bw > > On May 10, 2009, at 4:21 PM, Frits van Bommel wrote: > >> Bill Wendling wrote: >>> Did you forget a file in this commit? :-) >>> /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/ >>> llvmCore~obj/src/lib/VMCore/Verifier.cpp: In function 'bool >>> isMetadata(llvm::Value*)': >>> /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/ >>> llvmCore~obj/src/lib/VMCore/Verifier.cpp:354: error: 'MDNode' was >>> not declared in this scope >>> /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore.roots/ >>> llvmCore~obj/src/lib/VMCore/Verifier.cpp:354: error: no matching >>> function for call to 'isa(llvm::Value*&)' >> There are some missing #includes. See attached patch. >> (LLVM will build without #including Type.h from MDNode.h, but only >> by accident: a file with MDNode.h as its first #include fails) >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >