From aggarwa4 at illinois.edu Mon Jan 3 00:08:39 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 03 Jan 2011 06:08:39 -0000 Subject: [llvm-commits] [poolalloc] r122738 - /poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Message-ID: <20110103060840.012382A6C12C@llvm.org> Author: aggarwa4 Date: Mon Jan 3 00:08:39 2011 New Revision: 122738 URL: http://llvm.org/viewvc/llvm-project?rev=122738&view=rev Log: Remove dead code. No functionality changes. Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=122738&r1=122737&r2=122738&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original) +++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Mon Jan 3 00:08:39 2011 @@ -404,17 +404,11 @@ } return MyID; } else { - // - // SCCFunctions - Keep track of the functions in the current SCC - // - std::vector SCCFunctions; - unsigned SCCSize = 1; const Function *NF = Stack.back(); if(NF != F) ValMap[NF] = ~0U; DSGraph* SCCGraph = getDSGraph(*NF); - SCCFunctions.push_back(NF); // // First thing first: collapse all of the DSGraphs into a single graph for @@ -424,7 +418,6 @@ while (NF != F) { Stack.pop_back(); NF = Stack.back(); - SCCFunctions.push_back(NF); if(NF != F) ValMap[NF] = ~0U; @@ -467,8 +460,6 @@ } else { ValMap[F] = ~0U; } - - // We never have to revisit "SCC" processed functions... return MyID; } From nicholas at mxc.ca Mon Jan 3 00:16:07 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 03 Jan 2011 06:16:07 -0000 Subject: [llvm-commits] [llvm] r122739 - /llvm/trunk/docs/WritingAnLLVMPass.html Message-ID: <20110103061607.B56F82A6C12C@llvm.org> Author: nicholas Date: Mon Jan 3 00:16:07 2011 New Revision: 122739 URL: http://llvm.org/viewvc/llvm-project?rev=122739&view=rev Log: Further expand what a call graph pass may do. The rationale is that after analyzing a function in the SCC, we may want to modify it in a way that requires us to update its uses (f.e. to replace the call with a constant) or its users (f.e. to call it with fewer arguments). Modified: llvm/trunk/docs/WritingAnLLVMPass.html Modified: llvm/trunk/docs/WritingAnLLVMPass.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/WritingAnLLVMPass.html?rev=122739&r1=122738&r2=122739&view=diff ============================================================================== --- llvm/trunk/docs/WritingAnLLVMPass.html (original) +++ llvm/trunk/docs/WritingAnLLVMPass.html Mon Jan 3 00:16:07 2011 @@ -559,11 +559,9 @@
    -
  1. ... not allowed to modify any Functions that are not in -the current SCC.
  2. - -
  3. ... not allowed to inspect any Functions other than those -in the current SCC and the direct callers and direct callees of the SCC.
  4. +
  5. ... not allowed to inspect or modify any Functions other +than those in the current SCC and the direct callers and direct callees of the +SCC.
  6. ... required to preserve the current CallGraph object, updating it to reflect any changes made to the program.
  7. From sabre at nondot.org Mon Jan 3 00:19:09 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 06:19:09 -0000 Subject: [llvm-commits] [llvm] r122740 - /llvm/trunk/include/llvm/Support/StandardPasses.h Message-ID: <20110103061909.6C80C2A6C12C@llvm.org> Author: lattner Date: Mon Jan 3 00:19:09 2011 New Revision: 122740 URL: http://llvm.org/viewvc/llvm-project?rev=122740&view=rev Log: Turn on earlycse by default. This seems to be a small performance improvement in the generated code, and speeds up 'opt -std-compile-opts' compile time on 176.gcc from 24.84s to 23.2s (about 7%). This also resolves a specific code quality issue in rdar://7352081 which was generating poor code for: int t(int a, int b) { if (a & b & 1) return a & b; return 3; } Modified: llvm/trunk/include/llvm/Support/StandardPasses.h Modified: llvm/trunk/include/llvm/Support/StandardPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=122740&r1=122739&r2=122740&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) +++ llvm/trunk/include/llvm/Support/StandardPasses.h Mon Jan 3 00:19:09 2011 @@ -129,9 +129,9 @@ // Start of function pass. PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas + PM->add(createEarlyCSEPass()); // Catch trivial redundancies if (SimplifyLibCalls) PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations - PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. PM->add(createJumpThreadingPass()); // Thread jumps. PM->add(createCorrelatedValuePropagationPass()); // Propagate conditionals PM->add(createCFGSimplificationPass()); // Merge & remove BBs From zwarich at apple.com Mon Jan 3 00:33:01 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 03 Jan 2011 06:33:01 -0000 Subject: [llvm-commits] [llvm] r122741 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <20110103063301.3EBFB2A6C12C@llvm.org> Author: zwarich Date: Mon Jan 3 00:33:01 2011 New Revision: 122741 URL: http://llvm.org/viewvc/llvm-project?rev=122741&view=rev Log: Switch a worklist in CodeGenPrepare to SmallVector and increase the inline capacity on the Visited SmallPtrSet. On 403.gcc, this is about a 4.5% speedup of CodeGenPrepare time (which itself is 10% of time spent in the backend). This is progress towards PR8889. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=122741&r1=122740&r2=122741&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Mon Jan 3 00:33:01 2011 @@ -623,8 +623,8 @@ // Try to collapse single-value PHI nodes. This is necessary to undo // unprofitable PRE transformations. - std::vector worklist; - SmallPtrSet Visited; + SmallVector worklist; + SmallPtrSet Visited; worklist.push_back(Addr); // Use a worklist to iteratively look through PHI nodes, and ensure that From aggarwa4 at illinois.edu Mon Jan 3 00:45:06 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 03 Jan 2011 06:45:06 -0000 Subject: [llvm-commits] [poolalloc] r122742 - in /poolalloc/trunk: include/poolalloc/Heuristic.h lib/PoolAllocate/AllNodesHeuristic.cpp lib/PoolAllocate/Heuristic.cpp Message-ID: <20110103064506.EDAB32A6C12C@llvm.org> Author: aggarwa4 Date: Mon Jan 3 00:45:06 2011 New Revision: 122742 URL: http://llvm.org/viewvc/llvm-project?rev=122742&view=rev Log: Global DSNodes and those local DSNodes that mirror them all get the same pool now. Mirror the changes in SAFECode. Added: poolalloc/trunk/lib/PoolAllocate/AllNodesHeuristic.cpp Modified: poolalloc/trunk/include/poolalloc/Heuristic.h poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp Modified: poolalloc/trunk/include/poolalloc/Heuristic.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/poolalloc/Heuristic.h?rev=122742&r1=122741&r2=122742&view=diff ============================================================================== --- poolalloc/trunk/include/poolalloc/Heuristic.h (original) +++ poolalloc/trunk/include/poolalloc/Heuristic.h Mon Jan 3 00:45:06 2011 @@ -143,7 +143,13 @@ // to be pool allocated. // class AllNodesHeuristic: public Heuristic, public ModulePass { - public: + protected: + // Map of DSNodes to pool handles + std::map PoolMap; + void GetNodesReachableFromGlobals (DSGraph* G, + DenseSet &NodesFromGlobals); + + public: // Pass ID static char ID; @@ -173,9 +179,15 @@ AU.setPreservesAll(); } - // + void releaseMemory () { + PoolMap.clear(); + GlobalPoolNodes.clear(); + return; + } + // Interface methods // + virtual void findGlobalPoolNodes (DSNodeSet_t & Nodes); virtual void AssignToPools (const DSNodeList_t & NodesToPA, Function *F, DSGraph* G, std::vector &ResultPools); Added: poolalloc/trunk/lib/PoolAllocate/AllNodesHeuristic.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/AllNodesHeuristic.cpp?rev=122742&view=auto ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/AllNodesHeuristic.cpp (added) +++ poolalloc/trunk/lib/PoolAllocate/AllNodesHeuristic.cpp Mon Jan 3 00:45:06 2011 @@ -0,0 +1,256 @@ +//===-- Heuristic.cpp - Interface to PA heuristics ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This implements the various pool allocation heuristics. +// +// FIXME: It seems that the old alignment heuristics contained in this file +// were designed for 32-bit x86 processors (which makes sense as +// poolalloc was developed before x86-64). We need to revisit this +// code and decide what the heuristics should do today. +// +//===----------------------------------------------------------------------===// + +#include "dsa/DSGraphTraits.h" +#include "poolalloc/Heuristic.h" +#include "poolalloc/PoolAllocate.h" +#include "llvm/Instructions.h" +#include "llvm/Module.h" +#include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Target/TargetData.h" +#include + +using namespace llvm; +using namespace PA; + +// +// Function: GetNodesReachableFromGlobals() +// +// Description: +// This function finds all DSNodes which are reachable from globals. It finds +// DSNodes both within the local DSGraph as well as in the Globals graph that +// are reachable from globals. It does, however, filter out those DSNodes +// which are of no interest to automatic pool allocation. +// +// Inputs: +// G - The DSGraph for which to find DSNodes which are reachable by globals. +// This DSGraph can either by a DSGraph associated with a function *or* +// it can be the globals graph itself. +// +// Outputs: +// NodesFromGlobals - A reference to a container object in which to record +// DSNodes reachable from globals. DSNodes are *added* to +// this container; it is not cleared by this function. +// DSNodes from both the local and globals graph are added. +void +AllNodesHeuristic::GetNodesReachableFromGlobals (DSGraph* G, + DenseSet &NodesFromGlobals) { + // + // Get the globals graph associated with this DSGraph. If the globals graph + // is NULL, then the graph that was passed in *is* the globals graph. + // + DSGraph * GlobalsGraph = G->getGlobalsGraph(); + if (!GlobalsGraph) + GlobalsGraph = G; + + // + // Find all DSNodes which are reachable in the globals graph. + // + for (DSGraph::node_iterator NI = GlobalsGraph->node_begin(); + NI != GlobalsGraph->node_end(); + ++NI) { + NI->markReachableNodes(NodesFromGlobals); + } + + // + // Remove those global nodes which we know will never be pool allocated. + // + std::vector toRemove; + for (DenseSet::iterator I = NodesFromGlobals.begin(), + E = NodesFromGlobals.end(); I != E; ) { + DenseSet::iterator Last = I; ++I; + // + // Nodes that escape to external code could be reachable from globals. + // Nodes that are incomplete could be heap nodes. + // Unknown nodes could be anything. + // + const DSNode *tmp = *Last; + if (!(tmp->isHeapNode())) + toRemove.push_back (tmp); + } + + // + // Remove all globally reachable DSNodes which do not require pools. + // + for (unsigned index = 0; index < toRemove.size(); ++index) { + NodesFromGlobals.erase(toRemove[index]); + } + + // + // Now the fun part. Find DSNodes in the local graph that correspond to + // those nodes reachable in the globals graph. Add them to the set of + // reachable nodes, too. + // + if (G->getGlobalsGraph()) { + // + // Compute a mapping between local DSNodes and DSNodes in the globals + // graph. + // + DSGraph::NodeMapTy NodeMap; + G->computeGToGGMapping (NodeMap); + + // + // Scan through all DSNodes in the local graph. If a local DSNode has a + // corresponding DSNode in the globals graph that is reachable from a + // global, then add the local DSNode to the set of DSNodes reachable from a + // global. + // + // FIXME: A node's existance within the global DSGraph is probably + // sufficient evidence that it is reachable from a global. + // + + DSGraph::node_iterator ni = G->node_begin(); + for (; ni != G->node_end(); ++ni) { + DSNode * N = ni; + if (NodesFromGlobals.count (NodeMap[N].getNode())) + NodesFromGlobals.insert (N); + } + } +} + +// +// Method: findGlobalPoolNodes() +// +// Description: +// This method finds DSNodes that are reachable from globals and that need a +// pool. The Automatic Pool Allocation transform will use the returned +// information to build global pools for the DSNodes in question. +// +// Note that this method does not assign DSNodes to pools; it merely decides +// which DSNodes are reachable from globals and will need a pool of global +// scope. +// +// Outputs: +// Nodes - The DSNodes that are both reachable from globals and which should +// have global pools will be *added* to this container. +// +void +AllNodesHeuristic::findGlobalPoolNodes (DSNodeSet_t & Nodes) { + // Get the globals graph for the program. + DSGraph* GG = Graphs->getGlobalsGraph(); + + // Get all of the nodes reachable from globals. + DenseSet GlobalHeapNodes; + GetNodesReachableFromGlobals (GG, GlobalHeapNodes); + // + // Create a global pool for each global DSNode. + // + for (DenseSet::iterator NI = GlobalHeapNodes.begin(); + NI != GlobalHeapNodes.end();++NI) { + const DSNode * N = *NI; + PoolMap[N] = OnePool(N); + } + + // + // Now find all DSNodes belonging to function-local DSGraphs which are + // mirrored in the globals graph. These DSNodes require a global pool, too. + // + for (Module::iterator F = M->begin(); F != M->end(); ++F) { + if (Graphs->hasDSGraph(*F)) { + DSGraph* G = Graphs->getDSGraph(*F); + DSGraph::NodeMapTy NodeMap; + G->computeGToGGMapping (NodeMap); + // + // Scan through all DSNodes in the local graph. If a local DSNode has a + // corresponding DSNode in the globals graph that is reachable from a + // global, then add the local DSNode to the set of DSNodes reachable from + // a global. + // + DSGraph::node_iterator ni = G->node_begin(); + for (; ni != G->node_end(); ++ni) { + DSNode * N = ni; + DSNode * GGN = NodeMap[N].getNode(); + + //assert (!GGN || GlobalHeapNodes.count (GGN)); + if (GGN && GlobalHeapNodes.count (GGN)) + PoolMap[GGN].NodesInPool.push_back (N); + } + + + } + } + + // + // Copy the values into the output container. Note that DenseSet has no + // iterator traits (or whatever allows us to treat DenseSet has a generic + // container), so we have to use a loop to copy values from the DenseSet into + // the output container. + // + for (DenseSet::iterator I = GlobalHeapNodes.begin(), + E = GlobalHeapNodes.end(); I != E; ++I) { + Nodes.insert (*I); + } + + return; +} + +//===-- AllNodes Heuristic ------------------------------------------------===// +// +// This heuristic pool allocates everything possible into separate pools. +// + +bool +AllNodesHeuristic::runOnModule (Module & Module) { + // + // Remember which module we are analyzing. + // + M = &Module; + + // + // Get the reference to the DSA Graph. + // + Graphs = &getAnalysis(); + assert (Graphs && "No DSGraphs!\n"); + + // + // Find DSNodes which are reachable from globals and should be pool + // allocated. + // + findGlobalPoolNodes (GlobalPoolNodes); + + // We never modify anything in this pass + return false; +} + +void +AllNodesHeuristic::AssignToPools (const std::vector &NodesToPA, + Function *F, DSGraph* G, + std::vector &ResultPools) { + for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i){ + if (PoolMap.find (NodesToPA[i]) != PoolMap.end()) + ResultPools.push_back(PoolMap[NodesToPA[i]]); + else + ResultPools.push_back (OnePool(NodesToPA[i])); +// ResultPools.push_back(OnePool(NodesToPA[i])); + } +} + + +// +// Register all of the heuristic passes. +// +static RegisterPass +A ("paheur-AllNodes", "Pool allocate all nodes"); + +RegisterAnalysisGroup Heuristic1(A); + +char AllNodesHeuristic::ID = 0; + + Modified: poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp?rev=122742&r1=122741&r2=122742&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp Mon Jan 3 00:45:06 2011 @@ -438,42 +438,6 @@ return; } -//===-- AllNodes Heuristic ------------------------------------------------===// -// -// This heuristic pool allocates everything possible into separate pools. -// - -bool -AllNodesHeuristic::runOnModule (Module & Module) { - // - // Remember which module we are analyzing. - // - M = &Module; - - // - // Get the reference to the DSA Graph. - // - Graphs = &getAnalysis(); - assert (Graphs && "No DSGraphs!\n"); - - // - // Find DSNodes which are reachable from globals and should be pool - // allocated. - // - findGlobalPoolNodes (GlobalPoolNodes); - - // We never modify anything in this pass - return false; -} - -void -AllNodesHeuristic::AssignToPools (const std::vector &NodesToPA, - Function *F, DSGraph* G, - std::vector &ResultPools) { - for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) - ResultPools.push_back(OnePool(NodesToPA[i])); -} - //===-- AllButUnreachableFromMemoryHeuristic Heuristic --------------------===// // // This heuristic pool allocates everything possible into separate pools, unless @@ -937,9 +901,6 @@ // // Register all of the heuristic passes. // -static RegisterPass -A ("paheur-AllNodes", "Pool allocate all nodes"); - static RegisterPass B ("paheur-AllButUnreachableFromMemory", "Pool allocate all reachable from memory objects"); @@ -964,7 +925,6 @@ static RegisterAnalysisGroup HeuristicGroup ("Pool Allocation Heuristic"); -RegisterAnalysisGroup Heuristic1(A); RegisterAnalysisGroup Heuristic2(B); RegisterAnalysisGroup Heuristic3(C); RegisterAnalysisGroup Heuristic4(D); @@ -973,7 +933,6 @@ RegisterAnalysisGroup Heuristic7(G); char Heuristic::ID = 0; -char AllNodesHeuristic::ID = 0; char AllButUnreachableFromMemoryHeuristic::ID = 0; char CyclicNodesHeuristic::ID = 0; char SmartCoallesceNodesHeuristic::ID = 0; From rdivacky at freebsd.org Mon Jan 3 01:37:09 2011 From: rdivacky at freebsd.org (Roman Divacky) Date: Mon, 3 Jan 2011 08:37:09 +0100 Subject: [llvm-commits] [llvm] r122740 - /llvm/trunk/include/llvm/Support/StandardPasses.h In-Reply-To: <20110103061909.6C80C2A6C12C@llvm.org> References: <20110103061909.6C80C2A6C12C@llvm.org> Message-ID: <20110103073709.GA89749@freebsd.org> On Mon, Jan 03, 2011 at 06:19:09AM -0000, Chris Lattner wrote: > Author: lattner > Date: Mon Jan 3 00:19:09 2011 > New Revision: 122740 > > URL: http://llvm.org/viewvc/llvm-project?rev=122740&view=rev > Log: > Turn on earlycse by default. This seems to be a small performance > improvement in the generated code, and speeds up 'opt -std-compile-opts' > compile time on 176.gcc from 24.84s to 23.2s (about 7%). > > This also resolves a specific code quality issue in rdar://7352081 which > was generating poor code for: > > int t(int a, int b) { > if (a & b & 1) > return a & b; > return 3; > } > > > Modified: > llvm/trunk/include/llvm/Support/StandardPasses.h > > Modified: llvm/trunk/include/llvm/Support/StandardPasses.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=122740&r1=122739&r2=122740&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) > +++ llvm/trunk/include/llvm/Support/StandardPasses.h Mon Jan 3 00:19:09 2011 > @@ -129,9 +129,9 @@ > > // Start of function pass. > PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas > + PM->add(createEarlyCSEPass()); // Catch trivial redundancies > if (SimplifyLibCalls) > PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations > - PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. was removing the InstructionCombiningPass intended? gnu screen compiles to 344992 bytes without InstructionCombiningPass (as in trunk) but to 344624 bytes with the InstructionCombiningPass kept... on the other hand it hurts boot loader from freebsd a little (-145 bytes available to -165 bytes available) From evan.cheng at apple.com Mon Jan 3 01:53:18 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 03 Jan 2011 07:53:18 -0000 Subject: [llvm-commits] [llvm] r122743 - /llvm/trunk/include/llvm/Support/StandardPasses.h Message-ID: <20110103075318.909D72A6C12C@llvm.org> Author: evancheng Date: Mon Jan 3 01:53:18 2011 New Revision: 122743 URL: http://llvm.org/viewvc/llvm-project?rev=122743&view=rev Log: Undo what looks like accidental removal of an instcombine pass in r122740. Modified: llvm/trunk/include/llvm/Support/StandardPasses.h Modified: llvm/trunk/include/llvm/Support/StandardPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=122743&r1=122742&r2=122743&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) +++ llvm/trunk/include/llvm/Support/StandardPasses.h Mon Jan 3 01:53:18 2011 @@ -132,6 +132,7 @@ PM->add(createEarlyCSEPass()); // Catch trivial redundancies if (SimplifyLibCalls) PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations + PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. PM->add(createJumpThreadingPass()); // Thread jumps. PM->add(createCorrelatedValuePropagationPass()); // Propagate conditionals PM->add(createCFGSimplificationPass()); // Merge & remove BBs From evan.cheng at apple.com Mon Jan 3 01:57:10 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 02 Jan 2011 23:57:10 -0800 Subject: [llvm-commits] [llvm] r122740 - /llvm/trunk/include/llvm/Support/StandardPasses.h In-Reply-To: <20110103073709.GA89749@freebsd.org> References: <20110103061909.6C80C2A6C12C@llvm.org> <20110103073709.GA89749@freebsd.org> Message-ID: <872F6304-A6FF-4B35-8113-ACB6C3D27D20@apple.com> It does look like unintended change. I've added the instcombine pass back. Chris, please verify. Evan On Jan 2, 2011, at 11:37 PM, Roman Divacky wrote: > On Mon, Jan 03, 2011 at 06:19:09AM -0000, Chris Lattner wrote: >> Author: lattner >> Date: Mon Jan 3 00:19:09 2011 >> New Revision: 122740 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122740&view=rev >> Log: >> Turn on earlycse by default. This seems to be a small performance >> improvement in the generated code, and speeds up 'opt -std-compile-opts' >> compile time on 176.gcc from 24.84s to 23.2s (about 7%). >> >> This also resolves a specific code quality issue in rdar://7352081 which >> was generating poor code for: >> >> int t(int a, int b) { >> if (a & b & 1) >> return a & b; >> return 3; >> } >> >> >> Modified: >> llvm/trunk/include/llvm/Support/StandardPasses.h >> >> Modified: llvm/trunk/include/llvm/Support/StandardPasses.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=122740&r1=122739&r2=122740&view=diff >> ============================================================================== >> --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) >> +++ llvm/trunk/include/llvm/Support/StandardPasses.h Mon Jan 3 00:19:09 2011 >> @@ -129,9 +129,9 @@ >> >> // Start of function pass. >> PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas >> + PM->add(createEarlyCSEPass()); // Catch trivial redundancies >> if (SimplifyLibCalls) >> PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations >> - PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. > > was removing the InstructionCombiningPass intended? > > gnu screen compiles to 344992 bytes without InstructionCombiningPass (as in trunk) > but to 344624 bytes with the InstructionCombiningPass kept... > > on the other hand it hurts boot loader from freebsd a little (-145 bytes available > to -165 bytes available) > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Mon Jan 3 02:37:00 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 03 Jan 2011 09:37:00 +0100 Subject: [llvm-commits] [llvm] r122680 - in /llvm/trunk/include/llvm/Analysis: DominatorInternals.h Dominators.h In-Reply-To: <20110102070300.9107C2A6C12C@llvm.org> References: <20110102070300.9107C2A6C12C@llvm.org> Message-ID: <4D218AAC.6090008@free.fr> Hi Cameron, > --- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original) > +++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Sun Jan 2 01:03:00 2011 > @@ -257,12 +257,24 @@ > // infinite loops). In these cases an artificial exit node is required. > MultipleRoots |= (DT.isPostDominator()&& N != F.size()); > > + std::vector Buckets; how about using SmallVector? Ciao, Duncan. From zwarich at apple.com Mon Jan 3 02:47:42 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 3 Jan 2011 00:47:42 -0800 Subject: [llvm-commits] [llvm] r122680 - in /llvm/trunk/include/llvm/Analysis: DominatorInternals.h Dominators.h In-Reply-To: <4D218AAC.6090008@free.fr> References: <20110102070300.9107C2A6C12C@llvm.org> <4D218AAC.6090008@free.fr> Message-ID: On Jan 3, 2011, at 12:37 AM, Duncan Sands wrote: > Hi Cameron, > >> --- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original) >> +++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Sun Jan 2 01:03:00 2011 >> @@ -257,12 +257,24 @@ >> // infinite loops). In these cases an artificial exit node is required. >> MultipleRoots |= (DT.isPostDominator()&& N != F.size()); >> >> + std::vector Buckets; > > how about using SmallVector? That might be a good idea. I guess I didn't think about it because there is already so much other allocation going on, and this is just once per pass. Cameron From baldrick at free.fr Mon Jan 3 03:24:13 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 03 Jan 2011 10:24:13 +0100 Subject: [llvm-commits] [llvm] r122704 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll In-Reply-To: <20110102190103.6EECD2A6C12C@llvm.org> References: <20110102190103.6EECD2A6C12C@llvm.org> Message-ID: <4D2195BD.5000402@free.fr> Hi Chris, > enhance loop idiom recognition to scan *all* unconditionally executed > blocks in a loop, instead of just the header block. This makes it more > aggressive, able to handle Duncan's Ada examples. thanks for doing this! I noticed two issues with the examples I sent you, which now compile to define void @ubytezero([256 x i32]* %a) nounwind { return: %tmp32 = getelementptr [256 x i32]* %a, i32 0, i32 0 store i32 0, i32* %tmp32, align 4 %scevgep = getelementptr [256 x i32]* %a, i32 0, i32 1 %scevgep4 = bitcast i32* %scevgep to i8* call void @llvm.memset.p0i8.i32(i8* %scevgep4, i8 0, i32 1020, i32 4, i1 false) ret void } define void @uintzero(i32* %a) nounwind { return: store i32 0, i32* %a, align 4 %scevgep = getelementptr i32* %a, i32 1 %scevgep3 = bitcast i32* %scevgep to i8* call void @llvm.memset.p0i8.i32(i8* %scevgep3, i8 0, i32 -4, i32 4, i1 false) ret void } In both functions the memset could also take care of the store to the first element, rather than starting from the second element. However maybe merging the store and the memset should be a job for a different pass. Secondly, notice that the size of the memset in the second function is -4. Hopefully this will work correctly (i.e. memset 2^32-4 values)! It did make me wonder what happens if the loop stores say 2^32 or 2^48 values. Presumably the type of the memset size argument is automagically set to a size that can hold the loop trip count... Ciao, Duncan. From baldrick at free.fr Mon Jan 3 04:30:00 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 03 Jan 2011 11:30:00 +0100 Subject: [llvm-commits] [llvm] r122719 - in /llvm/trunk: include/llvm/InitializePasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/CMakeLists.txt lib/Transforms/Scalar/LoopInstSimplify.cpp lib/Transforms/Scalar/Scalar.cpp In-Reply-To: <20110103002516.F06722A6C12C@llvm.org> References: <20110103002516.F06722A6C12C@llvm.org> Message-ID: <4D21A528.4040003@free.fr> Hi Cameron, > Add a new loop-instsimplify pass, with the intention of replacing the instance > of instcombine that is currently in the middle of the loop pass pipeline. This > commit only checks in the pass; it will hopefully be enabled by default later. ... > + AU.addRequired(); Why do you require the dominator tree? Starting from the header you can get all CFG successors by looping over the successors and visiting those. By the very definition of dominance this will visit definitions before uses. It is simple to check whether a basic block is in the loop using LoopInfo, so you can just skip the ones that aren't. I guess there might be a problem with subloops if you want to skip those. > +bool LoopInstSimplify::runOnLoop(Loop* L, LPPassManager& LPM) { > + DominatorTree* DT =&getAnalysis(); Usual style is a space before the * not after. > + if (Visited.count(BB)) > + continue; > + Visited.insert(BB); Here you can just do: if (!Visited.insert(BB)) continue; > + DomTreeNode* Node = DT->getNode(BB); > + const std::vector& Children = Node->getChildren(); > + for (unsigned i = 0; i< Children.size(); ++i) { > + // Only visit children that are in the same loop. > + BasicBlock* ChildBB = Children[i]->getBlock(); > + if (!Visited.count(ChildBB)&& LI->getLoopFor(ChildBB) == L) > + VisitStack.push_back(ChildBB); > + } As mentioned above, I don't see the point of using the domtree for this. > + // Nothing that SimplifyInstruction() does should invalidate LCSSA form. > + assert(L->isLCSSAForm(*DT)); As discussed off list this is not true, as InstructionSimplify may look through phi nodes. Ciao, Duncan. From baldrick at free.fr Mon Jan 3 04:50:04 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 03 Jan 2011 10:50:04 -0000 Subject: [llvm-commits] [llvm] r122745 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Message-ID: <20110103105004.9E1042A6C12C@llvm.org> Author: baldrick Date: Mon Jan 3 04:50:04 2011 New Revision: 122745 URL: http://llvm.org/viewvc/llvm-project?rev=122745&view=rev Log: Speed up instsimplify by about 10-15% by not bothering to retry InstructionSimplify on instructions that didn't change since the last time round the loop. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Modified: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp?rev=122745&r1=122744&r2=122745&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Mon Jan 3 04:50:04 2011 @@ -19,6 +19,7 @@ #include "llvm/Pass.h" #include "llvm/Type.h" #include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" @@ -44,28 +45,38 @@ bool runOnFunction(Function &F) { const DominatorTree *DT = getAnalysisIfAvailable(); const TargetData *TD = getAnalysisIfAvailable(); + SmallPtrSet S1, S2, *ToSimplify = &S1, *Next = &S2; bool Changed = false; - bool LocalChanged; do { - LocalChanged = false; - for (df_iterator DI = df_begin(&F.getEntryBlock()), DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) for (BasicBlock::iterator BI = DI->begin(), BE = DI->end(); BI != BE;) { Instruction *I = BI++; - // Don't bother simplifying unused instructions. + // The first time through the loop ToSimplify is empty and we try to + // simplify all instructions. On later iterations ToSimplify is not + // empty and we only bother simplifying instructions that are in it. + if (!ToSimplify->empty() && !ToSimplify->count(I)) + continue; + // Don't waste time simplifying unused instructions. if (!I->use_empty()) if (Value *V = SimplifyInstruction(I, TD, DT)) { + // Mark all uses for resimplification next time round the loop. + for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); + UI != UE; ++UI) + Next->insert(cast(*UI)); I->replaceAllUsesWith(V); - LocalChanged = true; ++NumSimplified; + Changed = true; } - LocalChanged |= RecursivelyDeleteTriviallyDeadInstructions(I); + Changed |= RecursivelyDeleteTriviallyDeadInstructions(I); } - Changed |= LocalChanged; - } while (LocalChanged); + // Place the list of instructions to simplify on the next loop iteration + // into ToSimplify. + std::swap(ToSimplify, Next); + Next->clear(); + } while (!ToSimplify->empty()); return Changed; } From aggarwa4 at illinois.edu Mon Jan 3 04:57:02 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 03 Jan 2011 10:57:02 -0000 Subject: [llvm-commits] [poolalloc] r122746 - /poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Message-ID: <20110103105702.2E6482A6C12C@llvm.org> Author: aggarwa4 Date: Mon Jan 3 04:57:02 2011 New Revision: 122746 URL: http://llvm.org/viewvc/llvm-project?rev=122746&view=rev Log: Formatting changes. No functionality change. Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=122746&r1=122745&r2=122746&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original) +++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Mon Jan 3 04:57:02 2011 @@ -51,11 +51,8 @@ // BU: // Construct the callgraph from the local graphs // Find SCCs -// inline bottum up +// inline bottom up // -// We must split these out (they were merged in PLDI07) to handle multiple -// entry-points correctly. As a bonus, we can be more aggressive at propagating -// information upwards, as long as we don't remove unresolved call sites. bool BUDataStructures::runOnModuleInternal(Module& M) { // @@ -98,7 +95,7 @@ // Merge the globals variables (not the calls) from the globals graph back // into the individual function's graph so that changes made to globals during // BU can be reflected. This is specifically needed for correct call graph - + // for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (!(F->isDeclaration())){ DSGraph *Graph = getOrCreateGraph(F); @@ -112,10 +109,13 @@ Graph->computeIntPtrFlags(); } } + + // Once the correct flags have been calculated. Update the callgraph. for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (!(F->isDeclaration())){ DSGraph *Graph = getOrCreateGraph(F); - Graph->buildCompleteCallGraph(callgraph, GlobalFunctionList, filterCallees); + Graph->buildCompleteCallGraph(callgraph, + GlobalFunctionList, filterCallees); } } @@ -140,11 +140,10 @@ std::vector::iterator I = Callees.begin(); CallSite CS = DCS.getCallSite(); - while(I != Callees.end()) { + while (I != Callees.end()) { if (functionIsCallable(CS, *I)) { ++I; - } - else { + } else { I = Callees.erase(I); } } @@ -229,13 +228,13 @@ unsigned NextID = 1; - // do post order traversal on the global ctors. Use this information to update + // Do post order traversal on the global ctors. Use this information to update // the globals graph. const char *Name = "llvm.global_ctors"; GlobalVariable *GV = M.getNamedGlobal(Name); - if (GV && !(GV->isDeclaration()) && !(GV->hasLocalLinkage())){ - // Should be an array of '{ int, void ()* }' structs. The first value is - // the init priority, which we ignore. + if (GV && !(GV->isDeclaration()) && !(GV->hasLocalLinkage())) { + // Should be an array of '{ int, void ()* }' structs. The first value is + // the init priority, which we ignore. ConstantArray *InitList = dyn_cast(GV->getInitializer()); if (InitList) { for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) @@ -263,7 +262,7 @@ DSGraph::DontCloneAuxCallNodes); } } - } + } } // @@ -288,7 +287,6 @@ calculateGraphs(I, Stack, NextID, ValMap); // Calculate all graphs. CloneAuxIntoGlobal(getDSGraph(*I)); } - return; } @@ -471,7 +469,7 @@ // // Description: // This method takes the specified graph and processes each unresolved call -// site (a call site for which all targets are not yet known). For each +// site (a call site for which all targets are not yet known). For each // unresolved call site, it adds it to the globals graph and merges // information about the call site if the globals graph already had the call // site in its own list of unresolved call sites. @@ -620,7 +618,6 @@ cloneIntoGlobals(Graph, DSGraph::DontCloneCallNodes | DSGraph::DontCloneAuxCallNodes | DSGraph::StripAllocaBit); - //Graph.writeGraphToFile(cerr, "bu_" + F.getName()); - + //Graph->writeGraphToFile(cerr, "bu_" + F.getName()); } From zwarich at apple.com Mon Jan 3 05:22:27 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 03 Jan 2011 03:22:27 -0800 Subject: [llvm-commits] [llvm] r122719 - in /llvm/trunk: include/llvm/InitializePasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/CMakeLists.txt lib/Transforms/Scalar/LoopInstSimplify.cpp lib/Transforms/Scalar/Scalar.cpp In-Reply-To: <4D21A528.4040003@free.fr> References: <20110103002516.F06722A6C12C@llvm.org> <4D21A528.4040003@free.fr> Message-ID: <4F459E2D-0169-411A-8424-84E3F3D838AE@apple.com> On 2011-01-03, at 2:30 AM, Duncan Sands wrote: > Why do you require the dominator tree? Starting from the header you can get all > CFG successors by looping over the successors and visiting those. By the very > definition of dominance this will visit definitions before uses. It is simple > to check whether a basic block is in the loop using LoopInfo, so you can just > skip the ones that aren't. I guess there might be a problem with subloops if > you want to skip those. At the time I wanted to skip subloops, but that's just as easy to do without dominators. I'll switch to something simpler on the CFG alone. >> +bool LoopInstSimplify::runOnLoop(Loop* L, LPPassManager& LPM) { >> + DominatorTree* DT =&getAnalysis(); > > Usual style is a space before the * not after. Is this true? I see both all over LLVM. I try to duplicate the style of whatever file I'm in, but when it's a new file I'm not sure which other style to emulate. Cameron From baldrick at free.fr Mon Jan 3 06:43:47 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 03 Jan 2011 13:43:47 +0100 Subject: [llvm-commits] [llvm] r122727 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp test/Transforms/EarlyCSE/basic.ll In-Reply-To: <20110103031843.ACD052A6C12C@llvm.org> References: <20110103031843.ACD052A6C12C@llvm.org> Message-ID: <4D21C483.8000109@free.fr> Hi Chris, > +unsigned DenseMapInfo::getHashValue(MemoryValue Val) { > + Instruction *Inst = Val.Inst; > + // Hash in all of the operands as pointers. > + unsigned Res = 0; > + for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) > + Res ^= getHash(Inst->getOperand(i))<< i; > + // Mix in the opcode. > + return (Res<< 1) ^ Inst->getOpcode(); > +} for calls you could also hash in the attributes. Ciao, Duncan. From richard at metafoo.co.uk Mon Jan 3 06:44:43 2011 From: richard at metafoo.co.uk (Richard Smith) Date: Mon, 3 Jan 2011 12:44:43 -0000 (UTC) Subject: [llvm-commits] [PATCH] [MC] Reading off end of buffer when disassembling truncated x86 asm (PR7710) Message-ID: <57603.10.0.16.53.1294058683.squirrel@webmail.cantab.net> Hi, The attached patch (also attached to PR7710) fixes two issues which cause llvm-mc to incorrectly disassemble truncated asm: 1) A off-by-one error in llvm-mc's MemoryObject allowed reading one byte past the end of the buffer. 2) The X86 disassembler did not bail out with an error if it encountered a read error when parsing the mod/rm byte. Please review (and commit). Thanks, Richard -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-7710.diff Type: text/x-patch Size: 1240 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110103/6a412b71/attachment.bin From baldrick at free.fr Mon Jan 3 06:46:50 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 03 Jan 2011 13:46:50 +0100 Subject: [llvm-commits] [llvm] r122731 - /llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp In-Reply-To: <20110103034128.092322A6C12C@llvm.org> References: <20110103034128.092322A6C12C@llvm.org> Message-ID: <4D21C53A.10207@free.fr> Hi Chris, > split loads and calls into separate tables. Loads are now just indexed > by their pointer instead of using MemoryValue to wrap it. for readnone calls you don't have to worry about generations, writing to memory etc, you can treat them the same as (eg) an "add" instruction. Ciao, Duncan. From ofv at wanadoo.es Mon Jan 3 10:59:53 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Mon, 03 Jan 2011 16:59:53 -0000 Subject: [llvm-commits] [llvm] r122749 - /llvm/trunk/cmake/modules/LLVMProcessSources.cmake Message-ID: <20110103165953.1752F2A6C12C@llvm.org> Author: ofv Date: Mon Jan 3 10:59:52 2011 New Revision: 122749 URL: http://llvm.org/viewvc/llvm-project?rev=122749&view=rev Log: LLVMProcessSources: add .def files along with .h files to targets for the benefit of project-based generators (VS, XCode, etc). Modified: llvm/trunk/cmake/modules/LLVMProcessSources.cmake Modified: llvm/trunk/cmake/modules/LLVMProcessSources.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMProcessSources.cmake?rev=122749&r1=122748&r2=122749&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVMProcessSources.cmake (original) +++ llvm/trunk/cmake/modules/LLVMProcessSources.cmake Mon Jan 3 10:59:52 2011 @@ -12,7 +12,7 @@ macro(add_header_files srcs) - file(GLOB hds *.h) + file(GLOB hds *.h *.def) if( hds ) set_source_files_properties(${hds} PROPERTIES HEADER_FILE_ONLY ON) list(APPEND ${srcs} ${hds}) From greened at obbligato.org Mon Jan 3 11:30:25 2011 From: greened at obbligato.org (David Greene) Date: Mon, 03 Jan 2011 17:30:25 -0000 Subject: [llvm-commits] [llvm] r122754 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py Message-ID: <20110103173025.CCF792A6C12C@llvm.org> Author: greened Date: Mon Jan 3 11:30:25 2011 New Revision: 122754 URL: http://llvm.org/viewvc/llvm-project?rev=122754&view=rev Log: Reapply 122341 to fix PR8199 now that clang changes are in. Modified: llvm/trunk/docs/TestingGuide.html llvm/trunk/test/lit.cfg llvm/trunk/utils/lit/lit/TestRunner.py Modified: llvm/trunk/docs/TestingGuide.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TestingGuide.html?rev=122754&r1=122753&r2=122754&view=diff ============================================================================== --- llvm/trunk/docs/TestingGuide.html (original) +++ llvm/trunk/docs/TestingGuide.html Mon Jan 3 11:30:25 2011 @@ -376,6 +376,11 @@ shell. Consequently the syntax differs from normal shell script syntax in a few ways. You can specify as many RUN lines as needed.

    +

    lit performs substitution on each RUN line to replace LLVM tool + names with the full paths to the executable built for each tool (in + $(LLVM_OBJ_ROOT)/$(BuildMode)/bin). This ensures that lit does not + invoke any stray LLVM tools in the user's path during testing.

    +

    Each RUN line is executed on its own, distinct from other lines unless its last character is \. This continuation character causes the RUN line to be concatenated with the next one. In this way you can build up long Modified: llvm/trunk/test/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=122754&r1=122753&r2=122754&view=diff ============================================================================== --- llvm/trunk/test/lit.cfg (original) +++ llvm/trunk/test/lit.cfg Mon Jan 3 11:30:25 2011 @@ -4,6 +4,7 @@ import os import sys +import re # name: The name of this test suite. config.name = 'LLVM' @@ -148,6 +149,44 @@ else: config.substitutions.append(('%' + sub, site_exp[sub])) +# For each occurrence of an llvm tool name as its own word, replace it +# with the full path to the build directory holding that tool. This +# ensures that we are testing the tools just built and not some random +# tools that might happen to be in the user's PATH. Thus this list +# includes every tool placed in $(LLVM_OBJ_ROOT)/$(BuildMode)/bin +# (llvm_tools_dir in lit parlance). + # Don't match 'bugpoint-'. +for pattern in [r"\bbugpoint\b(?!-)", r"\bclang\b", + r"\bedis\b", r"\bgold\b", + r"\bllc\b", r"\blli\b", + r"\bllvm-ar\b", r"\bllvm-as\b", + r"\bllvm-bcanalyzer\b", r"\bllvm-config\b", + r"\bllvm-diff\b", r"\bllvm-dis\b", + r"\bllvm-extract\b", r"\bllvm-ld\b", + r"\bllvm-link\b", r"\bllvm-mc\b", + r"\bllvm-nm\b", r"\bllvm-prof\b", + r"\bllvm-ranlib\b", r"\bllvm-shlib\b", + r"\bllvm-stub\b", r"\bllvm2cpp\b", + # Don't match '-llvmc'. + r"(? References: <20110103075318.909D72A6C12C@llvm.org> Message-ID: On Jan 2, 2011, at 11:53 PM, Evan Cheng wrote: > Author: evancheng > Date: Mon Jan 3 01:53:18 2011 > New Revision: 122743 > > URL: http://llvm.org/viewvc/llvm-project?rev=122743&view=rev > Log: > Undo what looks like accidental removal of an instcombine pass in r122740. This wasn't accidental, is there a reason you want an instcombine here? -Chris > > Modified: > llvm/trunk/include/llvm/Support/StandardPasses.h > > Modified: llvm/trunk/include/llvm/Support/StandardPasses.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=122743&r1=122742&r2=122743&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) > +++ llvm/trunk/include/llvm/Support/StandardPasses.h Mon Jan 3 01:53:18 2011 > @@ -132,6 +132,7 @@ > PM->add(createEarlyCSEPass()); // Catch trivial redundancies > if (SimplifyLibCalls) > PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations > + PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. > PM->add(createJumpThreadingPass()); // Thread jumps. > PM->add(createCorrelatedValuePropagationPass()); // Propagate conditionals > PM->add(createCFGSimplificationPass()); // Merge & remove BBs > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Mon Jan 3 12:28:15 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 18:28:15 -0000 Subject: [llvm-commits] [llvm] r122758 - /llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Message-ID: <20110103182815.F28932A6C12C@llvm.org> Author: lattner Date: Mon Jan 3 12:28:15 2011 New Revision: 122758 URL: http://llvm.org/viewvc/llvm-project?rev=122758&view=rev Log: fix PR8895: metadata operands don't have a strong use of their nested values, so they can change and drop to null, which can change the hash and cause havok. It turns out that it isn't a good idea to value number stuff with metadata operands anyway, so... don't. Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122758&r1=122757&r2=122758&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Mon Jan 3 12:28:15 2011 @@ -145,9 +145,15 @@ } static bool canHandle(Instruction *Inst) { - if (CallInst *CI = dyn_cast(Inst)) - return CI->onlyReadsMemory(); - return false; + CallInst *CI = dyn_cast(Inst); + if (CI == 0 || !CI->onlyReadsMemory()) + return false; + + // Check that there are no metadata operands. + for (unsigned i = 0, e = CI->getNumOperands(); i != e; ++i) + if (CI->getOperand(i)->getType()->isMetadataTy()) + return false; + return true; } }; } @@ -407,7 +413,7 @@ if (LastStore && LastStore->getPointerOperand() == SI->getPointerOperand()) { DEBUG(dbgs() << "EarlyCSE DEAD STORE: " << *LastStore << " due to: " - << *Inst << '\n'); + << *Inst << '\n'); LastStore->eraseFromParent(); Changed = true; ++NumDSE; From sabre at nondot.org Mon Jan 3 12:43:03 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 18:43:03 -0000 Subject: [llvm-commits] [llvm] r122759 - /llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Message-ID: <20110103184303.B37E92A6C12C@llvm.org> Author: lattner Date: Mon Jan 3 12:43:03 2011 New Revision: 122759 URL: http://llvm.org/viewvc/llvm-project?rev=122759&view=rev Log: stength reduce my previous patch a bit. The only instructions that are allowed to have metadata operands are intrinsic calls, and the only ones that take metadata currently return void. Just reject all void instructions, which should not be value numbered anyway. To future proof things, add an assert to the getHashValue impl for calls to check that metadata operands aren't present. Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122759&r1=122758&r2=122759&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Mon Jan 3 12:43:03 2011 @@ -145,14 +145,13 @@ } static bool canHandle(Instruction *Inst) { + // Don't value number anything that returns void. + if (Inst->getType()->isVoidTy()) + return false; + CallInst *CI = dyn_cast(Inst); if (CI == 0 || !CI->onlyReadsMemory()) return false; - - // Check that there are no metadata operands. - for (unsigned i = 0, e = CI->getNumOperands(); i != e; ++i) - if (CI->getOperand(i)->getType()->isMetadataTy()) - return false; return true; } }; @@ -179,8 +178,12 @@ Instruction *Inst = Val.Inst; // Hash in all of the operands as pointers. unsigned Res = 0; - for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) + for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) { + assert(!Inst->getOperand(i)->getType()->isMetadataTy() && + "Cannot value number calls with metadata operands"); Res ^= getHash(Inst->getOperand(i)) << i; + } + // Mix in the opcode. return (Res << 1) ^ Inst->getOpcode(); } From clattner at apple.com Mon Jan 3 12:47:55 2011 From: clattner at apple.com (Chris Lattner) Date: Mon, 3 Jan 2011 10:47:55 -0800 Subject: [llvm-commits] [llvm] r122727 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp test/Transforms/EarlyCSE/basic.ll In-Reply-To: <4D21C483.8000109@free.fr> References: <20110103031843.ACD052A6C12C@llvm.org> <4D21C483.8000109@free.fr> Message-ID: <23C076BF-E5AA-405A-9F2C-CEA6624AD890@apple.com> On Jan 3, 2011, at 4:43 AM, Duncan Sands wrote: > Hi Chris, > >> +unsigned DenseMapInfo::getHashValue(MemoryValue Val) { >> + Instruction *Inst = Val.Inst; >> + // Hash in all of the operands as pointers. >> + unsigned Res = 0; >> + for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) >> + Res ^= getHash(Inst->getOperand(i))<< i; >> + // Mix in the opcode. >> + return (Res<< 1) ^ Inst->getOpcode(); >> +} > > for calls you could also hash in the attributes. The attributes for calls with identical arguments are almost always the same. This would just make the hash slower without reducing collisions IMO. -Chris From baldrick at free.fr Mon Jan 3 12:52:33 2011 From: baldrick at free.fr (Duncan Sands) Date: Mon, 03 Jan 2011 19:52:33 +0100 Subject: [llvm-commits] [llvm] r122727 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp test/Transforms/EarlyCSE/basic.ll In-Reply-To: <23C076BF-E5AA-405A-9F2C-CEA6624AD890@apple.com> References: <20110103031843.ACD052A6C12C@llvm.org> <4D21C483.8000109@free.fr> <23C076BF-E5AA-405A-9F2C-CEA6624AD890@apple.com> Message-ID: <4D221AF1.1050401@free.fr> Hi Chris, >>> +unsigned DenseMapInfo::getHashValue(MemoryValue Val) { >>> + Instruction *Inst = Val.Inst; >>> + // Hash in all of the operands as pointers. >>> + unsigned Res = 0; >>> + for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) >>> + Res ^= getHash(Inst->getOperand(i))<< i; >>> + // Mix in the opcode. >>> + return (Res<< 1) ^ Inst->getOpcode(); >>> +} >> >> for calls you could also hash in the attributes. > > The attributes for calls with identical arguments are almost always the same. This would just make the hash slower without reducing collisions IMO. since you only need to hash in the pointer to the attributes, it would be very cheap to do it. There is no need to hash in each individual attribute. Ciao, Duncan. From resistor at mac.com Mon Jan 3 13:00:11 2011 From: resistor at mac.com (Owen Anderson) Date: Mon, 03 Jan 2011 19:00:11 -0000 Subject: [llvm-commits] [llvm] r122760 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <20110103190011.5A0042A6C12C@llvm.org> Author: resistor Date: Mon Jan 3 13:00:11 2011 New Revision: 122760 URL: http://llvm.org/viewvc/llvm-project?rev=122760&view=rev Log: Simplify GVN's value expression structure, allowing the elimination of a lot of almost-but-not-quite-identical code. No intended functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=122760&r1=122759&r2=122760&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Mon Jan 3 13:00:11 2011 @@ -72,62 +72,20 @@ /// two values. namespace { struct Expression { - enum ExpressionOpcode { - ADD = Instruction::Add, - FADD = Instruction::FAdd, - SUB = Instruction::Sub, - FSUB = Instruction::FSub, - MUL = Instruction::Mul, - FMUL = Instruction::FMul, - UDIV = Instruction::UDiv, - SDIV = Instruction::SDiv, - FDIV = Instruction::FDiv, - UREM = Instruction::URem, - SREM = Instruction::SRem, - FREM = Instruction::FRem, - SHL = Instruction::Shl, - LSHR = Instruction::LShr, - ASHR = Instruction::AShr, - AND = Instruction::And, - OR = Instruction::Or, - XOR = Instruction::Xor, - TRUNC = Instruction::Trunc, - ZEXT = Instruction::ZExt, - SEXT = Instruction::SExt, - FPTOUI = Instruction::FPToUI, - FPTOSI = Instruction::FPToSI, - UITOFP = Instruction::UIToFP, - SITOFP = Instruction::SIToFP, - FPTRUNC = Instruction::FPTrunc, - FPEXT = Instruction::FPExt, - PTRTOINT = Instruction::PtrToInt, - INTTOPTR = Instruction::IntToPtr, - BITCAST = Instruction::BitCast, - ICMPEQ, ICMPNE, ICMPUGT, ICMPUGE, ICMPULT, ICMPULE, - ICMPSGT, ICMPSGE, ICMPSLT, ICMPSLE, FCMPOEQ, - FCMPOGT, FCMPOGE, FCMPOLT, FCMPOLE, FCMPONE, - FCMPORD, FCMPUNO, FCMPUEQ, FCMPUGT, FCMPUGE, - FCMPULT, FCMPULE, FCMPUNE, EXTRACT, INSERT, - SHUFFLE, SELECT, GEP, CALL, CONSTANT, - INSERTVALUE, EXTRACTVALUE, EMPTY, TOMBSTONE }; - - ExpressionOpcode opcode; + uint32_t opcode; const Type* type; SmallVector varargs; - Value *function; Expression() { } - Expression(ExpressionOpcode o) : opcode(o) { } + Expression(uint32_t o) : opcode(o) { } bool operator==(const Expression &other) const { if (opcode != other.opcode) return false; - else if (opcode == EMPTY || opcode == TOMBSTONE) + else if (opcode == ~0U || opcode == ~1U) return true; else if (type != other.type) return false; - else if (function != other.function) - return false; else if (varargs != other.varargs) return false; return true; @@ -148,19 +106,7 @@ uint32_t nextValueNumber; - Expression::ExpressionOpcode getOpcode(CmpInst* C); - Expression create_expression(BinaryOperator* BO); - Expression create_expression(CmpInst* C); - Expression create_expression(ShuffleVectorInst* V); - Expression create_expression(ExtractElementInst* C); - Expression create_expression(InsertElementInst* V); - Expression create_expression(SelectInst* V); - Expression create_expression(CastInst* C); - Expression create_expression(GetElementPtrInst* G); - Expression create_expression(CallInst* C); - Expression create_expression(ExtractValueInst* C); - Expression create_expression(InsertValueInst* C); - + Expression create_expression(Instruction* I); uint32_t lookup_or_add_call(CallInst* C); public: ValueTable() : nextValueNumber(1) { } @@ -181,11 +127,11 @@ namespace llvm { template <> struct DenseMapInfo { static inline Expression getEmptyKey() { - return Expression(Expression::EMPTY); + return ~0U; } static inline Expression getTombstoneKey() { - return Expression(Expression::TOMBSTONE); + return ~1U; } static unsigned getHashValue(const Expression e) { @@ -197,11 +143,7 @@ for (SmallVector::const_iterator I = e.varargs.begin(), E = e.varargs.end(); I != E; ++I) hash = *I + hash * 37; - - hash = ((unsigned)((uintptr_t)e.function >> 4) ^ - (unsigned)((uintptr_t)e.function >> 9)) + - hash * 37; - + return hash; } static bool isEqual(const Expression &LHS, const Expression &RHS) { @@ -215,185 +157,27 @@ // ValueTable Internal Functions //===----------------------------------------------------------------------===// -Expression::ExpressionOpcode ValueTable::getOpcode(CmpInst* C) { - if (isa(C)) { - switch (C->getPredicate()) { - default: // THIS SHOULD NEVER HAPPEN - llvm_unreachable("Comparison with unknown predicate?"); - case ICmpInst::ICMP_EQ: return Expression::ICMPEQ; - case ICmpInst::ICMP_NE: return Expression::ICMPNE; - case ICmpInst::ICMP_UGT: return Expression::ICMPUGT; - case ICmpInst::ICMP_UGE: return Expression::ICMPUGE; - case ICmpInst::ICMP_ULT: return Expression::ICMPULT; - case ICmpInst::ICMP_ULE: return Expression::ICMPULE; - case ICmpInst::ICMP_SGT: return Expression::ICMPSGT; - case ICmpInst::ICMP_SGE: return Expression::ICMPSGE; - case ICmpInst::ICMP_SLT: return Expression::ICMPSLT; - case ICmpInst::ICMP_SLE: return Expression::ICMPSLE; - } - } else { - switch (C->getPredicate()) { - default: // THIS SHOULD NEVER HAPPEN - llvm_unreachable("Comparison with unknown predicate?"); - case FCmpInst::FCMP_OEQ: return Expression::FCMPOEQ; - case FCmpInst::FCMP_OGT: return Expression::FCMPOGT; - case FCmpInst::FCMP_OGE: return Expression::FCMPOGE; - case FCmpInst::FCMP_OLT: return Expression::FCMPOLT; - case FCmpInst::FCMP_OLE: return Expression::FCMPOLE; - case FCmpInst::FCMP_ONE: return Expression::FCMPONE; - case FCmpInst::FCMP_ORD: return Expression::FCMPORD; - case FCmpInst::FCMP_UNO: return Expression::FCMPUNO; - case FCmpInst::FCMP_UEQ: return Expression::FCMPUEQ; - case FCmpInst::FCMP_UGT: return Expression::FCMPUGT; - case FCmpInst::FCMP_UGE: return Expression::FCMPUGE; - case FCmpInst::FCMP_ULT: return Expression::FCMPULT; - case FCmpInst::FCMP_ULE: return Expression::FCMPULE; - case FCmpInst::FCMP_UNE: return Expression::FCMPUNE; - } - } -} - -Expression ValueTable::create_expression(CallInst* C) { - Expression e; - - e.type = C->getType(); - e.function = C->getCalledFunction(); - e.opcode = Expression::CALL; - - CallSite CS(C); - for (CallInst::op_iterator I = CS.arg_begin(), E = CS.arg_end(); - I != E; ++I) - e.varargs.push_back(lookup_or_add(*I)); - - return e; -} - -Expression ValueTable::create_expression(BinaryOperator* BO) { - Expression e; - e.varargs.push_back(lookup_or_add(BO->getOperand(0))); - e.varargs.push_back(lookup_or_add(BO->getOperand(1))); - e.function = 0; - e.type = BO->getType(); - e.opcode = static_cast(BO->getOpcode()); - - return e; -} - -Expression ValueTable::create_expression(CmpInst* C) { - Expression e; - - e.varargs.push_back(lookup_or_add(C->getOperand(0))); - e.varargs.push_back(lookup_or_add(C->getOperand(1))); - e.function = 0; - e.type = C->getType(); - e.opcode = getOpcode(C); - return e; -} - -Expression ValueTable::create_expression(CastInst* C) { +Expression ValueTable::create_expression(Instruction *I) { Expression e; - - e.varargs.push_back(lookup_or_add(C->getOperand(0))); - e.function = 0; - e.type = C->getType(); - e.opcode = static_cast(C->getOpcode()); - - return e; -} - -Expression ValueTable::create_expression(ShuffleVectorInst* S) { - Expression e; - - e.varargs.push_back(lookup_or_add(S->getOperand(0))); - e.varargs.push_back(lookup_or_add(S->getOperand(1))); - e.varargs.push_back(lookup_or_add(S->getOperand(2))); - e.function = 0; - e.type = S->getType(); - e.opcode = Expression::SHUFFLE; - - return e; -} - -Expression ValueTable::create_expression(ExtractElementInst* E) { - Expression e; - - e.varargs.push_back(lookup_or_add(E->getOperand(0))); - e.varargs.push_back(lookup_or_add(E->getOperand(1))); - e.function = 0; - e.type = E->getType(); - e.opcode = Expression::EXTRACT; - - return e; -} - -Expression ValueTable::create_expression(InsertElementInst* I) { - Expression e; - - e.varargs.push_back(lookup_or_add(I->getOperand(0))); - e.varargs.push_back(lookup_or_add(I->getOperand(1))); - e.varargs.push_back(lookup_or_add(I->getOperand(2))); - e.function = 0; e.type = I->getType(); - e.opcode = Expression::INSERT; - - return e; -} - -Expression ValueTable::create_expression(SelectInst* I) { - Expression e; - - e.varargs.push_back(lookup_or_add(I->getCondition())); - e.varargs.push_back(lookup_or_add(I->getTrueValue())); - e.varargs.push_back(lookup_or_add(I->getFalseValue())); - e.function = 0; - e.type = I->getType(); - e.opcode = Expression::SELECT; - - return e; -} - -Expression ValueTable::create_expression(GetElementPtrInst* G) { - Expression e; - - e.varargs.push_back(lookup_or_add(G->getPointerOperand())); - e.function = 0; - e.type = G->getType(); - e.opcode = Expression::GEP; - - for (GetElementPtrInst::op_iterator I = G->idx_begin(), E = G->idx_end(); - I != E; ++I) - e.varargs.push_back(lookup_or_add(*I)); - - return e; -} - -Expression ValueTable::create_expression(ExtractValueInst* E) { - Expression e; - - e.varargs.push_back(lookup_or_add(E->getAggregateOperand())); - for (ExtractValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end(); - II != IE; ++II) - e.varargs.push_back(*II); - e.function = 0; - e.type = E->getType(); - e.opcode = Expression::EXTRACTVALUE; - - return e; -} - -Expression ValueTable::create_expression(InsertValueInst* E) { - Expression e; - - e.varargs.push_back(lookup_or_add(E->getAggregateOperand())); - e.varargs.push_back(lookup_or_add(E->getInsertedValueOperand())); - for (InsertValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end(); - II != IE; ++II) - e.varargs.push_back(*II); - e.function = 0; - e.type = E->getType(); - e.opcode = Expression::INSERTVALUE; - + e.opcode = I->getOpcode(); + for (Instruction::op_iterator OI = I->op_begin(), OE = I->op_end(); + OI != OE; ++OI) + e.varargs.push_back(lookup_or_add(*OI)); + + if (CmpInst *C = dyn_cast(I)) + e.opcode = (C->getOpcode() << 8) | C->getPredicate(); + else if (ExtractValueInst *E = dyn_cast(I)) { + for (ExtractValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end(); + II != IE; ++II) + e.varargs.push_back(*II); + } else if (InsertValueInst *E = dyn_cast(I)) { + for (InsertValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end(); + II != IE; ++II) + e.varargs.push_back(*II); + } + return e; } @@ -552,12 +336,8 @@ case Instruction::And: case Instruction::Or : case Instruction::Xor: - exp = create_expression(cast(I)); - break; case Instruction::ICmp: case Instruction::FCmp: - exp = create_expression(cast(I)); - break; case Instruction::Trunc: case Instruction::ZExt: case Instruction::SExt: @@ -570,28 +350,14 @@ case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: - exp = create_expression(cast(I)); - break; case Instruction::Select: - exp = create_expression(cast(I)); - break; case Instruction::ExtractElement: - exp = create_expression(cast(I)); - break; case Instruction::InsertElement: - exp = create_expression(cast(I)); - break; case Instruction::ShuffleVector: - exp = create_expression(cast(I)); - break; case Instruction::ExtractValue: - exp = create_expression(cast(I)); - break; case Instruction::InsertValue: - exp = create_expression(cast(I)); - break; case Instruction::GetElementPtr: - exp = create_expression(cast(I)); + exp = create_expression(I); break; default: valueNumbering[V] = nextValueNumber; From ofv at wanadoo.es Mon Jan 3 14:01:32 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Mon, 03 Jan 2011 20:01:32 -0000 Subject: [llvm-commits] [llvm] r122768 - /llvm/trunk/cmake/modules/TableGen.cmake Message-ID: <20110103200132.47FD12A6C12C@llvm.org> Author: ofv Date: Mon Jan 3 14:01:32 2011 New Revision: 122768 URL: http://llvm.org/viewvc/llvm-project?rev=122768&view=rev Log: TableGen.cmake: sometimes the .td file is not in the current directory (clang/include/clang/Basic/StmtNodes.td, for instance, is tablegenned from clang/include/clang/AST/CMakeLists.txt) so it is not contained on the list of all .td files on the current source directory which is used as the DEPENDS of the custom command. We must add the .td file to the DEPENDS list of the custom command. Otherwise some .inc files are not regenerated when the corresponding .td file changes. Modified: llvm/trunk/cmake/modules/TableGen.cmake Modified: llvm/trunk/cmake/modules/TableGen.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/TableGen.cmake?rev=122768&r1=122767&r2=122768&view=diff ============================================================================== --- llvm/trunk/cmake/modules/TableGen.cmake (original) +++ llvm/trunk/cmake/modules/TableGen.cmake Mon Jan 3 14:01:32 2011 @@ -18,7 +18,10 @@ -I ${LLVM_MAIN_SRC_DIR}/lib/Target -I ${LLVM_MAIN_INCLUDE_DIR} ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} -o ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp - DEPENDS tblgen ${local_tds} ${global_tds} + # The file in LLVM_TARGET_DEFINITIONS may be not in the current + # directory and local_tds may not contain it, so we must + # explicitly list it here: + DEPENDS tblgen ${local_tds} ${global_tds} ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} COMMENT "Building ${ofn}..." ) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn} From sabre at nondot.org Mon Jan 3 15:01:26 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 21:01:26 -0000 Subject: [llvm-commits] [llvm] r122771 - /llvm/trunk/test/Analysis/BasicAA/global-size.ll Message-ID: <20110103210126.B60E82A6C12C@llvm.org> Author: lattner Date: Mon Jan 3 15:01:26 2011 New Revision: 122771 URL: http://llvm.org/viewvc/llvm-project?rev=122771&view=rev Log: filecheckize Modified: llvm/trunk/test/Analysis/BasicAA/global-size.ll Modified: llvm/trunk/test/Analysis/BasicAA/global-size.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/global-size.ll?rev=122771&r1=122770&r2=122771&view=diff ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/global-size.ll (original) +++ llvm/trunk/test/Analysis/BasicAA/global-size.ll Mon Jan 3 15:01:26 2011 @@ -1,16 +1,18 @@ ; A store or load cannot alias a global if the accessed amount is larger then ; the global. -; RUN: opt < %s -basicaa -gvn -instcombine -S | not grep load +; RUN: opt < %s -basicaa -gvn -S | FileCheck %s target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" - at B = global i16 8 ; [#uses=2] + at B = global i16 8 -define i16 @test(i32* %P) { - %X = load i16* @B ; [#uses=1] +; CHECK: @test1 +define i16 @test1(i32* %P) { + %X = load i16* @B store i32 7, i32* %P - %Y = load i16* @B ; [#uses=1] - %Z = sub i16 %Y, %X ; [#uses=1] + %Y = load i16* @B + %Z = sub i16 %Y, %X ret i16 %Z +; CHECK: ret i16 0 } From sabre at nondot.org Mon Jan 3 15:03:33 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 21:03:33 -0000 Subject: [llvm-commits] [llvm] r122772 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Analysis/BasicAA/global-size.ll Message-ID: <20110103210333.507FA2A6C12C@llvm.org> Author: lattner Date: Mon Jan 3 15:03:33 2011 New Revision: 122772 URL: http://llvm.org/viewvc/llvm-project?rev=122772&view=rev Log: fix rdar://8813415 - a miscompilation of 164.gzip that loop-idiom exposed. It turns out to be a latent bug in basicaa, scary. Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp llvm/trunk/test/Analysis/BasicAA/global-size.ll Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=122772&r1=122771&r2=122772&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Mon Jan 3 15:03:33 2011 @@ -103,6 +103,8 @@ const TargetData &TD) { const Type *AccessTy; if (const GlobalVariable *GV = dyn_cast(V)) { + if (!GV->hasDefinitiveInitializer()) + return false; AccessTy = GV->getType()->getElementType(); } else if (const AllocaInst *AI = dyn_cast(V)) { if (!AI->isArrayAllocation()) Modified: llvm/trunk/test/Analysis/BasicAA/global-size.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/global-size.ll?rev=122772&r1=122771&r2=122772&view=diff ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/global-size.ll (original) +++ llvm/trunk/test/Analysis/BasicAA/global-size.ll Mon Jan 3 15:03:33 2011 @@ -16,3 +16,25 @@ ; CHECK: ret i16 0 } +; Cannot know anything about the size of this global. +; rdar://8813415 + at window = external global [0 x i8] + +; CHECK: @test2 +define i8 @test2(i32 %tmp79, i32 %w.2, i32 %indvar89) nounwind { + %tmp92 = add i32 %tmp79, %indvar89 + %arrayidx412 = getelementptr [0 x i8]* @window, i32 0, i32 %tmp92 + %tmp93 = add i32 %w.2, %indvar89 + %arrayidx416 = getelementptr [0 x i8]* @window, i32 0, i32 %tmp93 + + %A = load i8* %arrayidx412, align 1 + store i8 4, i8* %arrayidx416, align 1 + + %B = load i8* %arrayidx412, align 1 + %C = sub i8 %A, %B + ret i8 %C + +; CHECK: %B = load i8 +; CHECK: ret i8 %C +} + From resistor at mac.com Mon Jan 3 15:08:22 2011 From: resistor at mac.com (Owen Anderson) Date: Mon, 03 Jan 2011 21:08:22 -0000 Subject: [llvm-commits] [llvm] r122773 - /llvm/trunk/docs/AliasAnalysis.html Message-ID: <20110103210822.D1C622A6C12C@llvm.org> Author: resistor Date: Mon Jan 3 15:08:22 2011 New Revision: 122773 URL: http://llvm.org/viewvc/llvm-project?rev=122773&view=rev Log: We can count properly. Modified: llvm/trunk/docs/AliasAnalysis.html Modified: llvm/trunk/docs/AliasAnalysis.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/AliasAnalysis.html?rev=122773&r1=122772&r2=122773&view=diff ============================================================================== --- llvm/trunk/docs/AliasAnalysis.html (original) +++ llvm/trunk/docs/AliasAnalysis.html Mon Jan 3 15:08:22 2011 @@ -464,7 +464,7 @@

    -The AliasAnalysis interface exposes two methods which are used to +The AliasAnalysis interface exposes three methods which are used to communicate program changes from the clients to the analysis implementations. Various alias analysis implementations should use these methods to ensure that their internal data structures are kept up-to-date as the program changes (for From daniel at zuster.org Mon Jan 3 15:34:58 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 03 Jan 2011 21:34:58 -0000 Subject: [llvm-commits] [test-suite] r122775 - /test-suite/trunk/SingleSource/UnitTests/Vector/Makefile Message-ID: <20110103213458.EB91E2A6C12C@llvm.org> Author: ddunbar Date: Mon Jan 3 15:34:58 2011 New Revision: 122775 URL: http://llvm.org/viewvc/llvm-project?rev=122775&view=rev Log: Only run NEON tests on thumbv7. Modified: test-suite/trunk/SingleSource/UnitTests/Vector/Makefile Modified: test-suite/trunk/SingleSource/UnitTests/Vector/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/Vector/Makefile?rev=122775&r1=122774&r2=122775&view=diff ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/Vector/Makefile (original) +++ test-suite/trunk/SingleSource/UnitTests/Vector/Makefile Mon Jan 3 15:34:58 2011 @@ -17,7 +17,7 @@ endif # Assume ARMv7 implies NEON. -ifneq ($(CC_UNDER_TEST_TARGET_IS_ARMV7)$(CC_UNDER_TEST_TARGET_IS_THUMBV7),) +ifneq ($(CC_UNDER_TEST_TARGET_IS_THUMBV7),) DIRS += NEON endif From resistor at mac.com Mon Jan 3 15:38:41 2011 From: resistor at mac.com (Owen Anderson) Date: Mon, 03 Jan 2011 21:38:41 -0000 Subject: [llvm-commits] [llvm] r122777 - in /llvm/trunk: docs/AliasAnalysis.html include/llvm/Analysis/AliasAnalysis.h lib/Analysis/AliasAnalysis.cpp Message-ID: <20110103213842.024E32A6C12C@llvm.org> Author: resistor Date: Mon Jan 3 15:38:41 2011 New Revision: 122777 URL: http://llvm.org/viewvc/llvm-project?rev=122777&view=rev Log: Stub out a new updating interface to AliasAnalysis, allowing stateful analyses to be informed when a pointer value has potentially become escaping. Implementations can choose to either fall back to conservative responses for that value, or may recompute their analysis to accomodate the change. Modified: llvm/trunk/docs/AliasAnalysis.html llvm/trunk/include/llvm/Analysis/AliasAnalysis.h llvm/trunk/lib/Analysis/AliasAnalysis.cpp Modified: llvm/trunk/docs/AliasAnalysis.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/AliasAnalysis.html?rev=122777&r1=122776&r2=122777&view=diff ============================================================================== --- llvm/trunk/docs/AliasAnalysis.html (original) +++ llvm/trunk/docs/AliasAnalysis.html Mon Jan 3 15:38:41 2011 @@ -464,7 +464,7 @@

    -The AliasAnalysis interface exposes three methods which are used to +The AliasAnalysis interface exposes four methods which are used to communicate program changes from the clients to the analysis implementations. Various alias analysis implementations should use these methods to ensure that their internal data structures are kept up-to-date as the program changes (for @@ -505,6 +505,28 @@ analysis implementations. + +

    The addEscapingUse method
    + +
    +

    The addEscapingUse method is used when the uses of a pointer +value have changed in ways that may invalidate precomputed analysis information. +Implementations may either use this callback to provide conservative responses +for points whose uses have change since analysis time, or may recompute some +or all of their internal state to continue providing accurate responses.

    + +

    In general, any new use of a pointer value is considered an escaping use, +and must be reported through this callback, except for the +uses below:

    + +
      +
    • A bitcast or getelementptr of the pointer
    • +
    • A store through the pointer (but not a store + of the pointer)
    • +
    • A load through the pointer
    • +
    +
    +
    Efficiency Issues Modified: llvm/trunk/include/llvm/Analysis/AliasAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasAnalysis.h?rev=122777&r1=122776&r2=122777&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/AliasAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/AliasAnalysis.h Mon Jan 3 15:38:41 2011 @@ -469,6 +469,17 @@ /// virtual void copyValue(Value *From, Value *To); + /// addEscapingUse - This method should be used whenever an escaping use is + /// added to a pointer value. Analysis implementations may either return + /// conservative responses for that value in the future, or may recompute + /// some or all internal state to continue providing precise responses. + /// + /// Escaping uses are considered by anything _except_ the following: + /// - GEPs or bitcasts of the pointer + /// - Loads through the pointer + /// - Stores through (but not of) the pointer + virtual void addEscapingUse(Use &U); + /// replaceWithNewValue - This method is the obvious combination of the two /// above, and it provided as a helper to simplify client code. /// Modified: llvm/trunk/lib/Analysis/AliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasAnalysis.cpp?rev=122777&r1=122776&r2=122777&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/AliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/AliasAnalysis.cpp Mon Jan 3 15:38:41 2011 @@ -65,6 +65,12 @@ AA->copyValue(From, To); } +void AliasAnalysis::addEscapingUse(Use &U) { + assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); + AA->addEscapingUse(U); +} + + AliasAnalysis::ModRefResult AliasAnalysis::getModRefInfo(ImmutableCallSite CS, const Location &Loc) { From peckw at wesleypeck.com Mon Jan 3 15:40:26 2011 From: peckw at wesleypeck.com (Wesley Peck) Date: Mon, 03 Jan 2011 21:40:26 -0000 Subject: [llvm-commits] [llvm] r122778 - in /llvm/trunk/lib/Target/MBlaze: MBlazeFrameInfo.cpp MBlazeMachineFunction.h MBlazeRegisterInfo.cpp Message-ID: <20110103214026.E04052A6C12C@llvm.org> Author: peckw Date: Mon Jan 3 15:40:26 2011 New Revision: 122778 URL: http://llvm.org/viewvc/llvm-project?rev=122778&view=rev Log: Fix more stack layout issues in the MBlaze backend. Modified: llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp llvm/trunk/lib/Target/MBlaze/MBlazeMachineFunction.h llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp Modified: llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp?rev=122778&r1=122777&r2=122778&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp Mon Jan 3 15:40:26 2011 @@ -40,6 +40,35 @@ cl::Hidden); } +static void replaceFrameIndexes(MachineFunction &MF, + SmallVector, 16> &FR) { + MachineFrameInfo *MFI = MF.getFrameInfo(); + const SmallVector, 16>::iterator FRB = FR.begin(); + const SmallVector, 16>::iterator FRE = FR.end(); + + SmallVector, 16>::iterator FRI = FRB; + for (; FRI != FRE; ++FRI) { + MFI->RemoveStackObject(FRI->first); + int NFI = MFI->CreateFixedObject(4, FRI->second, true); + + for (MachineFunction::iterator MB=MF.begin(), ME=MF.end(); MB!=ME; ++MB) { + MachineBasicBlock::iterator MBB = MB->begin(); + const MachineBasicBlock::iterator MBE = MB->end(); + + for (; MBB != MBE; ++MBB) { + MachineInstr::mop_iterator MIB = MBB->operands_begin(); + const MachineInstr::mop_iterator MIE = MBB->operands_end(); + + for (MachineInstr::mop_iterator MII = MIB; MII != MIE; ++MII) { + if (!MII->isFI() || MII->getIndex() != FRI->first) continue; + DEBUG(dbgs() << "FOUND FI#" << MII->getIndex() << "\n"); + MII->setIndex(NFI); + } + } + } + } +} + //===----------------------------------------------------------------------===// // // Stack Frame Processing methods @@ -64,6 +93,7 @@ MachineRegisterInfo::livein_iterator LIE = MRI.livein_end(); const SmallVector &LiveInFI = MBlazeFI->getLiveIn(); SmallVector EraseInstr; + SmallVector, 16> FrameRelocate; MachineBasicBlock *MBB = MF.getBlockNumbered(0); MachineBasicBlock::iterator MIB = MBB->begin(); @@ -87,7 +117,6 @@ // // Additionally, if the SWI operation kills the def of REG then we don't // need the LWI operation so we can erase it as well. -#if 1 for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) { for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) { if (I->getOpcode() != MBlaze::LWI || I->getNumOperands() != 3 || @@ -117,7 +146,7 @@ EraseInstr.push_back(SI); DEBUG(dbgs() << "SWI for FI#" << FI << " removed\n"); - MBlazeFI->recordLoadArgsFI(FI, StackOffset); + FrameRelocate.push_back(std::make_pair(FI,StackOffset)); DEBUG(dbgs() << "FI#" << FI << " relocated to " << StackOffset << "\n"); StackOffset -= 4; @@ -126,7 +155,6 @@ } } } -#endif // In this loop we are searching for frame indexes that corrospond to // incoming arguments that are in registers. We look for instruction @@ -139,7 +167,6 @@ // caller has allocated stack space for it already. Instead of allocating // stack space on our frame, we record the correct location in the callers // frame. -#if 1 for (MachineRegisterInfo::livein_iterator LI = LII; LI != LIE; ++LI) { for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) { if (I->definesRegister(LI->first)) @@ -165,21 +192,21 @@ } StackAdjust += 4; - MBlazeFI->recordLoadArgsFI(FI, FILoc); + FrameRelocate.push_back(std::make_pair(FI,FILoc)); DEBUG(dbgs() << "FI#" << FI << " relocated to " << FILoc << "\n"); break; } } } -#endif // Go ahead and erase all of the instructions that we determined were // no longer needed. for (int i = 0, e = EraseInstr.size(); i < e; ++i) MBB->erase(EraseInstr[i]); - DEBUG(dbgs() << "Final stack adjustment: " << StackAdjust << "\n"); - MBlazeFI->setStackAdjust(StackAdjust); + // Replace all of the frame indexes that we have relocated with new + // fixed object frame indexes. + replaceFrameIndexes(MF, FrameRelocate); } static void interruptFrameLayout(MachineFunction &MF) { @@ -282,9 +309,6 @@ unsigned FrameSize = MFI->getStackSize(); DEBUG(dbgs() << "Original Frame Size: " << FrameSize << "\n" ); - FrameSize -= MBlazeFI->getStackAdjust(); - DEBUG(dbgs() << "Adjusted Frame Size: " << FrameSize << "\n" ); - // Get the alignments provided by the target, and the maximum alignment // (if any) of the fixed frame objects. // unsigned MaxAlign = MFI->getMaxAlignment(); Modified: llvm/trunk/lib/Target/MBlaze/MBlazeMachineFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeMachineFunction.h?rev=122778&r1=122777&r2=122778&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeMachineFunction.h (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeMachineFunction.h Mon Jan 3 15:40:26 2011 @@ -34,9 +34,6 @@ /// saved. This is used on Prologue and Epilogue to emit RA save/restore int RAStackOffset; - /// Holds the stack adjustment necessary for each function. - int StackAdjust; - /// MBlazeFIHolder - Holds a FrameIndex and it's Stack Pointer Offset struct MBlazeFIHolder { @@ -85,9 +82,9 @@ public: MBlazeFunctionInfo(MachineFunction& MF) - : FPStackOffset(0), RAStackOffset(0), StackAdjust(0), GPHolder(-1,-1), - HasLoadArgs(false), HasStoreVarArgs(false), SRetReturnReg(0), - GlobalBaseReg(0), VarArgsFrameIndex(0), LiveInFI() + : FPStackOffset(0), RAStackOffset(0), GPHolder(-1,-1), HasLoadArgs(false), + HasStoreVarArgs(false), SRetReturnReg(0), GlobalBaseReg(0), + VarArgsFrameIndex(0), LiveInFI() {} int getFPStackOffset() const { return FPStackOffset; } @@ -96,9 +93,6 @@ int getRAStackOffset() const { return RAStackOffset; } void setRAStackOffset(int Off) { RAStackOffset = Off; } - int getStackAdjust() const { return StackAdjust; } - void setStackAdjust(int Adj) { StackAdjust = Adj; } - int getGPStackOffset() const { return GPHolder.SPOffset; } int getGPFI() const { return GPHolder.FI; } void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; } @@ -125,6 +119,7 @@ if (!HasLoadArgs) HasLoadArgs=true; FnLoadArgs.push_back(MBlazeFIHolder(FI, SPOffset)); } + void recordStoreVarArgsFI(int FI, int SPOffset) { if (!HasStoreVarArgs) HasStoreVarArgs=true; FnStoreVarArgs.push_back(MBlazeFIHolder(FI, SPOffset)); @@ -135,6 +130,7 @@ for (unsigned i = 0, e = FnLoadArgs.size(); i != e; ++i) MFI->setObjectOffset(FnLoadArgs[i].FI, FnLoadArgs[i].SPOffset); } + void adjustStoreVarArgsFI(MachineFrameInfo *MFI) const { if (!hasStoreVarArgs()) return; for (unsigned i = 0, e = FnStoreVarArgs.size(); i != e; ++i) Modified: llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp?rev=122778&r1=122777&r2=122778&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp Mon Jan 3 15:40:26 2011 @@ -296,11 +296,6 @@ // and adjust SPOffsets considering the final stack size. int Offset = (spOffset < 0) ? (stackSize - spOffset) : spOffset; Offset += MI.getOperand(oi).getImm(); - if (!MFI->isFixedObjectIndex(FrameIndex) && - !MFI->isSpillSlotObjectIndex(FrameIndex) && - !MBlazeFI->isLiveIn(FrameIndex) && - spOffset >= 0) - Offset -= MBlazeFI->getStackAdjust(); DEBUG(dbgs() << "Offset : " << Offset << "\n" << "<--------->\n"); From greened at obbligato.org Mon Jan 3 15:55:08 2011 From: greened at obbligato.org (David Greene) Date: Mon, 03 Jan 2011 21:55:08 -0000 Subject: [llvm-commits] [llvm] r122779 - /llvm/trunk/test/lit.cfg Message-ID: <20110103215508.2D61E2A6C12C@llvm.org> Author: greened Date: Mon Jan 3 15:55:08 2011 New Revision: 122779 URL: http://llvm.org/viewvc/llvm-project?rev=122779&view=rev Log: Don't pattern match "clang-" as it may be part of a tool name with a triple suffix. Modified: llvm/trunk/test/lit.cfg Modified: llvm/trunk/test/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=122779&r1=122778&r2=122779&view=diff ============================================================================== --- llvm/trunk/test/lit.cfg (original) +++ llvm/trunk/test/lit.cfg Mon Jan 3 15:55:08 2011 @@ -155,8 +155,8 @@ # tools that might happen to be in the user's PATH. Thus this list # includes every tool placed in $(LLVM_OBJ_ROOT)/$(BuildMode)/bin # (llvm_tools_dir in lit parlance). - # Don't match 'bugpoint-'. -for pattern in [r"\bbugpoint\b(?!-)", r"\bclang\b", + # Don't match 'bugpoint-' or 'clang-'. +for pattern in [r"\bbugpoint\b(?!-)", r"\bclang\b(?!-)", r"\bedis\b", r"\bgold\b", r"\bllc\b", r"\blli\b", r"\bllvm-ar\b", r"\bllvm-as\b", From evan.cheng at apple.com Mon Jan 3 16:53:22 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 03 Jan 2011 22:53:22 -0000 Subject: [llvm-commits] [llvm] r122783 - in /llvm/trunk: lib/Target/X86/X86FrameInfo.cpp lib/Target/X86/X86InstrControl.td test/CodeGen/X86/2009-09-10-SpillComments.ll test/CodeGen/X86/2010-07-02-asm-alignstack.ll test/CodeGen/X86/abi-isel.ll test/CodeGen/X86/licm-symbol.ll test/CodeGen/X86/tail-opts.ll test/CodeGen/X86/tailcall-largecode.ll test/CodeGen/X86/tlv-2.ll Message-ID: <20110103225323.065CF2A6C12C@llvm.org> Author: evancheng Date: Mon Jan 3 16:53:22 2011 New Revision: 122783 URL: http://llvm.org/viewvc/llvm-project?rev=122783&view=rev Log: Use pushq / popq instead of subq $8, %rsp / addq $8, %rsp to adjust stack in prologue and epilogue if the adjustment is 8. Similarly, use pushl / popl if the adjustment is 4 in 32-bit mode. In the epilogue, takes care to pop to a caller-saved register that's not live at the exit (either return or tailcall instruction). rdar://8771137 Modified: llvm/trunk/lib/Target/X86/X86FrameInfo.cpp llvm/trunk/lib/Target/X86/X86InstrControl.td llvm/trunk/test/CodeGen/X86/2009-09-10-SpillComments.ll llvm/trunk/test/CodeGen/X86/2010-07-02-asm-alignstack.ll llvm/trunk/test/CodeGen/X86/abi-isel.ll llvm/trunk/test/CodeGen/X86/licm-symbol.ll llvm/trunk/test/CodeGen/X86/tail-opts.ll llvm/trunk/test/CodeGen/X86/tailcall-largecode.ll llvm/trunk/test/CodeGen/X86/tlv-2.ll Modified: llvm/trunk/lib/Target/X86/X86FrameInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameInfo.cpp?rev=122783&r1=122782&r2=122783&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FrameInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FrameInfo.cpp Mon Jan 3 16:53:22 2011 @@ -25,6 +25,7 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CommandLine.h" +#include "llvm/ADT/SmallSet.h" using namespace llvm; @@ -75,12 +76,70 @@ } } +/// findDeadCallerSavedReg - Return a caller-saved register that isn't live +/// when it reaches the "return" instruction. We can then pop a stack object +/// to this register without worry about clobbering it. +static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator &MBBI, + const TargetRegisterInfo &TRI, + bool Is64Bit) { + const MachineFunction *MF = MBB.getParent(); + const Function *F = MF->getFunction(); + if (!F || MF->getMMI().callsEHReturn()) + return 0; + + static const unsigned CallerSavedRegs32Bit[] = { + X86::EAX, X86::EDX, X86::ECX + }; + + static const unsigned CallerSavedRegs64Bit[] = { + X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI, + X86::R8, X86::R9, X86::R10, X86::R11 + }; + + unsigned Opc = MBBI->getOpcode(); + switch (Opc) { + default: return 0; + case X86::RET: + case X86::RETI: + case X86::TCRETURNdi: + case X86::TCRETURNri: + case X86::TCRETURNmi: + case X86::TCRETURNdi64: + case X86::TCRETURNri64: + case X86::TCRETURNmi64: + case X86::EH_RETURN: + case X86::EH_RETURN64: { + SmallSet Uses; + for (unsigned i = 0, e = MBBI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MBBI->getOperand(i); + if (!MO.isReg() || MO.isDef()) + continue; + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + for (const unsigned *AsI = TRI.getOverlaps(Reg); *AsI; ++AsI) + Uses.insert(*AsI); + } + + const unsigned *CS = Is64Bit ? CallerSavedRegs64Bit : CallerSavedRegs32Bit; + for (; *CS; ++CS) + if (!Uses.count(*CS)) + return *CS; + } + } + + return 0; +} + + /// emitSPUpdate - Emit a series of instructions to increment / decrement the /// stack pointer by a constant value. static void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, - unsigned StackPtr, int64_t NumBytes, bool Is64Bit, - const TargetInstrInfo &TII) { + unsigned StackPtr, int64_t NumBytes, + bool Is64Bit, const TargetInstrInfo &TII, + const TargetRegisterInfo &TRI) { bool isSub = NumBytes < 0; uint64_t Offset = isSub ? -NumBytes : NumBytes; unsigned Opc = isSub ? @@ -91,10 +150,26 @@ while (Offset) { uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset; + if (ThisVal == (Is64Bit ? 8 : 4)) { + // Use push / pop instead. + unsigned Reg = isSub + ? (Is64Bit ? X86::RAX : X86::EAX) + : findDeadCallerSavedReg(MBB, MBBI, TRI, Is64Bit); + if (Reg) { + Opc = isSub + ? (Is64Bit ? X86::PUSH64r : X86::PUSH32r) + : (Is64Bit ? X86::POP64r : X86::POP32r); + BuildMI(MBB, MBBI, DL, TII.get(Opc)) + .addReg(Reg, getDefRegState(!isSub) | getUndefRegState(isSub)); + Offset -= ThisVal; + continue; + } + } + MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr) - .addReg(StackPtr) - .addImm(ThisVal); + .addReg(StackPtr) + .addImm(ThisVal); MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead. Offset -= ThisVal; } @@ -531,9 +606,11 @@ BuildMI(MBB, MBBI, DL, TII.get(X86::WINCALL64pcrel32)) .addExternalSymbol("__chkstk") .addReg(StackPtr, RegState::Define | RegState::Implicit); - emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, TII); + emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, + TII, *RegInfo); } else if (NumBytes) - emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, TII); + emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, + TII, *RegInfo); if ((NumBytes || PushedRegs) && needsFrameMoves) { // Mark end of stack pointer adjustment. @@ -651,7 +728,7 @@ // We cannot use LEA here, because stack pointer was realigned. We need to // deallocate local frame back. if (CSSize) { - emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII); + emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII, *RegInfo); MBBI = prior(LastCSPop); } @@ -672,7 +749,7 @@ } } else if (NumBytes) { // Adjust stack pointer back: ESP += numbytes. - emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII); + emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII, *RegInfo); } // We're returning from function via eh_return. @@ -707,7 +784,7 @@ if (Offset) { // Check for possible merge with preceeding ADD instruction. Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true); - emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, TII); + emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, TII, *RegInfo); } // Jump to label or value in register. @@ -751,7 +828,7 @@ // Check for possible merge with preceeding ADD instruction. delta += mergeSPUpdates(MBB, MBBI, StackPtr, true); - emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, TII); + emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, TII, *RegInfo); } } Modified: llvm/trunk/lib/Target/X86/X86InstrControl.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrControl.td?rev=122783&r1=122782&r2=122783&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrControl.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrControl.td Mon Jan 3 16:53:22 2011 @@ -26,7 +26,7 @@ [(X86retflag timm:$amt)]>; def RETIW : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops), "retw\t$amt", - [(X86retflag timm:$amt)]>, OpSize; + []>, OpSize; def LRETL : I <0xCB, RawFrm, (outs), (ins), "lretl", []>; def LRETQ : RI <0xCB, RawFrm, (outs), (ins), Modified: llvm/trunk/test/CodeGen/X86/2009-09-10-SpillComments.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-09-10-SpillComments.ll?rev=122783&r1=122782&r2=122783&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-09-10-SpillComments.ll (original) +++ llvm/trunk/test/CodeGen/X86/2009-09-10-SpillComments.ll Mon Jan 3 16:53:22 2011 @@ -2,9 +2,9 @@ ; This test shouldn't require spills. -; CHECK: subq $8, %rsp +; CHECK: pushq ; CHECK-NOT: $rsp -; CHECK: addq $8, %rsp +; CHECK: popq %struct..0anon = type { i32 } %struct.rtvec_def = type { i32, [1 x %struct..0anon] } Modified: llvm/trunk/test/CodeGen/X86/2010-07-02-asm-alignstack.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-07-02-asm-alignstack.ll?rev=122783&r1=122782&r2=122783&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-07-02-asm-alignstack.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-07-02-asm-alignstack.ll Mon Jan 3 16:53:22 2011 @@ -3,7 +3,7 @@ define void @foo() nounwind ssp { entry: ; CHECK: foo -; CHECK: subq $8, %rsp +; CHECK: pushq ; CHECK: int $3 call void asm sideeffect alignstack "# top of block", "~{dirflag},~{fpsr},~{flags},~{edi},~{esi},~{edx},~{ecx},~{eax}"() nounwind call void asm sideeffect alignstack ".file \22small.c\22", "~{dirflag},~{fpsr},~{flags}"() nounwind @@ -18,7 +18,7 @@ define void @bar() nounwind ssp { entry: ; CHECK: bar -; CHECK-NOT: subq $8, %rsp +; CHECK-NOT: pushq ; CHECK: int $3 call void asm sideeffect "# top of block", "~{dirflag},~{fpsr},~{flags},~{edi},~{esi},~{edx},~{ecx},~{eax}"() nounwind call void asm sideeffect ".file \22small.c\22", "~{dirflag},~{fpsr},~{flags}"() nounwind Modified: llvm/trunk/test/CodeGen/X86/abi-isel.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/abi-isel.ll?rev=122783&r1=122782&r2=122783&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/abi-isel.ll (original) +++ llvm/trunk/test/CodeGen/X86/abi-isel.ll Mon Jan 3 16:53:22 2011 @@ -1,16 +1,16 @@ -; RUN: llc < %s -asm-verbose=0 -mtriple=i686-unknown-linux-gnu -march=x86 -relocation-model=static -code-model=small -post-RA-scheduler=false | FileCheck %s -check-prefix=LINUX-32-STATIC -; RUN: llc < %s -asm-verbose=0 -mtriple=i686-unknown-linux-gnu -march=x86 -relocation-model=static -code-model=small -post-RA-scheduler=false | FileCheck %s -check-prefix=LINUX-32-PIC +; RUN: llc < %s -asm-verbose=0 -mtriple=i686-unknown-linux-gnu -march=x86 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=LINUX-32-STATIC +; RUN: llc < %s -asm-verbose=0 -mtriple=i686-unknown-linux-gnu -march=x86 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=LINUX-32-PIC -; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-unknown-linux-gnu -march=x86-64 -relocation-model=static -code-model=small -post-RA-scheduler=false | FileCheck %s -check-prefix=LINUX-64-STATIC -; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-unknown-linux-gnu -march=x86-64 -relocation-model=pic -code-model=small -post-RA-scheduler=false | FileCheck %s -check-prefix=LINUX-64-PIC +; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-unknown-linux-gnu -march=x86-64 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=LINUX-64-STATIC +; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-unknown-linux-gnu -march=x86-64 -relocation-model=pic -code-model=small | FileCheck %s -check-prefix=LINUX-64-PIC -; RUN: llc < %s -asm-verbose=0 -mtriple=i686-apple-darwin -march=x86 -relocation-model=static -code-model=small -post-RA-scheduler=false | FileCheck %s -check-prefix=DARWIN-32-STATIC -; RUN: llc < %s -asm-verbose=0 -mtriple=i686-apple-darwin -march=x86 -relocation-model=dynamic-no-pic -code-model=small -post-RA-scheduler=false | FileCheck %s -check-prefix=DARWIN-32-DYNAMIC -; RUN: llc < %s -asm-verbose=0 -mtriple=i686-apple-darwin -march=x86 -relocation-model=pic -code-model=small -post-RA-scheduler=false | FileCheck %s -check-prefix=DARWIN-32-PIC - -; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-apple-darwin -march=x86-64 -relocation-model=static -code-model=small -post-RA-scheduler=false | FileCheck %s -check-prefix=DARWIN-64-STATIC -; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-apple-darwin -march=x86-64 -relocation-model=dynamic-no-pic -code-model=small -post-RA-scheduler=false | FileCheck %s -check-prefix=DARWIN-64-DYNAMIC -; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-apple-darwin -march=x86-64 -relocation-model=pic -code-model=small -post-RA-scheduler=false | FileCheck %s -check-prefix=DARWIN-64-PIC +; RUN: llc < %s -asm-verbose=0 -mtriple=i686-apple-darwin -march=x86 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=DARWIN-32-STATIC +; RUN: llc < %s -asm-verbose=0 -mtriple=i686-apple-darwin -march=x86 -relocation-model=dynamic-no-pic -code-model=small | FileCheck %s -check-prefix=DARWIN-32-DYNAMIC +; RUN: llc < %s -asm-verbose=0 -mtriple=i686-apple-darwin -march=x86 -relocation-model=pic -code-model=small | FileCheck %s -check-prefix=DARWIN-32-PIC + +; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-apple-darwin -march=x86-64 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=DARWIN-64-STATIC +; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-apple-darwin -march=x86-64 -relocation-model=dynamic-no-pic -code-model=small | FileCheck %s -check-prefix=DARWIN-64-DYNAMIC +; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-apple-darwin -march=x86-64 -relocation-model=pic -code-model=small | FileCheck %s -check-prefix=DARWIN-64-PIC @src = external global [131072 x i32] @dst = external global [131072 x i32] @@ -8375,7 +8375,7 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: lcallee: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll x ; LINUX-32-STATIC-NEXT: calll x ; LINUX-32-STATIC-NEXT: calll x @@ -8383,11 +8383,11 @@ ; LINUX-32-STATIC-NEXT: calll x ; LINUX-32-STATIC-NEXT: calll x ; LINUX-32-STATIC-NEXT: calll x -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: lcallee: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll x ; LINUX-32-PIC-NEXT: calll x ; LINUX-32-PIC-NEXT: calll x @@ -8395,11 +8395,11 @@ ; LINUX-32-PIC-NEXT: calll x ; LINUX-32-PIC-NEXT: calll x ; LINUX-32-PIC-NEXT: calll x -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: lcallee: -; LINUX-64-PIC: subq $8, %rsp +; LINUX-64-PIC: pushq ; LINUX-64-PIC-NEXT: callq x at PLT ; LINUX-64-PIC-NEXT: callq x at PLT ; LINUX-64-PIC-NEXT: callq x at PLT @@ -8407,7 +8407,7 @@ ; LINUX-64-PIC-NEXT: callq x at PLT ; LINUX-64-PIC-NEXT: callq x at PLT ; LINUX-64-PIC-NEXT: callq x at PLT -; LINUX-64-PIC-NEXT: addq $8, %rsp +; LINUX-64-PIC-NEXT: popq ; LINUX-64-PIC-NEXT: ret ; DARWIN-32-STATIC: _lcallee: @@ -8447,7 +8447,7 @@ ; DARWIN-32-PIC-NEXT: ret ; DARWIN-64-STATIC: _lcallee: -; DARWIN-64-STATIC: subq $8, %rsp +; DARWIN-64-STATIC: pushq ; DARWIN-64-STATIC-NEXT: callq _x ; DARWIN-64-STATIC-NEXT: callq _x ; DARWIN-64-STATIC-NEXT: callq _x @@ -8455,11 +8455,11 @@ ; DARWIN-64-STATIC-NEXT: callq _x ; DARWIN-64-STATIC-NEXT: callq _x ; DARWIN-64-STATIC-NEXT: callq _x -; DARWIN-64-STATIC-NEXT: addq $8, %rsp +; DARWIN-64-STATIC-NEXT: popq ; DARWIN-64-STATIC-NEXT: ret ; DARWIN-64-DYNAMIC: _lcallee: -; DARWIN-64-DYNAMIC: subq $8, %rsp +; DARWIN-64-DYNAMIC: pushq ; DARWIN-64-DYNAMIC-NEXT: callq _x ; DARWIN-64-DYNAMIC-NEXT: callq _x ; DARWIN-64-DYNAMIC-NEXT: callq _x @@ -8467,11 +8467,11 @@ ; DARWIN-64-DYNAMIC-NEXT: callq _x ; DARWIN-64-DYNAMIC-NEXT: callq _x ; DARWIN-64-DYNAMIC-NEXT: callq _x -; DARWIN-64-DYNAMIC-NEXT: addq $8, %rsp +; DARWIN-64-DYNAMIC-NEXT: popq ; DARWIN-64-DYNAMIC-NEXT: ret ; DARWIN-64-PIC: _lcallee: -; DARWIN-64-PIC: subq $8, %rsp +; DARWIN-64-PIC: pushq ; DARWIN-64-PIC-NEXT: callq _x ; DARWIN-64-PIC-NEXT: callq _x ; DARWIN-64-PIC-NEXT: callq _x @@ -8479,7 +8479,7 @@ ; DARWIN-64-PIC-NEXT: callq _x ; DARWIN-64-PIC-NEXT: callq _x ; DARWIN-64-PIC-NEXT: callq _x -; DARWIN-64-PIC-NEXT: addq $8, %rsp +; DARWIN-64-PIC-NEXT: popq ; DARWIN-64-PIC-NEXT: ret } @@ -8506,7 +8506,7 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: dcallee: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll y ; LINUX-32-STATIC-NEXT: calll y ; LINUX-32-STATIC-NEXT: calll y @@ -8514,11 +8514,11 @@ ; LINUX-32-STATIC-NEXT: calll y ; LINUX-32-STATIC-NEXT: calll y ; LINUX-32-STATIC-NEXT: calll y -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: dcallee: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll y ; LINUX-32-PIC-NEXT: calll y ; LINUX-32-PIC-NEXT: calll y @@ -8526,11 +8526,11 @@ ; LINUX-32-PIC-NEXT: calll y ; LINUX-32-PIC-NEXT: calll y ; LINUX-32-PIC-NEXT: calll y -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: dcallee: -; LINUX-64-PIC: subq $8, %rsp +; LINUX-64-PIC: pushq ; LINUX-64-PIC-NEXT: callq y at PLT ; LINUX-64-PIC-NEXT: callq y at PLT ; LINUX-64-PIC-NEXT: callq y at PLT @@ -8538,7 +8538,7 @@ ; LINUX-64-PIC-NEXT: callq y at PLT ; LINUX-64-PIC-NEXT: callq y at PLT ; LINUX-64-PIC-NEXT: callq y at PLT -; LINUX-64-PIC-NEXT: addq $8, %rsp +; LINUX-64-PIC-NEXT: popq ; LINUX-64-PIC-NEXT: ret ; DARWIN-32-STATIC: _dcallee: @@ -8578,7 +8578,7 @@ ; DARWIN-32-PIC-NEXT: ret ; DARWIN-64-STATIC: _dcallee: -; DARWIN-64-STATIC: subq $8, %rsp +; DARWIN-64-STATIC: pushq ; DARWIN-64-STATIC-NEXT: callq _y ; DARWIN-64-STATIC-NEXT: callq _y ; DARWIN-64-STATIC-NEXT: callq _y @@ -8586,11 +8586,11 @@ ; DARWIN-64-STATIC-NEXT: callq _y ; DARWIN-64-STATIC-NEXT: callq _y ; DARWIN-64-STATIC-NEXT: callq _y -; DARWIN-64-STATIC-NEXT: addq $8, %rsp +; DARWIN-64-STATIC-NEXT: popq ; DARWIN-64-STATIC-NEXT: ret ; DARWIN-64-DYNAMIC: _dcallee: -; DARWIN-64-DYNAMIC: subq $8, %rsp +; DARWIN-64-DYNAMIC: pushq ; DARWIN-64-DYNAMIC-NEXT: callq _y ; DARWIN-64-DYNAMIC-NEXT: callq _y ; DARWIN-64-DYNAMIC-NEXT: callq _y @@ -8598,11 +8598,11 @@ ; DARWIN-64-DYNAMIC-NEXT: callq _y ; DARWIN-64-DYNAMIC-NEXT: callq _y ; DARWIN-64-DYNAMIC-NEXT: callq _y -; DARWIN-64-DYNAMIC-NEXT: addq $8, %rsp +; DARWIN-64-DYNAMIC-NEXT: popq ; DARWIN-64-DYNAMIC-NEXT: ret ; DARWIN-64-PIC: _dcallee: -; DARWIN-64-PIC: subq $8, %rsp +; DARWIN-64-PIC: pushq ; DARWIN-64-PIC-NEXT: callq _y ; DARWIN-64-PIC-NEXT: callq _y ; DARWIN-64-PIC-NEXT: callq _y @@ -8610,7 +8610,7 @@ ; DARWIN-64-PIC-NEXT: callq _y ; DARWIN-64-PIC-NEXT: callq _y ; DARWIN-64-PIC-NEXT: callq _y -; DARWIN-64-PIC-NEXT: addq $8, %rsp +; DARWIN-64-PIC-NEXT: popq ; DARWIN-64-PIC-NEXT: ret } @@ -8770,24 +8770,24 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: caller: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll callee ; LINUX-32-STATIC-NEXT: calll callee -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: caller: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll callee ; LINUX-32-PIC-NEXT: calll callee -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: caller: -; LINUX-64-PIC: subq $8, %rsp +; LINUX-64-PIC: pushq ; LINUX-64-PIC-NEXT: callq callee at PLT ; LINUX-64-PIC-NEXT: callq callee at PLT -; LINUX-64-PIC-NEXT: addq $8, %rsp +; LINUX-64-PIC-NEXT: popq ; LINUX-64-PIC-NEXT: ret ; DARWIN-32-STATIC: _caller: @@ -8812,24 +8812,24 @@ ; DARWIN-32-PIC-NEXT: ret ; DARWIN-64-STATIC: _caller: -; DARWIN-64-STATIC: subq $8, %rsp +; DARWIN-64-STATIC: pushq ; DARWIN-64-STATIC-NEXT: callq _callee ; DARWIN-64-STATIC-NEXT: callq _callee -; DARWIN-64-STATIC-NEXT: addq $8, %rsp +; DARWIN-64-STATIC-NEXT: popq ; DARWIN-64-STATIC-NEXT: ret ; DARWIN-64-DYNAMIC: _caller: -; DARWIN-64-DYNAMIC: subq $8, %rsp +; DARWIN-64-DYNAMIC: pushq ; DARWIN-64-DYNAMIC-NEXT: callq _callee ; DARWIN-64-DYNAMIC-NEXT: callq _callee -; DARWIN-64-DYNAMIC-NEXT: addq $8, %rsp +; DARWIN-64-DYNAMIC-NEXT: popq ; DARWIN-64-DYNAMIC-NEXT: ret ; DARWIN-64-PIC: _caller: -; DARWIN-64-PIC: subq $8, %rsp +; DARWIN-64-PIC: pushq ; DARWIN-64-PIC-NEXT: callq _callee ; DARWIN-64-PIC-NEXT: callq _callee -; DARWIN-64-PIC-NEXT: addq $8, %rsp +; DARWIN-64-PIC-NEXT: popq ; DARWIN-64-PIC-NEXT: ret } @@ -8844,24 +8844,24 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: dcaller: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll dcallee ; LINUX-32-STATIC-NEXT: calll dcallee -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: dcaller: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll dcallee ; LINUX-32-PIC-NEXT: calll dcallee -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: dcaller: -; LINUX-64-PIC: subq $8, %rsp +; LINUX-64-PIC: pushq ; LINUX-64-PIC-NEXT: callq dcallee ; LINUX-64-PIC-NEXT: callq dcallee -; LINUX-64-PIC-NEXT: addq $8, %rsp +; LINUX-64-PIC-NEXT: popq ; LINUX-64-PIC-NEXT: ret ; DARWIN-32-STATIC: _dcaller: @@ -8886,24 +8886,24 @@ ; DARWIN-32-PIC-NEXT: ret ; DARWIN-64-STATIC: _dcaller: -; DARWIN-64-STATIC: subq $8, %rsp +; DARWIN-64-STATIC: pushq ; DARWIN-64-STATIC-NEXT: callq _dcallee ; DARWIN-64-STATIC-NEXT: callq _dcallee -; DARWIN-64-STATIC-NEXT: addq $8, %rsp +; DARWIN-64-STATIC-NEXT: popq ; DARWIN-64-STATIC-NEXT: ret ; DARWIN-64-DYNAMIC: _dcaller: -; DARWIN-64-DYNAMIC: subq $8, %rsp +; DARWIN-64-DYNAMIC: pushq ; DARWIN-64-DYNAMIC-NEXT: callq _dcallee ; DARWIN-64-DYNAMIC-NEXT: callq _dcallee -; DARWIN-64-DYNAMIC-NEXT: addq $8, %rsp +; DARWIN-64-DYNAMIC-NEXT: popq ; DARWIN-64-DYNAMIC-NEXT: ret ; DARWIN-64-PIC: _dcaller: -; DARWIN-64-PIC: subq $8, %rsp +; DARWIN-64-PIC: pushq ; DARWIN-64-PIC-NEXT: callq _dcallee ; DARWIN-64-PIC-NEXT: callq _dcallee -; DARWIN-64-PIC-NEXT: addq $8, %rsp +; DARWIN-64-PIC-NEXT: popq ; DARWIN-64-PIC-NEXT: ret } @@ -8918,24 +8918,24 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: lcaller: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll lcallee ; LINUX-32-STATIC-NEXT: calll lcallee -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: lcaller: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll lcallee ; LINUX-32-PIC-NEXT: calll lcallee -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: lcaller: -; LINUX-64-PIC: subq $8, %rsp +; LINUX-64-PIC: pushq ; LINUX-64-PIC-NEXT: callq lcallee at PLT ; LINUX-64-PIC-NEXT: callq lcallee at PLT -; LINUX-64-PIC-NEXT: addq $8, %rsp +; LINUX-64-PIC-NEXT: popq ; LINUX-64-PIC-NEXT: ret ; DARWIN-32-STATIC: _lcaller: @@ -8960,24 +8960,24 @@ ; DARWIN-32-PIC-NEXT: ret ; DARWIN-64-STATIC: _lcaller: -; DARWIN-64-STATIC: subq $8, %rsp +; DARWIN-64-STATIC: pushq ; DARWIN-64-STATIC-NEXT: callq _lcallee ; DARWIN-64-STATIC-NEXT: callq _lcallee -; DARWIN-64-STATIC-NEXT: addq $8, %rsp +; DARWIN-64-STATIC-NEXT: popq ; DARWIN-64-STATIC-NEXT: ret ; DARWIN-64-DYNAMIC: _lcaller: -; DARWIN-64-DYNAMIC: subq $8, %rsp +; DARWIN-64-DYNAMIC: pushq ; DARWIN-64-DYNAMIC-NEXT: callq _lcallee ; DARWIN-64-DYNAMIC-NEXT: callq _lcallee -; DARWIN-64-DYNAMIC-NEXT: addq $8, %rsp +; DARWIN-64-DYNAMIC-NEXT: popq ; DARWIN-64-DYNAMIC-NEXT: ret ; DARWIN-64-PIC: _lcaller: -; DARWIN-64-PIC: subq $8, %rsp +; DARWIN-64-PIC: pushq ; DARWIN-64-PIC-NEXT: callq _lcallee ; DARWIN-64-PIC-NEXT: callq _lcallee -; DARWIN-64-PIC-NEXT: addq $8, %rsp +; DARWIN-64-PIC-NEXT: popq ; DARWIN-64-PIC-NEXT: ret } @@ -8990,21 +8990,21 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: tailcaller: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll callee -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: tailcaller: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll callee -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: tailcaller: -; LINUX-64-PIC: subq $8, %rsp +; LINUX-64-PIC: pushq ; LINUX-64-PIC-NEXT: callq callee at PLT -; LINUX-64-PIC-NEXT: addq $8, %rsp +; LINUX-64-PIC-NEXT: popq ; LINUX-64-PIC-NEXT: ret ; DARWIN-32-STATIC: _tailcaller: @@ -9026,21 +9026,21 @@ ; DARWIN-32-PIC-NEXT: ret ; DARWIN-64-STATIC: _tailcaller: -; DARWIN-64-STATIC: subq $8, %rsp +; DARWIN-64-STATIC: pushq ; DARWIN-64-STATIC-NEXT: callq _callee -; DARWIN-64-STATIC-NEXT: addq $8, %rsp +; DARWIN-64-STATIC-NEXT: popq ; DARWIN-64-STATIC-NEXT: ret ; DARWIN-64-DYNAMIC: _tailcaller: -; DARWIN-64-DYNAMIC: subq $8, %rsp +; DARWIN-64-DYNAMIC: pushq ; DARWIN-64-DYNAMIC-NEXT: callq _callee -; DARWIN-64-DYNAMIC-NEXT: addq $8, %rsp +; DARWIN-64-DYNAMIC-NEXT: popq ; DARWIN-64-DYNAMIC-NEXT: ret ; DARWIN-64-PIC: _tailcaller: -; DARWIN-64-PIC: subq $8, %rsp +; DARWIN-64-PIC: pushq ; DARWIN-64-PIC-NEXT: callq _callee -; DARWIN-64-PIC-NEXT: addq $8, %rsp +; DARWIN-64-PIC-NEXT: popq ; DARWIN-64-PIC-NEXT: ret } @@ -9053,21 +9053,21 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: dtailcaller: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll dcallee -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: dtailcaller: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll dcallee -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: dtailcaller: -; LINUX-64-PIC: subq $8, %rsp +; LINUX-64-PIC: pushq ; LINUX-64-PIC-NEXT: callq dcallee -; LINUX-64-PIC-NEXT: addq $8, %rsp +; LINUX-64-PIC-NEXT: popq ; LINUX-64-PIC-NEXT: ret ; DARWIN-32-STATIC: _dtailcaller: @@ -9089,21 +9089,21 @@ ; DARWIN-32-PIC-NEXT: ret ; DARWIN-64-STATIC: _dtailcaller: -; DARWIN-64-STATIC: subq $8, %rsp +; DARWIN-64-STATIC: pushq ; DARWIN-64-STATIC-NEXT: callq _dcallee -; DARWIN-64-STATIC-NEXT: addq $8, %rsp +; DARWIN-64-STATIC-NEXT: popq ; DARWIN-64-STATIC-NEXT: ret ; DARWIN-64-DYNAMIC: _dtailcaller: -; DARWIN-64-DYNAMIC: subq $8, %rsp +; DARWIN-64-DYNAMIC: pushq ; DARWIN-64-DYNAMIC-NEXT: callq _dcallee -; DARWIN-64-DYNAMIC-NEXT: addq $8, %rsp +; DARWIN-64-DYNAMIC-NEXT: popq ; DARWIN-64-DYNAMIC-NEXT: ret ; DARWIN-64-PIC: _dtailcaller: -; DARWIN-64-PIC: subq $8, %rsp +; DARWIN-64-PIC: pushq ; DARWIN-64-PIC-NEXT: callq _dcallee -; DARWIN-64-PIC-NEXT: addq $8, %rsp +; DARWIN-64-PIC-NEXT: popq ; DARWIN-64-PIC-NEXT: ret } @@ -9116,21 +9116,21 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: ltailcaller: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll lcallee -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: ltailcaller: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll lcallee -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: ltailcaller: -; LINUX-64-PIC: subq $8, %rsp +; LINUX-64-PIC: pushq ; LINUX-64-PIC-NEXT: callq lcallee at PLT -; LINUX-64-PIC-NEXT: addq $8, %rsp +; LINUX-64-PIC-NEXT: popq ; LINUX-64-PIC-NEXT: ret ; DARWIN-32-STATIC: _ltailcaller: @@ -9152,21 +9152,21 @@ ; DARWIN-32-PIC-NEXT: ret ; DARWIN-64-STATIC: _ltailcaller: -; DARWIN-64-STATIC: subq $8, %rsp +; DARWIN-64-STATIC: pushq ; DARWIN-64-STATIC-NEXT: callq _lcallee -; DARWIN-64-STATIC-NEXT: addq $8, %rsp +; DARWIN-64-STATIC-NEXT: popq ; DARWIN-64-STATIC-NEXT: ret ; DARWIN-64-DYNAMIC: _ltailcaller: -; DARWIN-64-DYNAMIC: subq $8, %rsp +; DARWIN-64-DYNAMIC: pushq ; DARWIN-64-DYNAMIC-NEXT: callq _lcallee -; DARWIN-64-DYNAMIC-NEXT: addq $8, %rsp +; DARWIN-64-DYNAMIC-NEXT: popq ; DARWIN-64-DYNAMIC-NEXT: ret ; DARWIN-64-PIC: _ltailcaller: -; DARWIN-64-PIC: subq $8, %rsp +; DARWIN-64-PIC: pushq ; DARWIN-64-PIC-NEXT: callq _lcallee -; DARWIN-64-PIC-NEXT: addq $8, %rsp +; DARWIN-64-PIC-NEXT: popq ; DARWIN-64-PIC-NEXT: ret } @@ -9183,17 +9183,17 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: icaller: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll *ifunc ; LINUX-32-STATIC-NEXT: calll *ifunc -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: icaller: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll *ifunc ; LINUX-32-PIC-NEXT: calll *ifunc -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: icaller: @@ -9272,17 +9272,17 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: dicaller: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll *difunc ; LINUX-32-STATIC-NEXT: calll *difunc -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: dicaller: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll *difunc ; LINUX-32-PIC-NEXT: calll *difunc -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: dicaller: @@ -9320,24 +9320,24 @@ ; DARWIN-32-PIC-NEXT: ret ; DARWIN-64-STATIC: _dicaller: -; DARWIN-64-STATIC: subq $8, %rsp +; DARWIN-64-STATIC: pushq ; DARWIN-64-STATIC-NEXT: callq *_difunc(%rip) ; DARWIN-64-STATIC-NEXT: callq *_difunc(%rip) -; DARWIN-64-STATIC-NEXT: addq $8, %rsp +; DARWIN-64-STATIC-NEXT: popq ; DARWIN-64-STATIC-NEXT: ret ; DARWIN-64-DYNAMIC: _dicaller: -; DARWIN-64-DYNAMIC: subq $8, %rsp +; DARWIN-64-DYNAMIC: pushq ; DARWIN-64-DYNAMIC-NEXT: callq *_difunc(%rip) ; DARWIN-64-DYNAMIC-NEXT: callq *_difunc(%rip) -; DARWIN-64-DYNAMIC-NEXT: addq $8, %rsp +; DARWIN-64-DYNAMIC-NEXT: popq ; DARWIN-64-DYNAMIC-NEXT: ret ; DARWIN-64-PIC: _dicaller: -; DARWIN-64-PIC: subq $8, %rsp +; DARWIN-64-PIC: pushq ; DARWIN-64-PIC-NEXT: callq *_difunc(%rip) ; DARWIN-64-PIC-NEXT: callq *_difunc(%rip) -; DARWIN-64-PIC-NEXT: addq $8, %rsp +; DARWIN-64-PIC-NEXT: popq ; DARWIN-64-PIC-NEXT: ret } @@ -9354,24 +9354,24 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: licaller: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll *lifunc ; LINUX-32-STATIC-NEXT: calll *lifunc -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: licaller: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll *lifunc ; LINUX-32-PIC-NEXT: calll *lifunc -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: licaller: -; LINUX-64-PIC: subq $8, %rsp +; LINUX-64-PIC: pushq ; LINUX-64-PIC-NEXT: callq *lifunc(%rip) ; LINUX-64-PIC-NEXT: callq *lifunc(%rip) -; LINUX-64-PIC-NEXT: addq $8, %rsp +; LINUX-64-PIC-NEXT: popq ; LINUX-64-PIC-NEXT: ret ; DARWIN-32-STATIC: _licaller: @@ -9401,24 +9401,24 @@ ; DARWIN-32-PIC-NEXT: ret ; DARWIN-64-STATIC: _licaller: -; DARWIN-64-STATIC: subq $8, %rsp +; DARWIN-64-STATIC: pushq ; DARWIN-64-STATIC-NEXT: callq *_lifunc(%rip) ; DARWIN-64-STATIC-NEXT: callq *_lifunc(%rip) -; DARWIN-64-STATIC-NEXT: addq $8, %rsp +; DARWIN-64-STATIC-NEXT: popq ; DARWIN-64-STATIC-NEXT: ret ; DARWIN-64-DYNAMIC: _licaller: -; DARWIN-64-DYNAMIC: subq $8, %rsp +; DARWIN-64-DYNAMIC: pushq ; DARWIN-64-DYNAMIC-NEXT: callq *_lifunc(%rip) ; DARWIN-64-DYNAMIC-NEXT: callq *_lifunc(%rip) -; DARWIN-64-DYNAMIC-NEXT: addq $8, %rsp +; DARWIN-64-DYNAMIC-NEXT: popq ; DARWIN-64-DYNAMIC-NEXT: ret ; DARWIN-64-PIC: _licaller: -; DARWIN-64-PIC: subq $8, %rsp +; DARWIN-64-PIC: pushq ; DARWIN-64-PIC-NEXT: callq *_lifunc(%rip) ; DARWIN-64-PIC-NEXT: callq *_lifunc(%rip) -; DARWIN-64-PIC-NEXT: addq $8, %rsp +; DARWIN-64-PIC-NEXT: popq ; DARWIN-64-PIC-NEXT: ret } @@ -9435,17 +9435,17 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: itailcaller: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll *ifunc ; LINUX-32-STATIC-NEXT: calll *ifunc -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: itailcaller: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll *ifunc ; LINUX-32-PIC-NEXT: calll *ifunc -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: itailcaller: @@ -9521,22 +9521,22 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: ditailcaller: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll *difunc -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: ditailcaller: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll *difunc -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: ditailcaller: -; LINUX-64-PIC: subq $8, %rsp +; LINUX-64-PIC: pushq ; LINUX-64-PIC-NEXT: movq difunc at GOTPCREL(%rip), %rax ; LINUX-64-PIC-NEXT: callq *(%rax) -; LINUX-64-PIC-NEXT: addq $8, %rsp +; LINUX-64-PIC-NEXT: popq ; LINUX-64-PIC-NEXT: ret ; DARWIN-32-STATIC: _ditailcaller: @@ -9561,20 +9561,20 @@ ; DARWIN-32-PIC-NEXT: ret ; DARWIN-64-STATIC: _ditailcaller: -; DARWIN-64-STATIC: subq $8, %rsp +; DARWIN-64-STATIC: pushq ; DARWIN-64-STATIC-NEXT: callq *_difunc(%rip) -; DARWIN-64-STATIC-NEXT: addq $8, %rsp +; DARWIN-64-STATIC-NEXT: popq ; DARWIN-64-STATIC-NEXT: ret ; DARWIN-64-DYNAMIC: _ditailcaller: -; DARWIN-64-DYNAMIC: subq $8, %rsp +; DARWIN-64-DYNAMIC: pushq ; DARWIN-64-DYNAMIC-NEXT: callq *_difunc(%rip) -; DARWIN-64-DYNAMIC-NEXT: addq $8, %rsp +; DARWIN-64-DYNAMIC-NEXT: popq ; DARWIN-64-DYNAMIC-NEXT: ret ; DARWIN-64-PIC: _ditailcaller: ; DARWIN-64-PIC: callq *_difunc(%rip) -; DARWIN-64-PIC-NEXT: addq $8, %rsp +; DARWIN-64-PIC-NEXT: popq ; DARWIN-64-PIC-NEXT: ret } @@ -9588,21 +9588,21 @@ ; LINUX-64-STATIC: ret ; LINUX-32-STATIC: litailcaller: -; LINUX-32-STATIC: subl $4, %esp +; LINUX-32-STATIC: pushl ; LINUX-32-STATIC-NEXT: calll *lifunc -; LINUX-32-STATIC-NEXT: addl $4, %esp +; LINUX-32-STATIC-NEXT: popl ; LINUX-32-STATIC-NEXT: ret ; LINUX-32-PIC: litailcaller: -; LINUX-32-PIC: subl $4, %esp +; LINUX-32-PIC: pushl ; LINUX-32-PIC-NEXT: calll *lifunc -; LINUX-32-PIC-NEXT: addl $4, %esp +; LINUX-32-PIC-NEXT: popl ; LINUX-32-PIC-NEXT: ret ; LINUX-64-PIC: litailcaller: -; LINUX-64-PIC: subq $8, %rsp +; LINUX-64-PIC: pushq ; LINUX-64-PIC-NEXT: callq *lifunc(%rip) -; LINUX-64-PIC-NEXT: addq $8, %rsp +; LINUX-64-PIC-NEXT: popq ; LINUX-64-PIC-NEXT: ret ; DARWIN-32-STATIC: _litailcaller: @@ -9627,20 +9627,20 @@ ; DARWIN-32-PIC-NEXT: ret ; DARWIN-64-STATIC: _litailcaller: -; DARWIN-64-STATIC: subq $8, %rsp +; DARWIN-64-STATIC: pushq ; DARWIN-64-STATIC-NEXT: callq *_lifunc(%rip) -; DARWIN-64-STATIC-NEXT: addq $8, %rsp +; DARWIN-64-STATIC-NEXT: popq ; DARWIN-64-STATIC-NEXT: ret ; DARWIN-64-DYNAMIC: _litailcaller: -; DARWIN-64-DYNAMIC: subq $8, %rsp +; DARWIN-64-DYNAMIC: pushq ; DARWIN-64-DYNAMIC-NEXT: callq *_lifunc(%rip) -; DARWIN-64-DYNAMIC-NEXT: addq $8, %rsp +; DARWIN-64-DYNAMIC-NEXT: popq ; DARWIN-64-DYNAMIC-NEXT: ret ; DARWIN-64-PIC: _litailcaller: -; DARWIN-64-PIC: subq $8, %rsp +; DARWIN-64-PIC: pushq ; DARWIN-64-PIC-NEXT: callq *_lifunc(%rip) -; DARWIN-64-PIC-NEXT: addq $8, %rsp +; DARWIN-64-PIC-NEXT: popq ; DARWIN-64-PIC-NEXT: ret } Modified: llvm/trunk/test/CodeGen/X86/licm-symbol.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/licm-symbol.ll?rev=122783&r1=122782&r2=122783&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/licm-symbol.ll (original) +++ llvm/trunk/test/CodeGen/X86/licm-symbol.ll Mon Jan 3 16:53:22 2011 @@ -3,7 +3,7 @@ ; MachineLICM should be able to hoist the sF reference out of the loop. ; CHECK: pushl %esi -; CHECK: subl $4, %esp +; CHECK: pushl ; CHECK: movl $176, %esi ; CHECK: addl L___sF$non_lazy_ptr, %esi ; CHECK: .align 4, 0x90 Modified: llvm/trunk/test/CodeGen/X86/tail-opts.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tail-opts.ll?rev=122783&r1=122782&r2=122783&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tail-opts.ll (original) +++ llvm/trunk/test/CodeGen/X86/tail-opts.ll Mon Jan 3 16:53:22 2011 @@ -273,7 +273,7 @@ ; CHECK: foo: ; CHECK: callq func ; CHECK-NEXT: .LBB4_2: -; CHECK-NEXT: addq $8, %rsp +; CHECK-NEXT: popq ; CHECK-NEXT: ret define void @foo(i1* %V) nounwind { Modified: llvm/trunk/test/CodeGen/X86/tailcall-largecode.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcall-largecode.ll?rev=122783&r1=122782&r2=122783&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tailcall-largecode.ll (original) +++ llvm/trunk/test/CodeGen/X86/tailcall-largecode.ll Mon Jan 3 16:53:22 2011 @@ -17,7 +17,7 @@ ; Adjust the stack to enter the function. (The amount of the ; adjustment may change in the future, in which case the location of ; the stack argument and the return adjustment will change too.) -; CHECK: subq $8, %rsp +; CHECK: pushq ; Put the call target into R11, which won't be clobbered while restoring ; callee-saved registers and won't be used for passing arguments. ; CHECK: movq %rdi, %rax @@ -31,7 +31,7 @@ ; CHECK: movl $5, %r8d ; CHECK: movl $6, %r9d ; Adjust the stack to "return". -; CHECK: addq $8, %rsp +; CHECK: popq ; And tail-call to the target. ; CHECK: jmpq *%rax # TAILCALL %res = tail call fastcc i32 %target(i32 1, i32 2, i32 3, i32 4, i32 5, @@ -46,7 +46,7 @@ ; Adjust the stack to enter the function. (The amount of the ; adjustment may change in the future, in which case the location of ; the stack argument and the return adjustment will change too.) -; CHECK: subq $8, %rsp +; CHECK: pushq ; Pass the stack argument. ; CHECK: movl $7, 16(%rsp) ; Pass the register arguments, in the right registers. @@ -62,7 +62,7 @@ ; arguments. ; CHECK: movabsq $manyargs_callee, %rax ; Adjust the stack to "return". -; CHECK: addq $8, %rsp +; CHECK: popq ; And tail-call to the target. ; CHECK: jmpq *%rax # TAILCALL %res = tail call fastcc i32 @manyargs_callee(i32 1, i32 2, i32 3, i32 4, Modified: llvm/trunk/test/CodeGen/X86/tlv-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tlv-2.ll?rev=122783&r1=122782&r2=122783&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tlv-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/tlv-2.ll Mon Jan 3 16:53:22 2011 @@ -26,7 +26,7 @@ ; CHECK: movq _d at TLVP(%rip), %rdi ; CHECK: callq *(%rdi) ; CHECK: movl $4, (%rax) - ; CHECK: addq $8, %rsp + ; CHECK: popq ret void } From gohman at apple.com Mon Jan 3 17:15:21 2011 From: gohman at apple.com (Dan Gohman) Date: Mon, 3 Jan 2011 15:15:21 -0800 Subject: [llvm-commits] [llvm] r122715 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp test/Transforms/EarlyCSE/ test/Transforms/EarlyCSE/basic.ll test/Transforms/EarlyCSE/dg.exp In-Reply-To: <20110102230414.B3B9B2A6C12C@llvm.org> References: <20110102230414.B3B9B2A6C12C@llvm.org> Message-ID: <613EB5DF-3D84-4256-AC65-325BEAEE299E@apple.com> On Jan 2, 2011, at 3:04 PM, Chris Lattner wrote: > > + // See if the instruction has an available value. If so, use it. > + if (Instruction *V = AvailableValues->lookup(InstValue::get(Inst))) { > + Inst->replaceAllUsesWith(V); > + Inst->eraseFromParent(); > + Changed = true; > + continue; > + } Hi Chris, Since optional flags such as nsw, inbounds, etc. are not currently being hashed, this code could replace a value with another value with a proper superset of flags, which is not valid in general. One way to fix this would be to call intersectOptionalDataWith here. Dan From clattner at apple.com Mon Jan 3 17:24:07 2011 From: clattner at apple.com (Chris Lattner) Date: Mon, 3 Jan 2011 15:24:07 -0800 Subject: [llvm-commits] [llvm] r122715 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp test/Transforms/EarlyCSE/ test/Transforms/EarlyCSE/basic.ll test/Transforms/EarlyCSE/dg.exp In-Reply-To: <613EB5DF-3D84-4256-AC65-325BEAEE299E@apple.com> References: <20110102230414.B3B9B2A6C12C@llvm.org> <613EB5DF-3D84-4256-AC65-325BEAEE299E@apple.com> Message-ID: On Jan 3, 2011, at 3:15 PM, Dan Gohman wrote: > > On Jan 2, 2011, at 3:04 PM, Chris Lattner wrote: >> >> + // See if the instruction has an available value. If so, use it. >> + if (Instruction *V = AvailableValues->lookup(InstValue::get(Inst))) { >> + Inst->replaceAllUsesWith(V); >> + Inst->eraseFromParent(); >> + Changed = true; >> + continue; >> + } > > Hi Chris, > > Since optional flags such as nsw, inbounds, etc. are not currently being hashed, > this code could replace a value with another value with a proper superset of > flags, which is not valid in general. One way to fix this would be to call > intersectOptionalDataWith here. This will only replace one instruction with another if they pass the "Instruction::isIdenticalTo" predicate. I think that checks flags, so this should be ok (we'll just get a hash collision, which is fine). Does this make sense? -Chris From evan.cheng at apple.com Mon Jan 3 17:28:47 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 3 Jan 2011 15:28:47 -0800 Subject: [llvm-commits] [llvm] r122743 - /llvm/trunk/include/llvm/Support/StandardPasses.h In-Reply-To: References: <20110103075318.909D72A6C12C@llvm.org> Message-ID: On Jan 3, 2011, at 10:11 AM, Chris Lattner wrote: > > On Jan 2, 2011, at 11:53 PM, Evan Cheng wrote: > >> Author: evancheng >> Date: Mon Jan 3 01:53:18 2011 >> New Revision: 122743 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122743&view=rev >> Log: >> Undo what looks like accidental removal of an instcombine pass in r122740. > > This wasn't accidental, is there a reason you want an instcombine here? No reason other than it was there before r122740 (which is only supposed to add the earlycse pass). Are you certain there is no loss from removing this instcombine pass? Evan > > -Chris > >> >> Modified: >> llvm/trunk/include/llvm/Support/StandardPasses.h >> >> Modified: llvm/trunk/include/llvm/Support/StandardPasses.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=122743&r1=122742&r2=122743&view=diff >> ============================================================================== >> --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) >> +++ llvm/trunk/include/llvm/Support/StandardPasses.h Mon Jan 3 01:53:18 2011 >> @@ -132,6 +132,7 @@ >> PM->add(createEarlyCSEPass()); // Catch trivial redundancies >> if (SimplifyLibCalls) >> PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations >> + PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. >> PM->add(createJumpThreadingPass()); // Thread jumps. >> PM->add(createCorrelatedValuePropagationPass()); // Propagate conditionals >> PM->add(createCFGSimplificationPass()); // Merge & remove BBs >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From clattner at apple.com Mon Jan 3 17:33:20 2011 From: clattner at apple.com (Chris Lattner) Date: Mon, 3 Jan 2011 15:33:20 -0800 Subject: [llvm-commits] [llvm] r122743 - /llvm/trunk/include/llvm/Support/StandardPasses.h In-Reply-To: References: <20110103075318.909D72A6C12C@llvm.org> Message-ID: <4AA9515B-5C13-4B04-845B-78B0AB45C2C9@apple.com> On Jan 3, 2011, at 3:28 PM, Evan Cheng wrote: > > On Jan 3, 2011, at 10:11 AM, Chris Lattner wrote: > >> >> On Jan 2, 2011, at 11:53 PM, Evan Cheng wrote: >> >>> Author: evancheng >>> Date: Mon Jan 3 01:53:18 2011 >>> New Revision: 122743 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=122743&view=rev >>> Log: >>> Undo what looks like accidental removal of an instcombine pass in r122740. >> >> This wasn't accidental, is there a reason you want an instcombine here? > > No reason other than it was there before r122740 (which is only supposed to add the earlycse pass). Are you certain there is no loss from removing this instcombine pass? I'm not certain that there is no loss in no cases, but the performance comparisons I did had it removed and the intention of earlycse is to subsume that particular run of instcombine. -Chris From clattner at apple.com Mon Jan 3 17:34:45 2011 From: clattner at apple.com (Chris Lattner) Date: Mon, 3 Jan 2011 15:34:45 -0800 Subject: [llvm-commits] [llvm] r122740 - /llvm/trunk/include/llvm/Support/StandardPasses.h In-Reply-To: <20110103073709.GA89749@freebsd.org> References: <20110103061909.6C80C2A6C12C@llvm.org> <20110103073709.GA89749@freebsd.org> Message-ID: <80947CB2-DC50-41C6-8105-25268BE779E0@apple.com> On Jan 2, 2011, at 11:37 PM, Roman Divacky wrote: > On Mon, Jan 03, 2011 at 06:19:09AM -0000, Chris Lattner wrote: >> +++ llvm/trunk/include/llvm/Support/StandardPasses.h Mon Jan 3 00:19:09 2011 >> @@ -129,9 +129,9 @@ >> >> // Start of function pass. >> PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas >> + PM->add(createEarlyCSEPass()); // Catch trivial redundancies >> if (SimplifyLibCalls) >> PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations >> - PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. > > was removing the InstructionCombiningPass intended? > > gnu screen compiles to 344992 bytes without InstructionCombiningPass (as in trunk) > but to 344624 bytes with the InstructionCombiningPass kept... Hi Roman, Can you please file a bug with a .i file (along with the flags you're building with) for one of the files that is smaller with instcombine? It is entirely possible that an extra loop gets unrolled now or something like that, but I'd like to verify. Thanks! -Chris From clattner at apple.com Mon Jan 3 17:37:24 2011 From: clattner at apple.com (Chris Lattner) Date: Mon, 3 Jan 2011 15:37:24 -0800 Subject: [llvm-commits] [llvm] r122704 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll In-Reply-To: <4D2195BD.5000402@free.fr> References: <20110102190103.6EECD2A6C12C@llvm.org> <4D2195BD.5000402@free.fr> Message-ID: <2C5B6D79-D5B9-4ED8-999E-1471C2A9FD79@apple.com> On Jan 3, 2011, at 1:24 AM, Duncan Sands wrote: > Hi Chris, > >> enhance loop idiom recognition to scan *all* unconditionally executed >> blocks in a loop, instead of just the header block. This makes it more >> aggressive, able to handle Duncan's Ada examples. > > thanks for doing this! I noticed two issues with the examples I sent you, > which now compile to I didn't keep the .ll files, otherwise I'd answer these questions myself: > define void @ubytezero([256 x i32]* %a) nounwind { > return: > %tmp32 = getelementptr [256 x i32]* %a, i32 0, i32 0 > store i32 0, i32* %tmp32, align 4 > %scevgep = getelementptr [256 x i32]* %a, i32 0, i32 1 > %scevgep4 = bitcast i32* %scevgep to i8* > call void @llvm.memset.p0i8.i32(i8* %scevgep4, i8 0, i32 1020, i32 4, i1 false) > ret void > } > > define void @uintzero(i32* %a) nounwind { > return: > store i32 0, i32* %a, align 4 > %scevgep = getelementptr i32* %a, i32 1 > %scevgep3 = bitcast i32* %scevgep to i8* > call void @llvm.memset.p0i8.i32(i8* %scevgep3, i8 0, i32 -4, i32 4, i1 false) > ret void > } > > In both functions the memset could also take care of the store to the first > element, rather than starting from the second element. However maybe merging > the store and the memset should be a job for a different pass. It's likely that this should be done by memcpy opt, which has logic for merging multiple consecutive stores into a memset. > Secondly, notice that the size of the memset in the second function is -4. > Hopefully this will work correctly (i.e. memset 2^32-4 values)! It did make > me wonder what happens if the loop stores say 2^32 or 2^48 values. Presumably > the type of the memset size argument is automagically set to a size that can > hold the loop trip count... I don't understand what you're saying here... is there a miscompilation, or was the original code doing this large store? -4 is "a big 32-bit number" and is zero extended to i64 on 64-bit targets. -Chris From sabre at nondot.org Mon Jan 3 17:38:13 2011 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Jan 2011 23:38:13 -0000 Subject: [llvm-commits] [llvm] r122785 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp test/Transforms/EarlyCSE/basic.ll Message-ID: <20110103233813.CCBDC2A6C12C@llvm.org> Author: lattner Date: Mon Jan 3 17:38:13 2011 New Revision: 122785 URL: http://llvm.org/viewvc/llvm-project?rev=122785&view=rev Log: Duncan deftly points out that readnone functions aren't invalidated by stores, so they can be handled as 'simple' operations. Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp llvm/trunk/test/Transforms/EarlyCSE/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=122785&r1=122784&r2=122785&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Mon Jan 3 17:38:13 2011 @@ -56,6 +56,9 @@ } static bool canHandle(Instruction *Inst) { + // This can only handle non-void readnone functions. + if (CallInst *CI = dyn_cast(Inst)) + return CI->doesNotAccessMemory() && !CI->getType()->isVoidTy(); return isa(Inst) || isa(Inst) || isa(Inst) || isa(Inst) || isa(Inst) || isa(Inst) || @@ -105,7 +108,8 @@ Res ^= *I; } else { // nothing extra to hash in. - assert((isa(Inst) || isa(Inst) || + assert((isa(Inst) || + isa(Inst) || isa(Inst) || isa(Inst) || isa(Inst) || isa(Inst) || isa(Inst)) && "Invalid/unknown instruction"); Modified: llvm/trunk/test/Transforms/EarlyCSE/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/EarlyCSE/basic.ll?rev=122785&r1=122784&r2=122785&view=diff ============================================================================== --- llvm/trunk/test/Transforms/EarlyCSE/basic.ll (original) +++ llvm/trunk/test/Transforms/EarlyCSE/basic.ll Mon Jan 3 17:38:13 2011 @@ -106,3 +106,16 @@ ; CHECK-NEXT: store i32 45 ; CHECK-NEXT: ret void } + +;; Readnone functions aren't invalidated by stores. +; CHECK: @test8 +define i32 @test8(i32 *%P) { + %V1 = call i32 @func(i32* %P) readnone + store i32 4, i32* %P + %V2 = call i32 @func(i32* %P) readnone + %Diff = sub i32 %V1, %V2 + ret i32 %Diff + ; CHECK: ret i32 0 +} + + From clattner at apple.com Mon Jan 3 17:41:25 2011 From: clattner at apple.com (Chris Lattner) Date: Mon, 3 Jan 2011 15:41:25 -0800 Subject: [llvm-commits] [llvm] r122731 - /llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp In-Reply-To: <4D21C53A.10207@free.fr> References: <20110103034128.092322A6C12C@llvm.org> <4D21C53A.10207@free.fr> Message-ID: On Jan 3, 2011, at 4:46 AM, Duncan Sands wrote: > Hi Chris, > >> split loads and calls into separate tables. Loads are now just indexed >> by their pointer instead of using MemoryValue to wrap it. > > for readnone calls you don't have to worry about generations, writing to > memory etc, you can treat them the same as (eg) an "add" instruction. Great point, implemented in r122785. Thanks! -Chris From gohman at apple.com Mon Jan 3 17:43:03 2011 From: gohman at apple.com (Dan Gohman) Date: Mon, 3 Jan 2011 15:43:03 -0800 Subject: [llvm-commits] [llvm] r122678 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll In-Reply-To: <20110102033756.880E62A6C12C@llvm.org> References: <20110102033756.880E62A6C12C@llvm.org> Message-ID: <153940A7-1A50-43F1-BC87-B6C3B59784C5@apple.com> On Jan 1, 2011, at 7:37 PM, Chris Lattner wrote: > > + // The # stored bytes is (BECount+1)*Size. Expand the trip count out to > + // pointer size if it isn't already. > + const Type *IntPtr = TD->getIntPtrType(SI->getContext()); > + unsigned BESize = SE->getTypeSizeInBits(BECount->getType()); > + if (BESize < TD->getPointerSizeInBits()) > + BECount = SE->getZeroExtendExpr(BECount, IntPtr); > + else if (BESize > TD->getPointerSizeInBits()) > + BECount = SE->getTruncateExpr(BECount, IntPtr); This code (and other instances of it) can be simplified using ScalarEvolution's getTruncateOrZeroExtend. Also, truncating is surprising here, though I guess maybe it's safe since any loop where it would change the value would be iterating over the entire address space. > + > + const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1), > + true, true /*nooverflow*/); Setting nuw here is surprising, but as above, overflow would mean the loop is iterating over the entire address space. Setting nsw here seems incorrect, as there's no fundamental reason why iterating over half of the address space is invalid. Dan From gohman at apple.com Mon Jan 3 17:45:55 2011 From: gohman at apple.com (Dan Gohman) Date: Mon, 3 Jan 2011 15:45:55 -0800 Subject: [llvm-commits] [llvm] r122715 - in /llvm/trunk: lib/Transforms/Scalar/EarlyCSE.cpp test/Transforms/EarlyCSE/ test/Transforms/EarlyCSE/basic.ll test/Transforms/EarlyCSE/dg.exp In-Reply-To: References: <20110102230414.B3B9B2A6C12C@llvm.org> <613EB5DF-3D84-4256-AC65-325BEAEE299E@apple.com> Message-ID: <7925A3A8-7287-4C74-BB11-025C760EA9FB@apple.com> On Jan 3, 2011, at 3:24 PM, Chris Lattner wrote: > > On Jan 3, 2011, at 3:15 PM, Dan Gohman wrote: > >> >> On Jan 2, 2011, at 3:04 PM, Chris Lattner wrote: >>> >>> + // See if the instruction has an available value. If so, use it. >>> + if (Instruction *V = AvailableValues->lookup(InstValue::get(Inst))) { >>> + Inst->replaceAllUsesWith(V); >>> + Inst->eraseFromParent(); >>> + Changed = true; >>> + continue; >>> + } >> >> Hi Chris, >> >> Since optional flags such as nsw, inbounds, etc. are not currently being hashed, >> this code could replace a value with another value with a proper superset of >> flags, which is not valid in general. One way to fix this would be to call >> intersectOptionalDataWith here. > > This will only replace one instruction with another if they pass the "Instruction::isIdenticalTo" predicate. I think that checks flags, so this should be ok (we'll just get a hash collision, which is fine). Does this make sense? Ok, I see it now. So it would theoretically be possible to use isIdenticalToWhenDefined instead, along with intersectOptionalDataWith, to be slightly more aggressive, but it's probably not important. Dan From evan.cheng at apple.com Mon Jan 3 17:47:14 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 03 Jan 2011 23:47:14 -0000 Subject: [llvm-commits] [llvm] r122786 - in /llvm/trunk/test/MC/ELF: basic-elf-32.s basic-elf-64.s basic-elf.ll call-abs.ll call-abs.s Message-ID: <20110103234714.C37082A6C12C@llvm.org> Author: evancheng Date: Mon Jan 3 17:47:14 2011 New Revision: 122786 URL: http://llvm.org/viewvc/llvm-project?rev=122786&view=rev Log: Convert MC tests to .s so codegen changes won't break them. Added: llvm/trunk/test/MC/ELF/basic-elf-32.s llvm/trunk/test/MC/ELF/basic-elf-64.s llvm/trunk/test/MC/ELF/call-abs.s Removed: llvm/trunk/test/MC/ELF/basic-elf.ll llvm/trunk/test/MC/ELF/call-abs.ll Added: llvm/trunk/test/MC/ELF/basic-elf-32.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/basic-elf-32.s?rev=122786&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/basic-elf-32.s (added) +++ llvm/trunk/test/MC/ELF/basic-elf-32.s Mon Jan 3 17:47:14 2011 @@ -0,0 +1,78 @@ +// RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu %s -o - | elf-dump | FileCheck %s + + .text + .globl main + .align 16, 0x90 + .type main, at function +main: # @main +# BB#0: + subl $4, %esp + movl $.L.str1, (%esp) + calll puts + movl $.L.str2, (%esp) + calll puts + xorl %eax, %eax + addl $4, %esp + ret +.Ltmp0: + .size main, .Ltmp0-main + + .type .L.str1, at object # @.str1 + .section .rodata.str1.1,"aMS", at progbits,1 +.L.str1: + .asciz "Hello" + .size .L.str1, 6 + + .type .L.str2, at object # @.str2 +.L.str2: + .asciz "World!" + .size .L.str2, 7 + + .section .note.GNU-stack,"", at progbits + +// CHECK: ('e_indent[EI_CLASS]', 0x00000001) +// CHECK: ('e_indent[EI_DATA]', 0x00000001) +// CHECK: ('e_indent[EI_VERSION]', 0x00000001) +// CHECK: ('_sections', [ +// CHECK: # Section 0 +// CHECK: (('sh_name', 0x00000000) # '' + +// CHECK: # '.text' + +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) + +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) + +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) + +// CHECK: # 'main' +// CHECK: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_type', 0x00000002) + +// CHECK: # 'puts' +// CHECK: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_type', 0x00000000) + +// CHECK: # '.rel.text' + +// CHECK: ('_relocations', [ +// CHECK: # Relocation 0x00000000 +// CHECK: (('r_offset', 0x00000006) +// CHECK: ('r_type', 0x00000001) +// CHECK: ), +// CHECK: # Relocation 0x00000001 +// CHECK: (('r_offset', 0x0000000b) +// CHECK: ('r_type', 0x00000002) +// CHECK: ), +// CHECK: # Relocation 0x00000002 +// CHECK: (('r_offset', 0x00000012) +// CHECK: ('r_type', 0x00000001) +// CHECK: ), +// CHECK: # Relocation 0x00000003 +// CHECK: (('r_offset', 0x00000017) +// CHECK: ('r_type', 0x00000002) +// CHECK: ), +// CHECK: ]) Added: llvm/trunk/test/MC/ELF/basic-elf-64.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/basic-elf-64.s?rev=122786&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/basic-elf-64.s (added) +++ llvm/trunk/test/MC/ELF/basic-elf-64.s Mon Jan 3 17:47:14 2011 @@ -0,0 +1,82 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump | FileCheck %s + + .text + .globl main + .align 16, 0x90 + .type main, at function +main: # @main +# BB#0: + subq $8, %rsp + movl $.L.str1, %edi + callq puts + movl $.L.str2, %edi + callq puts + xorl %eax, %eax + addq $8, %rsp + ret +.Ltmp0: + .size main, .Ltmp0-main + + .type .L.str1, at object # @.str1 + .section .rodata.str1.1,"aMS", at progbits,1 +.L.str1: + .asciz "Hello" + .size .L.str1, 6 + + .type .L.str2, at object # @.str2 +.L.str2: + .asciz "World!" + .size .L.str2, 7 + + .section .note.GNU-stack,"", at progbits + +// CHECK: ('e_indent[EI_CLASS]', 0x00000002) +// CHECK: ('e_indent[EI_DATA]', 0x00000001) +// CHECK: ('e_indent[EI_VERSION]', 0x00000001) +// CHECK: ('_sections', [ +// CHECK: # Section 0 +// CHECK: (('sh_name', 0x00000000) # '' + +// CHECK: # '.text' + +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) + +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) + +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) + +// CHECK: # 'main' +// CHECK-NEXT: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_type', 0x00000002) + +// CHECK: # 'puts' +// CHECK-NEXT: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_type', 0x00000000) + +// CHECK: # '.rela.text' + +// CHECK: ('_relocations', [ +// CHECK: # Relocation 0x00000000 +// CHECK: (('r_offset', 0x00000005) +// CHECK: ('r_type', 0x0000000a) +// CHECK: ('r_addend', 0x00000000) +// CHECK: ), +// CHECK: # Relocation 0x00000001 +// CHECK: (('r_offset', 0x0000000a) +// CHECK: ('r_type', 0x00000002) +// CHECK: ('r_addend', 0xfffffffc) +// CHECK: ), +// CHECK: # Relocation 0x00000002 +// CHECK: (('r_offset', 0x0000000f) +// CHECK: ('r_type', 0x0000000a) +// CHECK: ('r_addend', 0x00000006) +// CHECK: ), +// CHECK: # Relocation 0x00000003 +// CHECK: (('r_offset', 0x00000014) +// CHECK: ('r_type', 0x00000002) +// CHECK: ('r_addend', 0xfffffffc) +// CHECK: ), +// CHECK: ]) Removed: llvm/trunk/test/MC/ELF/basic-elf.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/basic-elf.ll?rev=122785&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/basic-elf.ll (original) +++ llvm/trunk/test/MC/ELF/basic-elf.ll (removed) @@ -1,111 +0,0 @@ -; RUN: llc -filetype=obj -mtriple i686-pc-linux-gnu %s -o - | elf-dump | FileCheck -check-prefix=32 %s -; RUN: llc -filetype=obj -mtriple x86_64-pc-linux-gnu %s -o - | elf-dump | FileCheck -check-prefix=64 %s - - at .str1 = private constant [6 x i8] c"Hello\00" - at .str2 = private constant [7 x i8] c"World!\00" - -define i32 @main() nounwind { - %1 = call i32 @puts(i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0)) - %2 = call i32 @puts(i8* getelementptr inbounds ([7 x i8]* @.str2, i32 0, i32 0)) - ret i32 0 -} - -declare i32 @puts(i8* nocapture) nounwind - -; 32: ('e_indent[EI_CLASS]', 0x00000001) -; 32: ('e_indent[EI_DATA]', 0x00000001) -; 32: ('e_indent[EI_VERSION]', 0x00000001) -; 32: ('_sections', [ -; 32: # Section 0 -; 32: (('sh_name', 0x00000000) # '' - -; 32: # '.text' - -; 32: ('st_bind', 0x00000000) -; 32: ('st_type', 0x00000003) - -; 32: ('st_bind', 0x00000000) -; 32: ('st_type', 0x00000003) - -; 32: ('st_bind', 0x00000000) -; 32: ('st_type', 0x00000003) - -; 32: # 'main' -; 32: ('st_bind', 0x00000001) -; 32-NEXT: ('st_type', 0x00000002) - -; 32: # 'puts' -; 32: ('st_bind', 0x00000001) -; 32-NEXT: ('st_type', 0x00000000) - -; 32: # '.rel.text' - -; 32: ('_relocations', [ -; 32: # Relocation 0x00000000 -; 32: (('r_offset', 0x00000006) -; 32: ('r_type', 0x00000001) -; 32: ), -; 32: # Relocation 0x00000001 -; 32: (('r_offset', 0x0000000b) -; 32: ('r_type', 0x00000002) -; 32: ), -; 32: # Relocation 0x00000002 -; 32: (('r_offset', 0x00000012) -; 32: ('r_type', 0x00000001) -; 32: ), -; 32: # Relocation 0x00000003 -; 32: (('r_offset', 0x00000017) -; 32: ('r_type', 0x00000002) -; 32: ), -; 32: ]) - -; 64: ('e_indent[EI_CLASS]', 0x00000002) -; 64: ('e_indent[EI_DATA]', 0x00000001) -; 64: ('e_indent[EI_VERSION]', 0x00000001) -; 64: ('_sections', [ -; 64: # Section 0 -; 64: (('sh_name', 0x00000000) # '' - -; 64: # '.text' - -; 64: ('st_bind', 0x00000000) -; 64: ('st_type', 0x00000003) - -; 64: ('st_bind', 0x00000000) -; 64: ('st_type', 0x00000003) - -; 64: ('st_bind', 0x00000000) -; 64: ('st_type', 0x00000003) - -; 64: # 'main' -; 64-NEXT: ('st_bind', 0x00000001) -; 64-NEXT: ('st_type', 0x00000002) - -; 64: # 'puts' -; 64-NEXT: ('st_bind', 0x00000001) -; 64-NEXT: ('st_type', 0x00000000) - -; 64: # '.rela.text' - -; 64: ('_relocations', [ -; 64: # Relocation 0x00000000 -; 64: (('r_offset', 0x00000005) -; 64: ('r_type', 0x0000000a) -; 64: ('r_addend', 0x00000000) -; 64: ), -; 64: # Relocation 0x00000001 -; 64: (('r_offset', 0x0000000a) -; 64: ('r_type', 0x00000002) -; 64: ('r_addend', 0xfffffffc) -; 64: ), -; 64: # Relocation 0x00000002 -; 64: (('r_offset', 0x0000000f) -; 64: ('r_type', 0x0000000a) -; 64: ('r_addend', 0x00000006) -; 64: ), -; 64: # Relocation 0x00000003 -; 64: (('r_offset', 0x00000014) -; 64: ('r_type', 0x00000002) -; 64: ('r_addend', 0xfffffffc) -; 64: ), -; 64: ]) Removed: llvm/trunk/test/MC/ELF/call-abs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/call-abs.ll?rev=122785&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/call-abs.ll (original) +++ llvm/trunk/test/MC/ELF/call-abs.ll (removed) @@ -1,16 +0,0 @@ -; RUN: llc -filetype=obj -mtriple i686-pc-linux-gnu %s -o - | elf-dump | FileCheck %s - -define i32 @f() nounwind optsize ssp { -entry: - %call = tail call i32 inttoptr (i64 42 to i32 ()*)() nounwind optsize - %add = add nsw i32 %call, 1 - ret i32 %add -} - -; CHECK: ('_relocations', [ -; CHECK-NEXT: # Relocation 0x00000000 -; CHECK-NEXT: (('r_offset', 0x00000004) -; CHECK-NEXT: ('r_sym', 0x00000000) -; CHECK-NEXT: ('r_type', 0x00000002) -; CHECK-NEXT: ), -; CHECK-NEXT: ]) Added: llvm/trunk/test/MC/ELF/call-abs.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/call-abs.s?rev=122786&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/call-abs.s (added) +++ llvm/trunk/test/MC/ELF/call-abs.s Mon Jan 3 17:47:14 2011 @@ -0,0 +1,24 @@ +// RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu %s -o - | elf-dump | FileCheck %s + + .text + .globl f + .type f, at function +f: # @f +# BB#0: # %entry + subl $4, %esp + calll 42 + incl %eax + addl $4, %esp + ret +.Ltmp0: + .size f, .Ltmp0-f + + .section .note.GNU-stack,"", at progbits + +// CHECK: ('_relocations', [ +// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x00000004) +// CHECK-NEXT: ('r_sym', 0x00000000) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ), +// CHECK-NEXT: ]) From resistor at mac.com Mon Jan 3 17:51:43 2011 From: resistor at mac.com (Owen Anderson) Date: Mon, 03 Jan 2011 23:51:43 -0000 Subject: [llvm-commits] [llvm] r122787 - in /llvm/trunk/lib: Analysis/IPA/GlobalsModRef.cpp Analysis/NoAliasAnalysis.cpp Transforms/Scalar/GVN.cpp Message-ID: <20110103235143.AC4462A6C12C@llvm.org> Author: resistor Date: Mon Jan 3 17:51:43 2011 New Revision: 122787 URL: http://llvm.org/viewvc/llvm-project?rev=122787&view=rev Log: Use the new addEscapingValue callback to update GlobalsModRef when GVN adds PHIs of GEPs. For the moment, have GlobalsModRef handle this conservatively by simply removing the value from its maps. Modified: llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp llvm/trunk/lib/Analysis/NoAliasAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp?rev=122787&r1=122786&r2=122787&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp (original) +++ llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp Mon Jan 3 17:51:43 2011 @@ -152,6 +152,7 @@ virtual void deleteValue(Value *V); virtual void copyValue(Value *From, Value *To); + virtual void addEscapingUse(Use &U); /// getAdjustedAnalysisPointer - This method is used when a pass implements /// an analysis interface through multiple inheritance. If needed, it @@ -596,3 +597,13 @@ void GlobalsModRef::copyValue(Value *From, Value *To) { AliasAnalysis::copyValue(From, To); } + +void GlobalsModRef::addEscapingUse(Use &U) { + // For the purposes of this analysis, it is conservatively correct to treat + // a newly escaping value equivalently to a deleted one. We could perhaps + // be more precise by processing the new use and attempting to update our + // saved analysis results to accomodate it. + deleteValue(U); + + AliasAnalysis::addEscapingUse(U); +} Modified: llvm/trunk/lib/Analysis/NoAliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/NoAliasAnalysis.cpp?rev=122787&r1=122786&r2=122787&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/NoAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/NoAliasAnalysis.cpp Mon Jan 3 17:51:43 2011 @@ -65,6 +65,7 @@ virtual void deleteValue(Value *V) {} virtual void copyValue(Value *From, Value *To) {} + virtual void addEscapingUse(Use &U) {} /// getAdjustedAnalysisPointer - This method is used when a pass implements /// an analysis interface through multiple inheritance. If needed, it Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=122787&r1=122786&r2=122787&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Mon Jan 3 17:51:43 2011 @@ -1063,6 +1063,15 @@ if (V->getType()->isPointerTy()) for (unsigned i = 0, e = NewPHIs.size(); i != e; ++i) AA->copyValue(LI, NewPHIs[i]); + + // Now that we've copied information to the new PHIs, scan through + // them again and inform alias analysis that we've added potentially + // escaping uses to any values that are operands to these PHIs. + for (unsigned i = 0, e = NewPHIs.size(); i != e; ++i) { + PHINode *P = NewPHIs[i]; + for (unsigned ii = 0, ee = P->getNumIncomingValues(); ii != ee; ++ii) + AA->addEscapingUse(P->getOperandUse(2*ii)); + } return V; } @@ -1957,8 +1966,16 @@ insert_table(ValNo, Phi, CurrentBlock); CurInst->replaceAllUsesWith(Phi); - if (MD && Phi->getType()->isPointerTy()) - MD->invalidateCachedPointerInfo(Phi); + if (Phi->getType()->isPointerTy()) { + // Because we have added a PHI-use of the pointer value, it has now + // "escaped" from alias analysis' perspective. We need to inform + // AA of this. + for (unsigned ii = 0, ee = Phi->getNumIncomingValues(); ii != ee; ++ii) + VN.getAliasAnalysis()->addEscapingUse(Phi->getOperandUse(2*ii)); + + if (MD) + MD->invalidateCachedPointerInfo(Phi); + } VN.erase(CurInst); erase_table(ValNo, CurInst, CurrentBlock); From resistor at mac.com Mon Jan 3 17:51:56 2011 From: resistor at mac.com (Owen Anderson) Date: Mon, 03 Jan 2011 23:51:56 -0000 Subject: [llvm-commits] [llvm] r122788 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20110103235156.9069E2A6C12C@llvm.org> Author: resistor Date: Mon Jan 3 17:51:56 2011 New Revision: 122788 URL: http://llvm.org/viewvc/llvm-project?rev=122788&view=rev Log: Fix comment. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122788&r1=122787&r2=122788&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Mon Jan 3 17:51:56 2011 @@ -250,7 +250,7 @@ const SCEVConstant *Stride = dyn_cast(StoreEv->getOperand(1)); // TODO: Could also handle negative stride here someday, that will require the - // validity check in mayLoopModRefLocation to be updated though. + // validity check in mayLoopAccessLocation to be updated though. if (Stride == 0 || StoreSize != Stride->getValue()->getValue()) return false; From isanbard at gmail.com Mon Jan 3 17:59:05 2011 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 03 Jan 2011 23:59:05 -0000 Subject: [llvm-commits] [llvm] r122789 - /llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp Message-ID: <20110103235905.554D92A6C12C@llvm.org> Author: void Date: Mon Jan 3 17:59:05 2011 New Revision: 122789 URL: http://llvm.org/viewvc/llvm-project?rev=122789&view=rev Log: Formatting changes. No functionality change. Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp?rev=122789&r1=122788&r2=122789&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp Mon Jan 3 17:59:05 2011 @@ -10,11 +10,6 @@ #include "ARM.h" #include "ARMTargetMachine.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/StringSwitch.h" - #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h" @@ -23,6 +18,11 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegistry.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringSwitch.h" + #include #include @@ -30,93 +30,92 @@ namespace { - class ARMBaseAsmLexer : public TargetAsmLexer { - const MCAsmInfo &AsmInfo; +class ARMBaseAsmLexer : public TargetAsmLexer { + const MCAsmInfo &AsmInfo; - const AsmToken &lexDefinite() { - return getLexer()->Lex(); - } + const AsmToken &lexDefinite() { + return getLexer()->Lex(); + } - AsmToken LexTokenUAL(); - protected: - typedef std::map rmap_ty; - - rmap_ty RegisterMap; - - void InitRegisterMap(const TargetRegisterInfo *info) { - unsigned numRegs = info->getNumRegs(); - - for (unsigned i = 0; i < numRegs; ++i) { - const char *regName = info->getName(i); - if (regName) - RegisterMap[regName] = i; - } + AsmToken LexTokenUAL(); +protected: + typedef std::map rmap_ty; + + rmap_ty RegisterMap; + + void InitRegisterMap(const TargetRegisterInfo *info) { + unsigned numRegs = info->getNumRegs(); + + for (unsigned i = 0; i < numRegs; ++i) { + const char *regName = info->getName(i); + if (regName) + RegisterMap[regName] = i; } + } - unsigned MatchRegisterName(StringRef Name) { - rmap_ty::iterator iter = RegisterMap.find(Name.str()); - if (iter != RegisterMap.end()) - return iter->second; - else - return 0; - } + unsigned MatchRegisterName(StringRef Name) { + rmap_ty::iterator iter = RegisterMap.find(Name.str()); + if (iter != RegisterMap.end()) + return iter->second; + else + return 0; + } - AsmToken LexToken() { - if (!Lexer) { - SetError(SMLoc(), "No MCAsmLexer installed"); - return AsmToken(AsmToken::Error, "", 0); - } - - switch (AsmInfo.getAssemblerDialect()) { - default: - SetError(SMLoc(), "Unhandled dialect"); - return AsmToken(AsmToken::Error, "", 0); - case 0: - return LexTokenUAL(); - } - } - public: - ARMBaseAsmLexer(const Target &T, const MCAsmInfo &MAI) - : TargetAsmLexer(T), AsmInfo(MAI) { + AsmToken LexToken() { + if (!Lexer) { + SetError(SMLoc(), "No MCAsmLexer installed"); + return AsmToken(AsmToken::Error, "", 0); } - }; - class ARMAsmLexer : public ARMBaseAsmLexer { - public: - ARMAsmLexer(const Target &T, const MCAsmInfo &MAI) - : ARMBaseAsmLexer(T, MAI) { - std::string tripleString("arm-unknown-unknown"); - std::string featureString; - OwningPtr - targetMachine(T.createTargetMachine(tripleString, featureString)); - InitRegisterMap(targetMachine->getRegisterInfo()); + switch (AsmInfo.getAssemblerDialect()) { + default: + SetError(SMLoc(), "Unhandled dialect"); + return AsmToken(AsmToken::Error, "", 0); + case 0: + return LexTokenUAL(); } - }; + } +public: + ARMBaseAsmLexer(const Target &T, const MCAsmInfo &MAI) + : TargetAsmLexer(T), AsmInfo(MAI) { + } +}; - class ThumbAsmLexer : public ARMBaseAsmLexer { - public: - ThumbAsmLexer(const Target &T, const MCAsmInfo &MAI) - : ARMBaseAsmLexer(T, MAI) { - std::string tripleString("thumb-unknown-unknown"); - std::string featureString; - OwningPtr - targetMachine(T.createTargetMachine(tripleString, featureString)); - InitRegisterMap(targetMachine->getRegisterInfo()); - } - }; -} +class ARMAsmLexer : public ARMBaseAsmLexer { +public: + ARMAsmLexer(const Target &T, const MCAsmInfo &MAI) + : ARMBaseAsmLexer(T, MAI) { + std::string tripleString("arm-unknown-unknown"); + std::string featureString; + OwningPtr + targetMachine(T.createTargetMachine(tripleString, featureString)); + InitRegisterMap(targetMachine->getRegisterInfo()); + } +}; + +class ThumbAsmLexer : public ARMBaseAsmLexer { +public: + ThumbAsmLexer(const Target &T, const MCAsmInfo &MAI) + : ARMBaseAsmLexer(T, MAI) { + std::string tripleString("thumb-unknown-unknown"); + std::string featureString; + OwningPtr + targetMachine(T.createTargetMachine(tripleString, featureString)); + InitRegisterMap(targetMachine->getRegisterInfo()); + } +}; + +} // end anonymous namespace AsmToken ARMBaseAsmLexer::LexTokenUAL() { const AsmToken &lexedToken = lexDefinite(); switch (lexedToken.getKind()) { - default: - return AsmToken(lexedToken); + default: break; case AsmToken::Error: SetError(Lexer->getErrLoc(), Lexer->getErr()); - return AsmToken(lexedToken); - case AsmToken::Identifier: - { + break; + case AsmToken::Identifier: { std::string upperCase = lexedToken.getString().str(); std::string lowerCase = LowercaseString(upperCase); StringRef lowerRef(lowerCase); @@ -137,19 +136,17 @@ .Default(0); } - if (regID) { + if (regID) return AsmToken(AsmToken::Register, lexedToken.getString(), static_cast(regID)); - } else { - return AsmToken(lexedToken); - } } } + + return AsmToken(lexedToken); } extern "C" void LLVMInitializeARMAsmLexer() { RegisterAsmLexer X(TheARMTarget); RegisterAsmLexer Y(TheThumbTarget); } - From sabre at nondot.org Mon Jan 3 18:06:55 2011 From: sabre at nondot.org (Chris Lattner) Date: Tue, 04 Jan 2011 00:06:55 -0000 Subject: [llvm-commits] [llvm] r122790 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20110104000655.656BA2A6C12C@llvm.org> Author: lattner Date: Mon Jan 3 18:06:55 2011 New Revision: 122790 URL: http://llvm.org/viewvc/llvm-project?rev=122790&view=rev Log: use the very-handy getTruncateOrZeroExtend helper function, and stop setting NSW: signed overflow is possible. Thanks to Dan for pointing these out. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122790&r1=122789&r2=122790&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Mon Jan 3 18:06:55 2011 @@ -349,17 +349,13 @@ // The # stored bytes is (BECount+1)*Size. Expand the trip count out to // pointer size if it isn't already. const Type *IntPtr = TD->getIntPtrType(SI->getContext()); - unsigned BESize = SE->getTypeSizeInBits(BECount->getType()); - if (BESize < TD->getPointerSizeInBits()) - BECount = SE->getZeroExtendExpr(BECount, IntPtr); - else if (BESize > TD->getPointerSizeInBits()) - BECount = SE->getTruncateExpr(BECount, IntPtr); + BECount = SE->getTruncateOrZeroExtend(BECount, IntPtr); const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1), - true, true /*nooverflow*/); + true /*no unsigned overflow*/); if (StoreSize != 1) NumBytesS = SE->getMulExpr(NumBytesS, SE->getConstant(IntPtr, StoreSize), - true, true /*nooverflow*/); + true /*no unsigned overflow*/); Value *NumBytes = Expander.expandCodeFor(NumBytesS, IntPtr, Preheader->getTerminator()); @@ -426,17 +422,13 @@ // The # stored bytes is (BECount+1)*Size. Expand the trip count out to // pointer size if it isn't already. const Type *IntPtr = TD->getIntPtrType(SI->getContext()); - unsigned BESize = SE->getTypeSizeInBits(BECount->getType()); - if (BESize < TD->getPointerSizeInBits()) - BECount = SE->getZeroExtendExpr(BECount, IntPtr); - else if (BESize > TD->getPointerSizeInBits()) - BECount = SE->getTruncateExpr(BECount, IntPtr); + BECount = SE->getTruncateOrZeroExtend(BECount, IntPtr); const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1), - true, true /*nooverflow*/); + true /*no unsigned overflow*/); if (StoreSize != 1) NumBytesS = SE->getMulExpr(NumBytesS, SE->getConstant(IntPtr, StoreSize), - true, true /*nooverflow*/); + true /*no unsigned overflow*/); Value *NumBytes = Expander.expandCodeFor(NumBytesS, IntPtr, Preheader->getTerminator()); From clattner at apple.com Mon Jan 3 18:10:06 2011 From: clattner at apple.com (Chris Lattner) Date: Mon, 3 Jan 2011 16:10:06 -0800 Subject: [llvm-commits] [llvm] r122678 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll In-Reply-To: <153940A7-1A50-43F1-BC87-B6C3B59784C5@apple.com> References: <20110102033756.880E62A6C12C@llvm.org> <153940A7-1A50-43F1-BC87-B6C3B59784C5@apple.com> Message-ID: <4CFB44BA-C62B-43F7-9CF4-E685648A6AEB@apple.com> On Jan 3, 2011, at 3:43 PM, Dan Gohman wrote: > > On Jan 1, 2011, at 7:37 PM, Chris Lattner wrote: >> >> + // The # stored bytes is (BECount+1)*Size. Expand the trip count out to >> + // pointer size if it isn't already. >> + const Type *IntPtr = TD->getIntPtrType(SI->getContext()); >> + unsigned BESize = SE->getTypeSizeInBits(BECount->getType()); >> + if (BESize < TD->getPointerSizeInBits()) >> + BECount = SE->getZeroExtendExpr(BECount, IntPtr); >> + else if (BESize > TD->getPointerSizeInBits()) >> + BECount = SE->getTruncateExpr(BECount, IntPtr); > > This code (and other instances of it) can be simplified using > ScalarEvolution's getTruncateOrZeroExtend. > > Also, truncating is surprising here, though I guess maybe it's safe > since any loop where it would change the value would be iterating > over the entire address space. > >> + >> + const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1), >> + true, true /*nooverflow*/); > > Setting nuw here is surprising, but as above, overflow would mean > the loop is iterating over the entire address space. > > Setting nsw here seems incorrect, as there's no fundamental reason why > iterating over half of the address space is invalid. Great points, fixed in r122790, thanks for the review! -Chris From zwarich at apple.com Mon Jan 3 18:12:46 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 04 Jan 2011 00:12:46 -0000 Subject: [llvm-commits] [llvm] r122791 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Message-ID: <20110104001246.3EBC92A6C12C@llvm.org> Author: zwarich Date: Mon Jan 3 18:12:46 2011 New Revision: 122791 URL: http://llvm.org/viewvc/llvm-project?rev=122791&view=rev Log: Address most of Duncan's review comments. Also, make LoopInstSimplify a simple FunctionPass. It probably doesn't have a reason to be a LoopPass, as it will probably drop the simple fixed point and either use RPO iteration or Duncan's approach in instsimplify of only revisiting instructions that have changed. The next step is to preserve LoopSimplify. This looks like it won't be too hard, although the pass manager doesn't actually seem to respect when non-loop passes claim to preserve LCSSA or LoopSimplify. This will have to be fixed. Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp?rev=122791&r1=122790&r2=122791&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Mon Jan 3 18:12:46 2011 @@ -12,9 +12,11 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "loop-instsimplify" -#include "llvm/Analysis/LoopPass.h" +#include "llvm/Function.h" +#include "llvm/Pass.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Local.h" @@ -24,19 +26,17 @@ STATISTIC(NumSimplified, "Number of redundant instructions simplified"); namespace { - class LoopInstSimplify : public LoopPass { + class LoopInstSimplify : public FunctionPass { public: static char ID; // Pass ID, replacement for typeid - LoopInstSimplify() : LoopPass(ID) { + LoopInstSimplify() : FunctionPass(ID) { initializeLoopInstSimplifyPass(*PassRegistry::getPassRegistry()); } - bool runOnLoop(Loop*, LPPassManager&); + bool runOnFunction(Function&); virtual void getAnalysisUsage(AnalysisUsage& AU) const { AU.setPreservesCFG(); - AU.addRequired(); - AU.addPreserved(); AU.addRequired(); AU.addPreserved(); AU.addPreservedID(LCSSAID); @@ -57,9 +57,9 @@ return new LoopInstSimplify(); } -bool LoopInstSimplify::runOnLoop(Loop* L, LPPassManager& LPM) { - DominatorTree* DT = &getAnalysis(); - const LoopInfo* LI = &getAnalysis(); +bool LoopInstSimplify::runOnFunction(Function& F) { + DominatorTree* DT = getAnalysisIfAvailable(); + LoopInfo* LI = &getAnalysis(); const TargetData* TD = getAnalysisIfAvailable(); bool Changed = false; @@ -67,24 +67,14 @@ do { LocalChanged = false; - SmallPtrSet Visited; - SmallVector VisitStack; - - VisitStack.push_back(L->getHeader()); - - while (!VisitStack.empty()) { - BasicBlock* BB = VisitStack.back(); - VisitStack.pop_back(); - - if (Visited.count(BB)) - continue; - Visited.insert(BB); - - for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { + for (df_iterator DI = df_begin(&F.getEntryBlock()), + DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) + for (BasicBlock::iterator BI = DI->begin(), BE = DI->end(); BI != BE;) { Instruction* I = BI++; // Don't bother simplifying unused instructions. if (!I->use_empty()) { - if (Value* V = SimplifyInstruction(I, TD, DT)) { + Value* V = SimplifyInstruction(I, TD, DT); + if (V && LI->replacementPreservesLCSSAForm(I, V)) { I->replaceAllUsesWith(V); LocalChanged = true; ++NumSimplified; @@ -92,21 +82,9 @@ } LocalChanged |= RecursivelyDeleteTriviallyDeadInstructions(I); } - Changed |= LocalChanged; - DomTreeNode* Node = DT->getNode(BB); - const std::vector& Children = Node->getChildren(); - for (unsigned i = 0; i < Children.size(); ++i) { - // Only visit children that are in the same loop. - BasicBlock* ChildBB = Children[i]->getBlock(); - if (!Visited.count(ChildBB) && LI->getLoopFor(ChildBB) == L) - VisitStack.push_back(ChildBB); - } - } + Changed |= LocalChanged; } while (LocalChanged); - // Nothing that SimplifyInstruction() does should invalidate LCSSA form. - assert(L->isLCSSAForm(*DT)); - return Changed; } From atrick at apple.com Mon Jan 3 18:32:57 2011 From: atrick at apple.com (Andrew Trick) Date: Tue, 04 Jan 2011 00:32:57 -0000 Subject: [llvm-commits] [llvm] r122794 - in /llvm/trunk/lib/Target/ARM: ARMScheduleA9.td ARMSubtarget.cpp Message-ID: <20110104003257.951B52A6C12D@llvm.org> Author: atrick Date: Mon Jan 3 18:32:57 2011 New Revision: 122794 URL: http://llvm.org/viewvc/llvm-project?rev=122794&view=rev Log: Fix the ARM IIC_iCMPsi itinerary and add an important assert. Modified: llvm/trunk/lib/Target/ARM/ARMScheduleA9.td llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp Modified: llvm/trunk/lib/Target/ARM/ARMScheduleA9.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMScheduleA9.td?rev=122794&r1=122793&r2=122794&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMScheduleA9.td (original) +++ llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Mon Jan 3 18:32:57 2011 @@ -123,7 +123,8 @@ InstrItinData, InstrStage<1, [A9_ALU0, A9_ALU1]>], [1, 1], [A9_LdBypass, A9_LdBypass]>, - InstrItinData], + InstrItinData, + InstrStage<2, [A9_ALU0, A9_ALU1]>], [1, 1], [A9_LdBypass, NoBypass]>, InstrItinData, InstrStage<3, [A9_ALU0, A9_ALU1]>], Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp?rev=122794&r1=122793&r2=122794&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp Mon Jan 3 18:32:57 2011 @@ -240,6 +240,7 @@ // clear the lowest bit allStage1Units ^= allStage1Units & ~(allStage1Units - 1); } + assert(InstrItins.IssueWidth <= 2 && "itinerary bug, too many stage 1 units"); } bool ARMSubtarget::enablePostRAScheduler( From resistor at mac.com Mon Jan 3 18:55:21 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 04 Jan 2011 00:55:21 -0000 Subject: [llvm-commits] [llvm] r122795 - /llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp Message-ID: <20110104005522.039642A6C12C@llvm.org> Author: resistor Date: Mon Jan 3 18:55:21 2011 New Revision: 122795 URL: http://llvm.org/viewvc/llvm-project?rev=122795&view=rev Log: Clean up a funky pass registration that got passed over when I got rid of static constructors. Modified: llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp?rev=122795&r1=122794&r2=122795&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp Mon Jan 3 18:55:21 2011 @@ -17,18 +17,12 @@ #include "llvm/CodeGen/MachineModuleInfo.h" using namespace llvm; -// Register this pass with PassInfo directly to avoid having to define -// a default constructor. -static PassInfo -X("Machine Function Analysis", "machine-function-analysis", - &MachineFunctionAnalysis::ID, 0, - /*CFGOnly=*/false, /*is_analysis=*/true); - char MachineFunctionAnalysis::ID = 0; MachineFunctionAnalysis::MachineFunctionAnalysis(const TargetMachine &tm, CodeGenOpt::Level OL) : FunctionPass(ID), TM(tm), OptLevel(OL), MF(0) { + initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry()); } MachineFunctionAnalysis::~MachineFunctionAnalysis() { From greened at obbligato.org Mon Jan 3 19:05:30 2011 From: greened at obbligato.org (David Greene) Date: Tue, 04 Jan 2011 01:05:30 -0000 Subject: [llvm-commits] [llvm] r122796 - /llvm/trunk/test/lit.cfg Message-ID: <20110104010530.D1A832A6C12C@llvm.org> Author: greened Date: Mon Jan 3 19:05:30 2011 New Revision: 122796 URL: http://llvm.org/viewvc/llvm-project?rev=122796&view=rev Log: Don't pattern match "/clang" so we don't mangle directory names. Some tests use absolute paths to clang. Modified: llvm/trunk/test/lit.cfg Modified: llvm/trunk/test/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=122796&r1=122795&r2=122796&view=diff ============================================================================== --- llvm/trunk/test/lit.cfg (original) +++ llvm/trunk/test/lit.cfg Mon Jan 3 19:05:30 2011 @@ -156,7 +156,8 @@ # includes every tool placed in $(LLVM_OBJ_ROOT)/$(BuildMode)/bin # (llvm_tools_dir in lit parlance). # Don't match 'bugpoint-' or 'clang-'. -for pattern in [r"\bbugpoint\b(?!-)", r"\bclang\b(?!-)", + # Don't match '/clang'. +for pattern in [r"\bbugpoint\b(?!-)", r"(? References: <20110104005522.039642A6C12C@llvm.org> Message-ID: On Jan 3, 2011, at 4:55 PM, Owen Anderson wrote: > Author: resistor > Date: Mon Jan 3 18:55:21 2011 > New Revision: 122795 > > URL: http://llvm.org/viewvc/llvm-project?rev=122795&view=rev > Log: > Clean up a funky pass registration that got passed over when I got rid of static constructors. The pass still shows up as "Unnamed pass: implement Pass::getPassName()". Don't you still need to add the INITIALIZE* macros, or implement getPassName()? /jakob From bob.wilson at apple.com Mon Jan 3 19:28:16 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 04 Jan 2011 01:28:16 -0000 Subject: [llvm-commits] [test-suite] r122798 - /test-suite/trunk/SingleSource/Regression/C++/EH/Makefile Message-ID: <20110104012816.9EB092A6C12C@llvm.org> Author: bwilson Date: Mon Jan 3 19:28:16 2011 New Revision: 122798 URL: http://llvm.org/viewvc/llvm-project?rev=122798&view=rev Log: Temporarily disable SingleSource/Regression/C++/EH/inlined_cleanup for ARM/Darwin. It had been failing in a harmless way but for some reason it is now crashing my testers. Modified: test-suite/trunk/SingleSource/Regression/C++/EH/Makefile Modified: test-suite/trunk/SingleSource/Regression/C++/EH/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Regression/C%2B%2B/EH/Makefile?rev=122798&r1=122797&r2=122798&view=diff ============================================================================== --- test-suite/trunk/SingleSource/Regression/C++/EH/Makefile (original) +++ test-suite/trunk/SingleSource/Regression/C++/EH/Makefile Mon Jan 3 19:28:16 2011 @@ -1,6 +1,14 @@ LEVEL = ../../../.. REQUIRES_EH_SUPPORT = 1 +# Temporarily skip inlined_cleanup on ARM/Darwin. Radar 8411222 +include $(LEVEL)/Makefile.config +ifeq ($(ARCH),ARM) +ifeq ($(TARGET_OS),Darwin) +PROGRAMS_TO_SKIP := inlined_cleanup +endif +endif + CFLAGS += -std=c99 LDFLAGS += -lstdc++ include $(LEVEL)/SingleSource/Makefile.singlesrc From clattner at apple.com Mon Jan 3 19:58:01 2011 From: clattner at apple.com (Chris Lattner) Date: Mon, 3 Jan 2011 17:58:01 -0800 Subject: [llvm-commits] [llvm] r122791 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp In-Reply-To: <20110104001246.3EBC92A6C12C@llvm.org> References: <20110104001246.3EBC92A6C12C@llvm.org> Message-ID: <32892E36-5659-43D1-B3DB-18154819B2A6@apple.com> On Jan 3, 2011, at 4:12 PM, Cameron Zwarich wrote: > Author: zwarich > Date: Mon Jan 3 18:12:46 2011 > New Revision: 122791 > > URL: http://llvm.org/viewvc/llvm-project?rev=122791&view=rev > Log: > Address most of Duncan's review comments. Also, make LoopInstSimplify a simple > FunctionPass. It probably doesn't have a reason to be a LoopPass, as it will > probably drop the simple fixed point and either use RPO iteration or Duncan's > approach in instsimplify of only revisiting instructions that have changed. Hi Cameron, If it's not a loop pass, it won't be pipelined along with the other loop passes, right? -Chris > > The next step is to preserve LoopSimplify. This looks like it won't be too hard, > although the pass manager doesn't actually seem to respect when non-loop passes > claim to preserve LCSSA or LoopSimplify. This will have to be fixed. > > Modified: > llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp > > Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp?rev=122791&r1=122790&r2=122791&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Mon Jan 3 18:12:46 2011 > @@ -12,9 +12,11 @@ > //===----------------------------------------------------------------------===// > > #define DEBUG_TYPE "loop-instsimplify" > -#include "llvm/Analysis/LoopPass.h" > +#include "llvm/Function.h" > +#include "llvm/Pass.h" > #include "llvm/Analysis/Dominators.h" > #include "llvm/Analysis/InstructionSimplify.h" > +#include "llvm/Analysis/LoopInfo.h" > #include "llvm/Target/TargetData.h" > #include "llvm/Transforms/Scalar.h" > #include "llvm/Transforms/Utils/Local.h" > @@ -24,19 +26,17 @@ > STATISTIC(NumSimplified, "Number of redundant instructions simplified"); > > namespace { > - class LoopInstSimplify : public LoopPass { > + class LoopInstSimplify : public FunctionPass { > public: > static char ID; // Pass ID, replacement for typeid > - LoopInstSimplify() : LoopPass(ID) { > + LoopInstSimplify() : FunctionPass(ID) { > initializeLoopInstSimplifyPass(*PassRegistry::getPassRegistry()); > } > > - bool runOnLoop(Loop*, LPPassManager&); > + bool runOnFunction(Function&); > > virtual void getAnalysisUsage(AnalysisUsage& AU) const { > AU.setPreservesCFG(); > - AU.addRequired(); > - AU.addPreserved(); > AU.addRequired(); > AU.addPreserved(); > AU.addPreservedID(LCSSAID); > @@ -57,9 +57,9 @@ > return new LoopInstSimplify(); > } > > -bool LoopInstSimplify::runOnLoop(Loop* L, LPPassManager& LPM) { > - DominatorTree* DT = &getAnalysis(); > - const LoopInfo* LI = &getAnalysis(); > +bool LoopInstSimplify::runOnFunction(Function& F) { > + DominatorTree* DT = getAnalysisIfAvailable(); > + LoopInfo* LI = &getAnalysis(); > const TargetData* TD = getAnalysisIfAvailable(); > > bool Changed = false; > @@ -67,24 +67,14 @@ > do { > LocalChanged = false; > > - SmallPtrSet Visited; > - SmallVector VisitStack; > - > - VisitStack.push_back(L->getHeader()); > - > - while (!VisitStack.empty()) { > - BasicBlock* BB = VisitStack.back(); > - VisitStack.pop_back(); > - > - if (Visited.count(BB)) > - continue; > - Visited.insert(BB); > - > - for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { > + for (df_iterator DI = df_begin(&F.getEntryBlock()), > + DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) > + for (BasicBlock::iterator BI = DI->begin(), BE = DI->end(); BI != BE;) { > Instruction* I = BI++; > // Don't bother simplifying unused instructions. > if (!I->use_empty()) { > - if (Value* V = SimplifyInstruction(I, TD, DT)) { > + Value* V = SimplifyInstruction(I, TD, DT); > + if (V && LI->replacementPreservesLCSSAForm(I, V)) { > I->replaceAllUsesWith(V); > LocalChanged = true; > ++NumSimplified; > @@ -92,21 +82,9 @@ > } > LocalChanged |= RecursivelyDeleteTriviallyDeadInstructions(I); > } > - Changed |= LocalChanged; > > - DomTreeNode* Node = DT->getNode(BB); > - const std::vector& Children = Node->getChildren(); > - for (unsigned i = 0; i < Children.size(); ++i) { > - // Only visit children that are in the same loop. > - BasicBlock* ChildBB = Children[i]->getBlock(); > - if (!Visited.count(ChildBB) && LI->getLoopFor(ChildBB) == L) > - VisitStack.push_back(ChildBB); > - } > - } > + Changed |= LocalChanged; > } while (LocalChanged); > > - // Nothing that SimplifyInstruction() does should invalidate LCSSA form. > - assert(L->isLCSSAForm(*DT)); > - > return Changed; > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From zwarich at apple.com Mon Jan 3 20:54:43 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 3 Jan 2011 18:54:43 -0800 Subject: [llvm-commits] [llvm] r122791 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp In-Reply-To: <32892E36-5659-43D1-B3DB-18154819B2A6@apple.com> References: <20110104001246.3EBC92A6C12C@llvm.org> <32892E36-5659-43D1-B3DB-18154819B2A6@apple.com> Message-ID: On Jan 3, 2011, at 5:58 PM, Chris Lattner wrote: > On Jan 3, 2011, at 4:12 PM, Cameron Zwarich wrote: > >> Author: zwarich >> Date: Mon Jan 3 18:12:46 2011 >> New Revision: 122791 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122791&view=rev >> Log: >> Address most of Duncan's review comments. Also, make LoopInstSimplify a simple >> FunctionPass. It probably doesn't have a reason to be a LoopPass, as it will >> probably drop the simple fixed point and either use RPO iteration or Duncan's >> approach in instsimplify of only revisiting instructions that have changed. > > Hi Cameron, > > If it's not a loop pass, it won't be pipelined along with the other loop passes, right? That's correct, but ScalarEvolution runs right after instcombine here and also breaks the loop pass pipelining, so we'll need to solve that problem there too. As long as ScalarEvolution breaks loop pass pipelining, there isn't really much gained from running LoopInstSimplify as a loop pass. If both LoopInstSimplify and ScalarEvolution preserve LoopSimplify and LCSSA (even as function passes rather than loop passes), shouldn't the loop pass manager skip recomputing them? Or is there something I am missing? Cameron From zwarich at apple.com Mon Jan 3 22:43:31 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 04 Jan 2011 04:43:31 -0000 Subject: [llvm-commits] [llvm] r122801 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <20110104044331.3BD3E2A6C12C@llvm.org> Author: zwarich Date: Mon Jan 3 22:43:31 2011 New Revision: 122801 URL: http://llvm.org/viewvc/llvm-project?rev=122801&view=rev Log: Avoid finding loop back edges when we are not splitting critical edges in CodeGenPrepare (which is the default behavior). Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=122801&r1=122800&r2=122801&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Mon Jan 3 22:43:31 2011 @@ -119,8 +119,10 @@ // unconditional branch. EverMadeChange |= EliminateMostlyEmptyBlocks(F); - // Now find loop back edges. - findLoopBackEdges(F); + // Now find loop back edges, but only if they are being used to decide which + // critical edges to split. + if (CriticalEdgeSplit) + findLoopBackEdges(F); bool MadeChange = true; while (MadeChange) { From grosser at fim.uni-passau.de Mon Jan 3 22:52:16 2011 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Mon, 03 Jan 2011 23:52:16 -0500 Subject: [llvm-commits] [PATCH] Fix: instcombine does not get max if hidden by sext Message-ID: <4D22A780.6060209@fim.uni-passau.de> Hi, I fixed a recent bug report, that blocked me on a large FORTRAN test case: InstCombine: X = sext x ; x < c ? X : C-1 --> X = sext x; X > C-1 ? C-1 : X Instead of calculating this with mixed types promote all to the larger type. This enables scalar evolution to analyze this expression. PR8866 OK for commit? Tobi -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-InstCombine.patch Type: text/x-diff Size: 6359 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110103/ee687fc0/attachment.bin From stoklund at 2pi.dk Mon Jan 3 23:29:12 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 3 Jan 2011 21:29:12 -0800 Subject: [llvm-commits] [llvm] r122801 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: <20110104044331.3BD3E2A6C12C@llvm.org> References: <20110104044331.3BD3E2A6C12C@llvm.org> Message-ID: <26A75B47-71D0-4125-B7FB-8FF965D0EB70@2pi.dk> On Jan 3, 2011, at 8:43 PM, Cameron Zwarich wrote: > Author: zwarich > Date: Mon Jan 3 22:43:31 2011 > New Revision: 122801 > > URL: http://llvm.org/viewvc/llvm-project?rev=122801&view=rev > Log: > Avoid finding loop back edges when we are not splitting critical edges in > CodeGenPrepare (which is the default behavior). Thanks, Cameron. I noticed that there are a number of local DenseMap instances as well. It may be worthwhile to promote them to class members to avoid repeated allocations. DenseMap SunkAddrs; DenseMap InsertedTruncs; These two are in static functions that would have to be promoted to methods: DenseMap InsertedCasts; DenseMap InsertedCmps; It seems like a good idea to avoid allocating and freeing a DenseMap for every bitcast and cmp instruction. 403.gcc has 157000 of those. Is the fix-point loop in CodeGenPrepare still necessary? When critical edge splitting is disabled? /jakob -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110103/688f17e3/attachment.bin From zwarich at apple.com Mon Jan 3 23:42:39 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 3 Jan 2011 21:42:39 -0800 Subject: [llvm-commits] [llvm] r122801 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: <26A75B47-71D0-4125-B7FB-8FF965D0EB70@2pi.dk> References: <20110104044331.3BD3E2A6C12C@llvm.org> <26A75B47-71D0-4125-B7FB-8FF965D0EB70@2pi.dk> Message-ID: On Jan 3, 2011, at 9:29 PM, Jakob Stoklund Olesen wrote: > On Jan 3, 2011, at 8:43 PM, Cameron Zwarich wrote: > >> Author: zwarich >> Date: Mon Jan 3 22:43:31 2011 >> New Revision: 122801 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122801&view=rev >> Log: >> Avoid finding loop back edges when we are not splitting critical edges in >> CodeGenPrepare (which is the default behavior). > > Thanks, Cameron. > > I noticed that there are a number of local DenseMap instances as well. It may be worthwhile to promote them to class members to avoid repeated allocations. > > DenseMap SunkAddrs; > DenseMap InsertedTruncs; > > These two are in static functions that would have to be promoted to methods: > > DenseMap InsertedCasts; > DenseMap InsertedCmps; > > It seems like a good idea to avoid allocating and freeing a DenseMap for every bitcast and cmp instruction. 403.gcc has 157000 of those. Good idea. I'll test that now. It's a bit annoying that you can't rely on RAII with all of these early returns, but I guess we could have a little .clear() helper RAII object. ;-) > Is the fix-point loop in CodeGenPrepare still necessary? When critical edge splitting is disabled? I've just been running some experiments on this. The fixed point loop is probably necessary for the 'ext' optimizations, as a lot of 'ext' casts get optimized after other instructions have been sunk into their block. On all of test-suite + SPEC2000 & SPEC2006, there are only 4 noop copies optimized in a later iteration (these don't really matter as they will be eliminated by the coalescer later), but there are 15 memory instructions that have their addressing code sunk into their BB in a later iteration. I was thinking of just iterating the ext optimizations afterwards, possibly based on a worklist, but it would be nice to know why these memory instructions have sinkable addressing code after the first iteration. As an aside, I tried adding another pass of CFG optimizations (which is probably not there because it would reverse the critical edge splitting), and it merges a decent number of extra blocks. Cameron From clattner at apple.com Tue Jan 4 00:06:14 2011 From: clattner at apple.com (Chris Lattner) Date: Mon, 3 Jan 2011 22:06:14 -0800 Subject: [llvm-commits] [llvm] r122791 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp In-Reply-To: References: <20110104001246.3EBC92A6C12C@llvm.org> <32892E36-5659-43D1-B3DB-18154819B2A6@apple.com> Message-ID: <16510DCB-A027-458E-8C02-E46941B7DDD3@apple.com> On Jan 3, 2011, at 6:54 PM, Cameron Zwarich wrote: > On Jan 3, 2011, at 5:58 PM, Chris Lattner wrote: > >> On Jan 3, 2011, at 4:12 PM, Cameron Zwarich wrote: >> >>> Author: zwarich >>> Date: Mon Jan 3 18:12:46 2011 >>> New Revision: 122791 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=122791&view=rev >>> Log: >>> Address most of Duncan's review comments. Also, make LoopInstSimplify a simple >>> FunctionPass. It probably doesn't have a reason to be a LoopPass, as it will >>> probably drop the simple fixed point and either use RPO iteration or Duncan's >>> approach in instsimplify of only revisiting instructions that have changed. >> >> Hi Cameron, >> >> If it's not a loop pass, it won't be pipelined along with the other loop passes, right? > > That's correct, but ScalarEvolution runs right after instcombine here and also breaks the loop pass pipelining, so we'll need to solve that problem there too. As long as ScalarEvolution breaks loop pass pipelining, there isn't really much gained from running LoopInstSimplify as a loop pass. > > If both LoopInstSimplify and ScalarEvolution preserve LoopSimplify and LCSSA (even as function passes rather than loop passes), shouldn't the loop pass manager skip recomputing them? Or is there something I am missing? ScalarEvolution is an analysis, not a transformation, so it should trivially preserve LCSSA. The right long term fix (IMO) is for all the loop passes to preserve ScalarEvolution. This will cause the passmgr to run ScalarEvolution before all of the loop passes, then the loop passes can all be pipelined naturally. -Chris From stoklund at 2pi.dk Tue Jan 4 00:10:19 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 3 Jan 2011 22:10:19 -0800 Subject: [llvm-commits] [llvm] r122801 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: References: <20110104044331.3BD3E2A6C12C@llvm.org> <26A75B47-71D0-4125-B7FB-8FF965D0EB70@2pi.dk> Message-ID: <1CC24B63-4E25-4134-B9D4-D213A19001B6@2pi.dk> On Jan 3, 2011, at 9:42 PM, Cameron Zwarich wrote: > On Jan 3, 2011, at 9:29 PM, Jakob Stoklund Olesen wrote: >> >> It seems like a good idea to avoid allocating and freeing a DenseMap for every bitcast and cmp instruction. 403.gcc has 157000 of those. > > Good idea. I'll test that now. It's a bit annoying that you can't rely on RAII with all of these early returns, but I guess we could have a little .clear() helper RAII object. ;-) Don't bother. Just clear the maps before using them instead of after. Nobody will notice. Note that 3 of the maps can share a single DenseMap. >> Is the fix-point loop in CodeGenPrepare still necessary? When critical edge splitting is disabled? > > I've just been running some experiments on this. The fixed point loop is probably necessary for the 'ext' optimizations, as a lot of 'ext' casts get optimized after other instructions have been sunk into their block. On all of test-suite + SPEC2000 & SPEC2006, there are only 4 noop copies optimized in a later iteration (these don't really matter as they will be eliminated by the coalescer later), but there are 15 memory instructions that have their addressing code sunk into their BB in a later iteration. I was thinking of just iterating the ext optimizations afterwards, possibly based on a worklist, but it would be nice to know why these memory instructions have sinkable addressing code after the first iteration. It is probably chained bitcast / ext / gep instructions getting lowered one at a time. If that is the case, you could probably get away with iterating over each basic block separately instead of re-checking the whole function. That assumes that the chains to be lowered already were in the same basic block. I have no idea if that is generally true. It would be safer and faster to add the operands of lowered instructions to a work list, but that is a bit more work to implement. > As an aside, I tried adding another pass of CFG optimizations (which is probably not there because it would reverse the critical edge splitting), and it merges a decent number of extra blocks. That makes sense. I see critical edge splitting during register allocation in our future ;-) /jakob -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110103/38b67038/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110103/38b67038/attachment.bin From zwarich at apple.com Tue Jan 4 00:42:27 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 04 Jan 2011 06:42:27 -0000 Subject: [llvm-commits] [llvm] r122803 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <20110104064227.D83E12A6C12C@llvm.org> Author: zwarich Date: Tue Jan 4 00:42:27 2011 New Revision: 122803 URL: http://llvm.org/viewvc/llvm-project?rev=122803&view=rev Log: Eliminate repeated allocation of a per-BB DenseMap for a 4.6% reduction of time spent in StrongPHIElimination on 403.gcc. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122803&r1=122802&r2=122803&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Tue Jan 4 00:42:27 2011 @@ -144,6 +144,10 @@ // sources. DenseMap > PHISrcDefs; + // Maps a color to a pair of a MachineInstr* and a virtual register, which + // is the operand of that PHI corresponding to the current basic block. + DenseMap > CurrentPHIForColor; + // FIXME: Can these two data structures be combined? Would a std::multimap // be any better? @@ -567,12 +571,7 @@ // the predecessor block. The def of a PHI's destination register is processed // along with the other defs in a basic block. - // The map CurrentPHIForColor maps a color to a pair of a MachineInstr* and a - // virtual register, which is the operand of that PHI corresponding to the - // current basic block. - // FIXME: This should use a container that doesn't always perform heap - // allocation. - DenseMap > CurrentPHIForColor; + CurrentPHIForColor.clear(); for (MachineBasicBlock::succ_iterator SI = MBB.succ_begin(), SE = MBB.succ_end(); SI != SE; ++SI) { From sabre at nondot.org Tue Jan 4 01:27:30 2011 From: sabre at nondot.org (Chris Lattner) Date: Tue, 04 Jan 2011 07:27:30 -0000 Subject: [llvm-commits] [llvm] r122805 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20110104072731.021AD2A6C12C@llvm.org> Author: lattner Date: Tue Jan 4 01:27:30 2011 New Revision: 122805 URL: http://llvm.org/viewvc/llvm-project?rev=122805&view=rev Log: restructure this a bit. Initialize the WeakVH with "I", the instruction *after* the store. The store will always be deleted if the transformation kicks in, so we'd do an N^2 scan of every loop block. Whoops. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122805&r1=122804&r2=122805&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Tue Jan 4 01:27:30 2011 @@ -207,19 +207,22 @@ bool MadeChange = false; for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { - // Look for store instructions, which may be memsets. - StoreInst *SI = dyn_cast(I++); - if (SI == 0 || SI->isVolatile()) continue; + Instruction *Inst = I++; + // Look for store instructions, which may be optimized to memset/memcpy. + if (StoreInst *SI = dyn_cast(Inst)) { + if (SI->isVolatile()) continue; - WeakVH InstPtr(SI); - if (!processLoopStore(SI, BECount)) continue; + WeakVH InstPtr(I); + if (!processLoopStore(SI, BECount)) continue; + MadeChange = true; + + // If processing the store invalidated our iterator, start over from the + // head of the loop. + if (InstPtr == 0) + I = BB->begin(); + continue; + } - MadeChange = true; - - // If processing the store invalidated our iterator, start over from the - // head of the loop. - if (InstPtr == 0) - I = BB->begin(); } return MadeChange; From sabre at nondot.org Tue Jan 4 01:46:34 2011 From: sabre at nondot.org (Chris Lattner) Date: Tue, 04 Jan 2011 07:46:34 -0000 Subject: [llvm-commits] [llvm] r122806 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll Message-ID: <20110104074634.2EA702A6C12C@llvm.org> Author: lattner Date: Tue Jan 4 01:46:33 2011 New Revision: 122806 URL: http://llvm.org/viewvc/llvm-project?rev=122806&view=rev Log: Teach loop-idiom to turn a loop containing a memset into a larger memset when safe. The testcase is basically this nested loop: void foo(char *X) { for (int i = 0; i != 100; ++i) for (int j = 0; j != 100; ++j) X[j+i*100] = 0; } which gets turned into a single memset now. clang -O3 doesn't optimize this yet though due to a phase ordering issue I haven't analyzed yet. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp llvm/trunk/test/Transforms/LoopIdiom/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=122806&r1=122805&r2=122806&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Tue Jan 4 01:46:33 2011 @@ -39,6 +39,7 @@ #define DEBUG_TYPE "loop-idiom" #include "llvm/Transforms/Scalar.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" @@ -72,9 +73,11 @@ SmallVectorImpl &ExitBlocks); bool processLoopStore(StoreInst *SI, const SCEV *BECount); + bool processLoopMemSet(MemSetInst *MSI, const SCEV *BECount); - bool processLoopStoreOfSplatValue(StoreInst *SI, unsigned StoreSize, - Value *SplatValue, + bool processLoopStoreOfSplatValue(Value *DestPtr, unsigned StoreSize, + unsigned StoreAlignment, + Value *SplatValue, Instruction *TheStore, const SCEVAddRecExpr *Ev, const SCEV *BECount); bool processLoopStoreOfLoopLoad(StoreInst *SI, unsigned StoreSize, @@ -210,27 +213,39 @@ Instruction *Inst = I++; // Look for store instructions, which may be optimized to memset/memcpy. if (StoreInst *SI = dyn_cast(Inst)) { - if (SI->isVolatile()) continue; - WeakVH InstPtr(I); if (!processLoopStore(SI, BECount)) continue; MadeChange = true; // If processing the store invalidated our iterator, start over from the - // head of the loop. + // top of the block. if (InstPtr == 0) I = BB->begin(); continue; } + // Look for memset instructions, which may be optimized to a larger memset. + if (MemSetInst *MSI = dyn_cast(Inst)) { + WeakVH InstPtr(I); + if (!processLoopMemSet(MSI, BECount)) continue; + MadeChange = true; + + // If processing the memset invalidated our iterator, start over from the + // top of the block. + if (InstPtr == 0) + I = BB->begin(); + continue; + } } return MadeChange; } -/// scanBlock - Look over a block to see if we can promote anything out of it. +/// processLoopStore - See if this store can be promoted to a memset or memcpy. bool LoopIdiomRecognize::processLoopStore(StoreInst *SI, const SCEV *BECount) { + if (SI->isVolatile()) return false; + Value *StoredVal = SI->getValueOperand(); Value *StorePtr = SI->getPointerOperand(); @@ -261,8 +276,8 @@ // turned into a memset of i8 -1, assuming that all the consequtive bytes // are stored. A store of i32 0x01020304 can never be turned into a memset. if (Value *SplatValue = isBytewiseValue(StoredVal)) - if (processLoopStoreOfSplatValue(SI, StoreSize, SplatValue, StoreEv, - BECount)) + if (processLoopStoreOfSplatValue(StorePtr, StoreSize, SI->getAlignment(), + SplatValue, SI, StoreEv, BECount)) return true; // If the stored value is a strided load in the same loop with the same stride @@ -281,13 +296,48 @@ return false; } +/// processLoopMemSet - See if this memset can be promoted to a large memset. +bool LoopIdiomRecognize:: +processLoopMemSet(MemSetInst *MSI, const SCEV *BECount) { + // We can only handle non-volatile memsets with a constant size. + if (MSI->isVolatile() || !isa(MSI->getLength())) return false; + + Value *Pointer = MSI->getDest(); + + // See if the pointer expression is an AddRec like {base,+,1} on the current + // loop, which indicates a strided store. If we have something else, it's a + // random store we can't handle. + const SCEVAddRecExpr *Ev = dyn_cast(SE->getSCEV(Pointer)); + if (Ev == 0 || Ev->getLoop() != CurLoop || !Ev->isAffine()) + return false; + + // Reject memsets that are so large that they overflow an unsigned. + uint64_t SizeInBytes = cast(MSI->getLength())->getZExtValue(); + if ((SizeInBytes >> 32) != 0) + return false; + + // Check to see if the stride matches the size of the memset. If so, then we + // know that every byte is touched in the loop. + const SCEVConstant *Stride = dyn_cast(Ev->getOperand(1)); + + // TODO: Could also handle negative stride here someday, that will require the + // validity check in mayLoopAccessLocation to be updated though. + if (Stride == 0 || MSI->getLength() != Stride->getValue()) + return false; + + return processLoopStoreOfSplatValue(Pointer, (unsigned)SizeInBytes, + MSI->getAlignment(), MSI->getValue(), + MSI, Ev, BECount); +} + + /// mayLoopAccessLocation - Return true if the specified loop might access the /// specified pointer location, which is a loop-strided access. The 'Access' /// argument specifies what the verboten forms of access are (read or write). static bool mayLoopAccessLocation(Value *Ptr,AliasAnalysis::ModRefResult Access, Loop *L, const SCEV *BECount, unsigned StoreSize, AliasAnalysis &AA, - StoreInst *IgnoredStore) { + Instruction *IgnoredStore) { // Get the location that may be stored across the loop. Since the access is // strided positively through memory, we say that the modified location starts // at the pointer and has infinite size. @@ -317,8 +367,9 @@ /// processLoopStoreOfSplatValue - We see a strided store of a memsetable value. /// If we can transform this into a memset in the loop preheader, do so. bool LoopIdiomRecognize:: -processLoopStoreOfSplatValue(StoreInst *SI, unsigned StoreSize, - Value *SplatValue, +processLoopStoreOfSplatValue(Value *DestPtr, unsigned StoreSize, + unsigned StoreAlignment, Value *SplatValue, + Instruction *TheStore, const SCEVAddRecExpr *Ev, const SCEV *BECount) { // Verify that the stored value is loop invariant. If not, we can't promote // the memset. @@ -329,9 +380,9 @@ // this into a memset in the loop preheader now if we want. However, this // would be unsafe to do if there is anything else in the loop that may read // or write to the aliased location. Check for an alias. - if (mayLoopAccessLocation(SI->getPointerOperand(), AliasAnalysis::ModRef, + if (mayLoopAccessLocation(DestPtr, AliasAnalysis::ModRef, CurLoop, BECount, - StoreSize, getAnalysis(), SI)) + StoreSize, getAnalysis(), TheStore)) return false; // Okay, everything looks good, insert the memset. @@ -344,14 +395,14 @@ // header. Just insert code for it in the preheader. SCEVExpander Expander(*SE); - unsigned AddrSpace = SI->getPointerAddressSpace(); + unsigned AddrSpace = cast(DestPtr->getType())->getAddressSpace(); Value *BasePtr = Expander.expandCodeFor(Ev->getStart(), Builder.getInt8PtrTy(AddrSpace), Preheader->getTerminator()); // The # stored bytes is (BECount+1)*Size. Expand the trip count out to // pointer size if it isn't already. - const Type *IntPtr = TD->getIntPtrType(SI->getContext()); + const Type *IntPtr = TD->getIntPtrType(SplatValue->getContext()); BECount = SE->getTruncateOrZeroExtend(BECount, IntPtr); const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1), @@ -364,15 +415,15 @@ Expander.expandCodeFor(NumBytesS, IntPtr, Preheader->getTerminator()); Value *NewCall = - Builder.CreateMemSet(BasePtr, SplatValue, NumBytes, SI->getAlignment()); + Builder.CreateMemSet(BasePtr, SplatValue, NumBytes, StoreAlignment); DEBUG(dbgs() << " Formed memset: " << *NewCall << "\n" - << " from store to: " << *Ev << " at: " << *SI << "\n"); + << " from store to: " << *Ev << " at: " << *TheStore << "\n"); (void)NewCall; // Okay, the memset has been formed. Zap the original store and anything that // feeds into it. - DeleteDeadInstruction(SI, *SE); + DeleteDeadInstruction(TheStore, *SE); ++NumMemSet; return true; } Modified: llvm/trunk/test/Transforms/LoopIdiom/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/basic.ll?rev=122806&r1=122805&r2=122806&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIdiom/basic.ll (original) +++ llvm/trunk/test/Transforms/LoopIdiom/basic.ll Tue Jan 4 01:46:33 2011 @@ -240,3 +240,36 @@ ; CHECK: ret void } +; Two dimensional nested loop should be promoted to one big memset. +define void @test10(i8* %X) nounwind ssp { +entry: + br label %bb.nph + +bb.nph: ; preds = %entry, %for.inc10 + %i.04 = phi i32 [ 0, %entry ], [ %inc12, %for.inc10 ] + br label %for.body5 + +for.body5: ; preds = %for.body5, %bb.nph + %j.02 = phi i32 [ 0, %bb.nph ], [ %inc, %for.body5 ] + %mul = mul nsw i32 %i.04, 100 + %add = add nsw i32 %j.02, %mul + %idxprom = sext i32 %add to i64 + %arrayidx = getelementptr inbounds i8* %X, i64 %idxprom + store i8 0, i8* %arrayidx, align 1 + %inc = add nsw i32 %j.02, 1 + %cmp4 = icmp eq i32 %inc, 100 + br i1 %cmp4, label %for.inc10, label %for.body5 + +for.inc10: ; preds = %for.body5 + %inc12 = add nsw i32 %i.04, 1 + %cmp = icmp eq i32 %inc12, 100 + br i1 %cmp, label %for.end13, label %bb.nph + +for.end13: ; preds = %for.inc10 + ret void +; CHECK: @test10 +; CHECK: entry: +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %X, i8 0, i64 10000, i32 1, i1 false) +; CHECK-NOT: store +; CHECK: ret void +} From baldrick at free.fr Tue Jan 4 02:20:19 2011 From: baldrick at free.fr (Duncan Sands) Date: Tue, 04 Jan 2011 09:20:19 +0100 Subject: [llvm-commits] [llvm] r122791 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp In-Reply-To: <20110104001246.3EBC92A6C12C@llvm.org> References: <20110104001246.3EBC92A6C12C@llvm.org> Message-ID: <4D22D843.1030706@free.fr> Hi Cameron, > Address most of Duncan's review comments. Also, make LoopInstSimplify a simple > FunctionPass. It probably doesn't have a reason to be a LoopPass, as it will > probably drop the simple fixed point and either use RPO iteration or Duncan's > approach in instsimplify of only revisiting instructions that have changed. > > The next step is to preserve LoopSimplify. This looks like it won't be too hard, > although the pass manager doesn't actually seem to respect when non-loop passes > claim to preserve LCSSA or LoopSimplify. This will have to be fixed. as far as I can see the pass is now identical to instsimplify, only it preserves LCSSA form. In that case, why not delete the pass and teach instsimplify to preserve LCSSA form if it detects the presence of the LCSSA analysis? However I think Chris is right and you should go back to having this be a loop pass. Ciao, Duncan. From baldrick at free.fr Tue Jan 4 03:02:11 2011 From: baldrick at free.fr (Duncan Sands) Date: Tue, 04 Jan 2011 10:02:11 +0100 Subject: [llvm-commits] [llvm] r122704 - in /llvm/trunk: lib/Transforms/Scalar/LoopIdiomRecognize.cpp test/Transforms/LoopIdiom/basic.ll In-Reply-To: <2C5B6D79-D5B9-4ED8-999E-1471C2A9FD79@apple.com> References: <20110102190103.6EECD2A6C12C@llvm.org> <4D2195BD.5000402@free.fr> <2C5B6D79-D5B9-4ED8-999E-1471C2A9FD79@apple.com> Message-ID: <4D22E213.7090801@free.fr> Hi Chris, ... >> In both functions the memset could also take care of the store to the first >> element, rather than starting from the second element. However maybe merging >> the store and the memset should be a job for a different pass. > > It's likely that this should be done by memcpy opt, which has logic for merging multiple consecutive stores into a memset. OK. >> Secondly, notice that the size of the memset in the second function is -4. >> Hopefully this will work correctly (i.e. memset 2^32-4 values)! It did make >> me wonder what happens if the loop stores say 2^32 or 2^48 values. Presumably >> the type of the memset size argument is automagically set to a size that can >> hold the loop trip count... > > I don't understand what you're saying here... is there a miscompilation, or was the original code doing this large store? -4 is "a big 32-bit number" and is zero extended to i64 on 64-bit targets. No miscompilation, 2^32-4 is correct. I took a look at the loopidiom code and it gets the type of the memset size operand from the SCEV type, so it should always be big enough, i.e. there is no problem here, sorry to have bothered you about it. Ciao, Duncan. From pichet2000 at gmail.com Tue Jan 4 04:23:42 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Tue, 04 Jan 2011 10:23:42 -0000 Subject: [llvm-commits] [llvm] r122808 - /llvm/trunk/utils/lit/lit/TestRunner.py Message-ID: <20110104102342.95C5F2A6C12C@llvm.org> Author: fpichet Date: Tue Jan 4 04:23:42 2011 New Revision: 122808 URL: http://llvm.org/viewvc/llvm-project?rev=122808&view=rev Log: Disable r122754 on Windows: was causing all lit tests to fail. Modified: llvm/trunk/utils/lit/lit/TestRunner.py Modified: llvm/trunk/utils/lit/lit/TestRunner.py URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/TestRunner.py?rev=122808&r1=122807&r2=122808&view=diff ============================================================================== --- llvm/trunk/utils/lit/lit/TestRunner.py (original) +++ llvm/trunk/utils/lit/lit/TestRunner.py Tue Jan 4 04:23:42 2011 @@ -451,8 +451,12 @@ # expression pattern a with substitution b in line ln. def processLine(ln): # Apply substitutions + # FIXME: Investigate why re.sub doesn't work on Windows for a,b in substitutions: - ln = re.sub(a, b, ln) + if kIsWindows: + ln = ln.replace(a,b) + else: + ln = re.sub(a, b, ln) # Strip the trailing newline and any extra whitespace. return ln.strip() From pichet2000 at gmail.com Tue Jan 4 04:31:50 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Tue, 4 Jan 2011 05:31:50 -0500 Subject: [llvm-commits] [llvm] r122754 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py In-Reply-To: <20110103173025.CCF792A6C12C@llvm.org> References: <20110103173025.CCF792A6C12C@llvm.org> Message-ID: On Mon, Jan 3, 2011 at 12:30 PM, David Greene wrote: > Author: greened > Date: Mon Jan 3 11:30:25 2011 > New Revision: 122754 > > URL: http://llvm.org/viewvc/llvm-project?rev=122754&view=rev > Log: > > Reapply 122341 to fix PR8199 now that clang changes are in. > > Modified: > llvm/trunk/docs/TestingGuide.html > llvm/trunk/test/lit.cfg > llvm/trunk/utils/lit/lit/TestRunner.py > Hi, I disabled that fix on Windows. It doesn't work at all and cause all lit tests to fail. Any ideas why? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110104/782c4f6d/attachment.html From zwarich at apple.com Thu Jan 6 05:19:41 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Thu, 06 Jan 2011 03:19:41 -0800 Subject: [llvm-commits] [llvm] r122791 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp In-Reply-To: <4D22D843.1030706@free.fr> References: <20110104001246.3EBC92A6C12C@llvm.org> <4D22D843.1030706@free.fr> Message-ID: <89DC179B-2EC7-4F72-A951-4BA743313EE9@apple.com> On Jan 4, 2011, at 12:20 AM, Duncan Sands wrote: > Hi Cameron, > >> Address most of Duncan's review comments. Also, make LoopInstSimplify a simple >> FunctionPass. It probably doesn't have a reason to be a LoopPass, as it will >> probably drop the simple fixed point and either use RPO iteration or Duncan's >> approach in instsimplify of only revisiting instructions that have changed. >> >> The next step is to preserve LoopSimplify. This looks like it won't be too hard, >> although the pass manager doesn't actually seem to respect when non-loop passes >> claim to preserve LCSSA or LoopSimplify. This will have to be fixed. > > as far as I can see the pass is now identical to instsimplify, only it preserves > LCSSA form. In that case, why not delete the pass and teach instsimplify to > preserve LCSSA form if it detects the presence of the LCSSA analysis? However > I think Chris is right and you should go back to having this be a loop pass. Yes, that is what I will do. It also needs to preserve LoopSimplify. Cameron > From baldrick at free.fr Tue Jan 4 06:52:29 2011 From: baldrick at free.fr (Duncan Sands) Date: Tue, 04 Jan 2011 12:52:29 -0000 Subject: [llvm-commits] [llvm] r122809 - in /llvm/trunk: include/llvm/InstrTypes.h lib/VMCore/Instructions.cpp Message-ID: <20110104125229.89DB82A6C12C@llvm.org> Author: baldrick Date: Tue Jan 4 06:52:29 2011 New Revision: 122809 URL: http://llvm.org/viewvc/llvm-project?rev=122809&view=rev Log: These methods should be "const"; make them so. Modified: llvm/trunk/include/llvm/InstrTypes.h llvm/trunk/lib/VMCore/Instructions.cpp Modified: llvm/trunk/include/llvm/InstrTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=122809&r1=122808&r2=122809&view=diff ============================================================================== --- llvm/trunk/include/llvm/InstrTypes.h (original) +++ llvm/trunk/include/llvm/InstrTypes.h Tue Jan 4 06:52:29 2011 @@ -824,11 +824,11 @@ /// This is just a convenience that dispatches to the subclasses. /// @brief Determine if this CmpInst is commutative. - bool isCommutative(); + bool isCommutative() const; /// This is just a convenience that dispatches to the subclasses. /// @brief Determine if this is an equals/not equals predicate. - bool isEquality(); + bool isEquality() const; /// @returns true if the comparison is signed, false otherwise. /// @brief Determine if this instruction is using a signed comparison. Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=122809&r1=122808&r2=122809&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Tue Jan 4 06:52:29 2011 @@ -2736,14 +2736,14 @@ cast(this)->swapOperands(); } -bool CmpInst::isCommutative() { - if (ICmpInst *IC = dyn_cast(this)) +bool CmpInst::isCommutative() const { + if (const ICmpInst *IC = dyn_cast(this)) return IC->isCommutative(); return cast(this)->isCommutative(); } -bool CmpInst::isEquality() { - if (ICmpInst *IC = dyn_cast(this)) +bool CmpInst::isEquality() const { + if (const ICmpInst *IC = dyn_cast(this)) return IC->isEquality(); return cast(this)->isEquality(); } From greened at obbligato.org Tue Jan 4 09:20:03 2011 From: greened at obbligato.org (David A. Greene) Date: Tue, 04 Jan 2011 09:20:03 -0600 Subject: [llvm-commits] [llvm] r122808 - /llvm/trunk/utils/lit/lit/TestRunner.py In-Reply-To: <20110104102342.95C5F2A6C12C@llvm.org> (Francois Pichet's message of "Tue, 04 Jan 2011 10:23:42 -0000") References: <20110104102342.95C5F2A6C12C@llvm.org> Message-ID: Francois Pichet writes: > Author: fpichet > Date: Tue Jan 4 04:23:42 2011 > New Revision: 122808 > > URL: http://llvm.org/viewvc/llvm-project?rev=122808&view=rev > Log: > Disable r122754 on Windows: was causing all lit tests to fail. > > Modified: > llvm/trunk/utils/lit/lit/TestRunner.py > > Modified: llvm/trunk/utils/lit/lit/TestRunner.py > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/TestRunner.py?rev=122808&r1=122807&r2=122808&view=diff > ============================================================================== > --- llvm/trunk/utils/lit/lit/TestRunner.py (original) > +++ llvm/trunk/utils/lit/lit/TestRunner.py Tue Jan 4 04:23:42 2011 > @@ -451,8 +451,12 @@ > # expression pattern a with substitution b in line ln. > def processLine(ln): > # Apply substitutions > + # FIXME: Investigate why re.sub doesn't work on Windows > for a,b in substitutions: > - ln = re.sub(a, b, ln) > + if kIsWindows: > + ln = ln.replace(a,b) > + else: > + ln = re.sub(a, b, ln) > > # Strip the trailing newline and any extra whitespace. > return ln.strip() This can't possibly work. "a" is a regular expression. A replace isn't going to match it. -Dave From greened at obbligato.org Tue Jan 4 09:20:25 2011 From: greened at obbligato.org (David A. Greene) Date: Tue, 04 Jan 2011 09:20:25 -0600 Subject: [llvm-commits] [llvm] r122754 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py In-Reply-To: (Francois Pichet's message of "Tue, 4 Jan 2011 05:31:50 -0500") References: <20110103173025.CCF792A6C12C@llvm.org> Message-ID: Francois Pichet writes: > On Mon, Jan 3, 2011 at 12:30 PM, David Greene wrote: > > Author: greened > Date: Mon Jan ?3 11:30:25 2011 > New Revision: 122754 > > URL: http://llvm.org/viewvc/llvm-project?rev=122754&view=rev > Log: > > Reapply 122341 to fix PR8199 now that clang changes are in. > > Modified: > ? ?llvm/trunk/docs/TestingGuide.html > ? ?llvm/trunk/test/lit.cfg > ? ?llvm/trunk/utils/lit/lit/TestRunner.py > > Hi,? > > I disabled that fix on Windows. It doesn't work at all and cause all lit tests to fail.? > Any ideas why?? No. Do you have test output you can post? -Dave From grosser at fim.uni-passau.de Tue Jan 4 10:01:17 2011 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Tue, 04 Jan 2011 16:01:17 -0000 Subject: [llvm-commits] [llvm] r122810 - /llvm/trunk/test/lit.cfg Message-ID: <20110104160117.396602A6C12C@llvm.org> Author: grosser Date: Tue Jan 4 10:01:17 2011 New Revision: 122810 URL: http://llvm.org/viewvc/llvm-project?rev=122810&view=rev Log: Include llvm-gcc dir before llvm_tools_dir This ensures that always the recently compiled tools are picked for testing. Modified: llvm/trunk/test/lit.cfg Modified: llvm/trunk/test/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=122810&r1=122809&r2=122810&view=diff ============================================================================== --- llvm/trunk/test/lit.cfg (original) +++ llvm/trunk/test/lit.cfg Tue Jan 4 10:01:17 2011 @@ -27,6 +27,18 @@ # Tweak the PATH to include the scripts dir, the tools dir, and the llvm-gcc bin # dir (if available). if llvm_obj_root is not None: + # Include llvm-gcc first, as the llvm-gcc binaryies will not appear + # neither in the tools nor in the scripts dir. However it might be + # possible, that some old llvm tools are in the llvm-gcc dir. Adding + # llvm-gcc dir first ensures, that those will always be overwritten + # by the new tools in llvm_tools_dir. So now outdated tools are used + # for testing + llvmgcc_dir = getattr(config, 'llvmgcc_dir', None) + if llvmgcc_dir: + path = os.path.pathsep.join((os.path.join(llvmgcc_dir, 'bin'), + config.environment['PATH'])) + config.environment['PATH'] = path + llvm_src_root = getattr(config, 'llvm_src_root', None) if not llvm_src_root: lit.fatal('No LLVM source root set!') @@ -41,12 +53,6 @@ path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH'])) config.environment['PATH'] = path - llvmgcc_dir = getattr(config, 'llvmgcc_dir', None) - if llvmgcc_dir: - path = os.path.pathsep.join((os.path.join(llvmgcc_dir, 'bin'), - config.environment['PATH'])) - config.environment['PATH'] = path - # Propagate 'HOME' through the environment. if 'HOME' in os.environ: config.environment['HOME'] = os.environ['HOME'] From zwarich at apple.com Tue Jan 4 10:24:51 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 04 Jan 2011 16:24:51 -0000 Subject: [llvm-commits] [llvm] r122811 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <20110104162451.BF1A62A6C12C@llvm.org> Author: zwarich Date: Tue Jan 4 10:24:51 2011 New Revision: 122811 URL: http://llvm.org/viewvc/llvm-project?rev=122811&view=rev Log: Switch to path halving from path compression for a small speedup. This also makes getLeader() nonrecursive. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122811&r1=122810&r2=122811&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Tue Jan 4 10:24:51 2011 @@ -400,12 +400,18 @@ StrongPHIElimination::Node* StrongPHIElimination::Node::getLeader() { - Node* parentPointer = parent.getPointer(); - if (parentPointer == this) - return this; - Node* newParent = parentPointer->getLeader(); - parent.setPointer(newParent); - return newParent; + Node* N = this; + Node* Parent = parent.getPointer(); + Node* Grandparent = Parent->parent.getPointer(); + + while (Parent != Grandparent) { + N->parent.setPointer(Grandparent); + N = Grandparent; + Parent = Parent->parent.getPointer(); + Grandparent = Parent->parent.getPointer(); + } + + return Parent; } unsigned StrongPHIElimination::getRegColor(unsigned Reg) { From bigcheesegs at gmail.com Tue Jan 4 11:00:18 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Tue, 04 Jan 2011 17:00:18 -0000 Subject: [llvm-commits] [llvm] r122812 - /llvm/trunk/unittests/Support/Path.cpp Message-ID: <20110104170018.BDC1D2A6C12C@llvm.org> Author: mspencer Date: Tue Jan 4 11:00:18 2011 New Revision: 122812 URL: http://llvm.org/viewvc/llvm-project?rev=122812&view=rev Log: UnitTests/Path: Produce useful diagnostics on error. Modified: llvm/trunk/unittests/Support/Path.cpp Modified: llvm/trunk/unittests/Support/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Path.cpp?rev=122812&r1=122811&r2=122812&view=diff ============================================================================== --- llvm/trunk/unittests/Support/Path.cpp (original) +++ llvm/trunk/unittests/Support/Path.cpp Tue Jan 4 11:00:18 2011 @@ -16,6 +16,14 @@ using namespace llvm; using namespace llvm::sys; +#define ASSERT_NO_ERROR(x) \ + if (error_code ec = x) { \ + SmallString<128> Message; \ + GTEST_FATAL_FAILURE_((Twine(#x) + ": did not return errc::success.\n" + \ + "error message: " + \ + x.message()).toNullTerminatedStringRef(Message).data()); \ + } else {} + namespace { TEST(Support, Path) { @@ -100,9 +108,9 @@ path::is_absolute(*i); path::is_relative(*i); - SmallString<16> temp_store; + SmallString<128> temp_store; temp_store = *i; - ASSERT_FALSE(fs::make_absolute(temp_store)); + ASSERT_NO_ERROR(fs::make_absolute(temp_store)); temp_store = *i; path::remove_filename(temp_store); @@ -114,58 +122,58 @@ EXPECT_EQ(*(--sys::path::end(filename)), (stem + ext).str()); path::native(*i, temp_store); - - outs().flush(); } // Create a temp file. int FileDescriptor; SmallString<64> TempPath; - ASSERT_FALSE(fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath)); + ASSERT_NO_ERROR( + fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath)); // Make sure it exists. bool TempFileExists; - ASSERT_FALSE(sys::fs::exists(Twine(TempPath), TempFileExists)); + ASSERT_NO_ERROR(sys::fs::exists(Twine(TempPath), TempFileExists)); EXPECT_TRUE(TempFileExists); // Create another temp tile. int FD2; SmallString<64> TempPath2; - ASSERT_FALSE(fs::unique_file("%%-%%-%%-%%.temp", FD2, TempPath2)); + ASSERT_NO_ERROR(fs::unique_file("%%-%%-%%-%%.temp", FD2, TempPath2)); ASSERT_NE(TempPath.str(), TempPath2.str()); // Try to copy the first to the second. - EXPECT_EQ(fs::copy_file(Twine(TempPath), Twine(TempPath2)), errc::file_exists); + EXPECT_EQ( + fs::copy_file(Twine(TempPath), Twine(TempPath2)), errc::file_exists); ::close(FD2); // Try again with the proper options. - ASSERT_FALSE(fs::copy_file(Twine(TempPath), Twine(TempPath2), - fs::copy_option::overwrite_if_exists)); + ASSERT_NO_ERROR(fs::copy_file(Twine(TempPath), Twine(TempPath2), + fs::copy_option::overwrite_if_exists)); // Remove Temp2. - ASSERT_FALSE(fs::remove(Twine(TempPath2), TempFileExists)); + ASSERT_NO_ERROR(fs::remove(Twine(TempPath2), TempFileExists)); EXPECT_TRUE(TempFileExists); // Make sure Temp2 doesn't exist. - ASSERT_FALSE(fs::exists(Twine(TempPath2), TempFileExists)); + ASSERT_NO_ERROR(fs::exists(Twine(TempPath2), TempFileExists)); EXPECT_FALSE(TempFileExists); // Create a hard link to Temp1. - ASSERT_FALSE(fs::create_hard_link(Twine(TempPath), Twine(TempPath2))); + ASSERT_NO_ERROR(fs::create_hard_link(Twine(TempPath), Twine(TempPath2))); bool equal; - ASSERT_FALSE(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal)); + ASSERT_NO_ERROR(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal)); EXPECT_TRUE(equal); // Remove Temp1. ::close(FileDescriptor); - ASSERT_FALSE(fs::remove(Twine(TempPath), TempFileExists)); + ASSERT_NO_ERROR(fs::remove(Twine(TempPath), TempFileExists)); EXPECT_TRUE(TempFileExists); // Remove the hard link. - ASSERT_FALSE(fs::remove(Twine(TempPath2), TempFileExists)); + ASSERT_NO_ERROR(fs::remove(Twine(TempPath2), TempFileExists)); EXPECT_TRUE(TempFileExists); // Make sure Temp1 doesn't exist. - ASSERT_FALSE(fs::exists(Twine(TempPath), TempFileExists)); + ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists)); EXPECT_FALSE(TempFileExists); // I've yet to do directory iteration on Unix. From clattner at apple.com Tue Jan 4 12:17:43 2011 From: clattner at apple.com (Chris Lattner) Date: Tue, 4 Jan 2011 10:17:43 -0800 Subject: [llvm-commits] [llvm] r122719 - in /llvm/trunk: include/llvm/InitializePasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/CMakeLists.txt lib/Transforms/Scalar/LoopInstSimplify.cpp lib/Transforms/Scalar/Scalar.cpp In-Reply-To: <4F459E2D-0169-411A-8424-84E3F3D838AE@apple.com> References: <20110103002516.F06722A6C12C@llvm.org> <4D21A528.4040003@free.fr> <4F459E2D-0169-411A-8424-84E3F3D838AE@apple.com> Message-ID: On Jan 3, 2011, at 3:22 AM, Cameron Zwarich wrote: >>> +bool LoopInstSimplify::runOnLoop(Loop* L, LPPassManager& LPM) { >>> + DominatorTree* DT =&getAnalysis(); >> >> Usual style is a space before the * not after. > > Is this true? I see both all over LLVM. I try to duplicate the style of whatever file I'm in, but when it's a new file I'm not sure which other style to emulate. Please use "Loop *L", thanks! -Chris From sabre at nondot.org Tue Jan 4 12:19:15 2011 From: sabre at nondot.org (Chris Lattner) Date: Tue, 04 Jan 2011 18:19:15 -0000 Subject: [llvm-commits] [llvm] r122814 - in /llvm/trunk: lib/Analysis/ValueTracking.cpp test/Transforms/InstCombine/crash.ll Message-ID: <20110104181915.C72B52A6C12C@llvm.org> Author: lattner Date: Tue Jan 4 12:19:15 2011 New Revision: 122814 URL: http://llvm.org/viewvc/llvm-project?rev=122814&view=rev Log: fix an off-by-one bug that caused a crash analyzing ashr's with huge shift amounts, PR8896 Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp llvm/trunk/test/Transforms/InstCombine/crash.ll Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=122814&r1=122813&r2=122814&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ValueTracking.cpp (original) +++ llvm/trunk/lib/Analysis/ValueTracking.cpp Tue Jan 4 12:19:15 2011 @@ -337,7 +337,7 @@ // (ashr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0 if (ConstantInt *SA = dyn_cast(I->getOperand(1))) { // Compute the new bits that are at the top now. - uint64_t ShiftAmt = SA->getLimitedValue(BitWidth); + uint64_t ShiftAmt = SA->getLimitedValue(BitWidth-1); // Signed shift right. APInt Mask2(Mask.shl(ShiftAmt)); Modified: llvm/trunk/test/Transforms/InstCombine/crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/crash.ll?rev=122814&r1=122813&r2=122814&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/crash.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/crash.ll Tue Jan 4 12:19:15 2011 @@ -298,3 +298,40 @@ } +; PR8896 + at g_54 = external global [7 x i16] + +define void @test15(i32* %p_92) nounwind { +entry: +%0 = load i32* %p_92, align 4 +%1 = icmp ne i32 %0, 0 +%2 = zext i1 %1 to i32 +%3 = call i32 @func_14() nounwind +%4 = trunc i32 %3 to i16 +%5 = sext i16 %4 to i32 +%6 = trunc i32 %5 to i16 +br i1 undef, label %"3", label %"5" + +"3": ; preds = %entry +%7 = sext i16 %6 to i32 +%8 = ashr i32 %7, -1649554541 +%9 = trunc i32 %8 to i16 +br label %"5" + +"5": ; preds = %"3", %entry +%10 = phi i16 [ %9, %"3" ], [ %6, %entry ] +%11 = sext i16 %10 to i32 +%12 = xor i32 %2, %11 +%13 = sext i32 %12 to i64 +%14 = icmp ne i64 %13, 0 +br i1 %14, label %return, label %"7" + +"7": ; preds = %"5" +ret void + +return: ; preds = %"5" +ret void +} + +declare i32 @func_14() + From zwarich at apple.com Tue Jan 4 12:19:20 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 04 Jan 2011 18:19:20 -0000 Subject: [llvm-commits] [llvm] r122815 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Message-ID: <20110104181920.277E72A6C12D@llvm.org> Author: zwarich Date: Tue Jan 4 12:19:19 2011 New Revision: 122815 URL: http://llvm.org/viewvc/llvm-project?rev=122815&view=rev Log: Switch to the new style of asterisk placement. Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp?rev=122815&r1=122814&r2=122815&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Tue Jan 4 12:19:19 2011 @@ -33,9 +33,9 @@ initializeLoopInstSimplifyPass(*PassRegistry::getPassRegistry()); } - bool runOnFunction(Function&); + bool runOnFunction(Function &); - virtual void getAnalysisUsage(AnalysisUsage& AU) const { + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired(); AU.addPreserved(); @@ -57,10 +57,10 @@ return new LoopInstSimplify(); } -bool LoopInstSimplify::runOnFunction(Function& F) { - DominatorTree* DT = getAnalysisIfAvailable(); - LoopInfo* LI = &getAnalysis(); - const TargetData* TD = getAnalysisIfAvailable(); +bool LoopInstSimplify::runOnFunction(Function &F) { + DominatorTree *DT = getAnalysisIfAvailable(); + LoopInfo *LI = &getAnalysis(); + const TargetData *TD = getAnalysisIfAvailable(); bool Changed = false; bool LocalChanged; @@ -70,10 +70,10 @@ for (df_iterator DI = df_begin(&F.getEntryBlock()), DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) for (BasicBlock::iterator BI = DI->begin(), BE = DI->end(); BI != BE;) { - Instruction* I = BI++; + Instruction *I = BI++; // Don't bother simplifying unused instructions. if (!I->use_empty()) { - Value* V = SimplifyInstruction(I, TD, DT); + Value *V = SimplifyInstruction(I, TD, DT); if (V && LI->replacementPreservesLCSSAForm(I, V)) { I->replaceAllUsesWith(V); LocalChanged = true; From resistor at mac.com Tue Jan 4 12:21:18 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 04 Jan 2011 18:21:18 -0000 Subject: [llvm-commits] [llvm] r122816 - /llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h Message-ID: <20110104182118.296A32A6C12C@llvm.org> Author: resistor Date: Tue Jan 4 12:21:18 2011 New Revision: 122816 URL: http://llvm.org/viewvc/llvm-project?rev=122816&view=rev Log: Give MachineFunctionAnalysis a getPassName() implementation to make timing reports prettier. Modified: llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h Modified: llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h?rev=122816&r1=122815&r2=122816&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h Tue Jan 4 12:21:18 2011 @@ -37,6 +37,10 @@ MachineFunction &getMF() const { return *MF; } CodeGenOpt::Level getOptLevel() const { return OptLevel; } + + virtual const char* getPassName() const { + return "Machine Function Analysis"; + } private: virtual bool doInitialization(Module &M); From resistor at mac.com Tue Jan 4 12:22:08 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 04 Jan 2011 18:22:08 -0000 Subject: [llvm-commits] [llvm] r122817 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <20110104182209.0291A2A6C12C@llvm.org> Author: resistor Date: Tue Jan 4 12:22:08 2011 New Revision: 122817 URL: http://llvm.org/viewvc/llvm-project?rev=122817&view=rev Log: Remove commented out code. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=122817&r1=122816&r2=122817&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Jan 4 12:22:08 2011 @@ -90,10 +90,6 @@ return false; return true; } - - /*bool operator!=(const Expression &other) const { - return !(*this == other); - }*/ }; class ValueTable { From resistor at mac.com Tue Jan 4 12:54:18 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 04 Jan 2011 18:54:18 -0000 Subject: [llvm-commits] [llvm] r122819 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <20110104185418.581862A6C12C@llvm.org> Author: resistor Date: Tue Jan 4 12:54:18 2011 New Revision: 122819 URL: http://llvm.org/viewvc/llvm-project?rev=122819&view=rev Log: Branch instructions don't produce values, so there's no need to generate a value number for them. This avoids adding them to the various value numbering tables, resulting in a minor (~3%) speedup for GVN on 40.gcc. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=122819&r1=122818&r2=122819&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Jan 4 12:54:18 2011 @@ -1670,14 +1670,9 @@ return Changed; } - uint32_t NextNum = VN.getNextUnusedValueNumber(); - unsigned Num = VN.lookup_or_add(I); - // For conditions branches, we can perform simple conditional propagation on // the condition value itself. if (BranchInst *BI = dyn_cast(I)) { - insert_table(Num, I, I->getParent()); - if (!BI->isConditional() || isa(BI->getCondition())) return false; @@ -1699,6 +1694,9 @@ return false; } + uint32_t NextNum = VN.getNextUnusedValueNumber(); + unsigned Num = VN.lookup_or_add(I); + // Allocations are always uniquely numbered, so we can save time and memory // by fast failing them. if (isa(I) || isa(I) || isa(I)) { From dalej at apple.com Tue Jan 4 13:01:54 2011 From: dalej at apple.com (Dale Johannesen) Date: Tue, 04 Jan 2011 19:01:54 -0000 Subject: [llvm-commits] [llvm] r122821 - /llvm/trunk/lib/Transforms/IPO/Inliner.cpp Message-ID: <20110104190154.470292A6C12C@llvm.org> Author: johannes Date: Tue Jan 4 13:01:54 2011 New Revision: 122821 URL: http://llvm.org/viewvc/llvm-project?rev=122821&view=rev Log: Improve the accuracy of the inlining heuristic looking for the case where a static caller is itself inlined everywhere else, and thus may go away if it doesn't get too big due to inlining other things into it. If there are references to the caller other than calls, it will not be removed; account for this. This results in same-day completion of the case in PR8853. Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=122821&r1=122820&r2=122821&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/Inliner.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/Inliner.cpp Tue Jan 4 13:01:54 2011 @@ -252,20 +252,25 @@ if (Caller->hasLocalLinkage()) { int TotalSecondaryCost = 0; bool outerCallsFound = false; - bool allOuterCallsWillBeInlined = true; - bool someOuterCallWouldNotBeInlined = false; + // This bool tracks what happens if we do NOT inline C into B. + bool callerWillBeRemoved = true; + // This bool tracks what happens if we DO inline C into B. + bool inliningPreventsSomeOuterInline = false; for (Value::use_iterator I = Caller->use_begin(), E =Caller->use_end(); I != E; ++I) { CallSite CS2(*I); // If this isn't a call to Caller (it could be some other sort - // of reference) skip it. - if (!CS2 || CS2.getCalledFunction() != Caller) + // of reference) skip it. Such references will prevent the caller + // from being removed. + if (!CS2 || CS2.getCalledFunction() != Caller) { + callerWillBeRemoved = false; continue; + } InlineCost IC2 = getInlineCost(CS2); if (IC2.isNever()) - allOuterCallsWillBeInlined = false; + callerWillBeRemoved = false; if (IC2.isAlways() || IC2.isNever()) continue; @@ -275,14 +280,14 @@ float FudgeFactor2 = getInlineFudgeFactor(CS2); if (Cost2 >= (int)(CurrentThreshold2 * FudgeFactor2)) - allOuterCallsWillBeInlined = false; + callerWillBeRemoved = false; // See if we have this case. We subtract off the penalty // for the call instruction, which we would be deleting. if (Cost2 < (int)(CurrentThreshold2 * FudgeFactor2) && Cost2 + Cost - (InlineConstants::CallPenalty + 1) >= (int)(CurrentThreshold2 * FudgeFactor2)) { - someOuterCallWouldNotBeInlined = true; + inliningPreventsSomeOuterInline = true; TotalSecondaryCost += Cost2; } } @@ -290,10 +295,10 @@ // one is set very low by getInlineCost, in anticipation that Caller will // be removed entirely. We did not account for this above unless there // is only one caller of Caller. - if (allOuterCallsWillBeInlined && Caller->use_begin() != Caller->use_end()) + if (callerWillBeRemoved && Caller->use_begin() != Caller->use_end()) TotalSecondaryCost += InlineConstants::LastCallToStaticBonus; - if (outerCallsFound && someOuterCallWouldNotBeInlined && + if (outerCallsFound && inliningPreventsSomeOuterInline && TotalSecondaryCost < Cost) { DEBUG(dbgs() << " NOT Inlining: " << *CS.getInstruction() << " Cost = " << Cost << From resistor at mac.com Tue Jan 4 13:10:55 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 04 Jan 2011 19:10:55 -0000 Subject: [llvm-commits] [llvm] r122822 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <20110104191055.122B52A6C12C@llvm.org> Author: resistor Date: Tue Jan 4 13:10:54 2011 New Revision: 122822 URL: http://llvm.org/viewvc/llvm-project?rev=122822&view=rev Log: When removing a value from GVN's leaders list, don't drop the Next pointer in a corner case. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=122822&r1=122821&r2=122822&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Jan 4 13:10:54 2011 @@ -466,6 +466,7 @@ NumberTableEntry* Next = Curr->Next; Curr->Val = Next->Val; Curr->BB = Next->BB; + Curr->Next = Next->Next; } } } @@ -1693,7 +1694,7 @@ return false; } - + uint32_t NextNum = VN.getNextUnusedValueNumber(); unsigned Num = VN.lookup_or_add(I); From resistor at mac.com Tue Jan 4 13:13:25 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 04 Jan 2011 19:13:25 -0000 Subject: [llvm-commits] [llvm] r122823 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <20110104191325.5B9D92A6C12C@llvm.org> Author: resistor Date: Tue Jan 4 13:13:25 2011 New Revision: 122823 URL: http://llvm.org/viewvc/llvm-project?rev=122823&view=rev Log: Clarify terminology, settling on referring to what was the "number table" as the "leader table", and rename methods to make it much more clear what they're doing. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=122823&r1=122822&r2=122823&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Jan 4 13:13:25 2011 @@ -419,37 +419,37 @@ ValueTable VN; /// NumberTable - A mapping from value numers to lists of Value*'s that - /// have that value number. Use lookupNumber to query it. - struct NumberTableEntry { + /// have that value number. Use findLeader to query it. + struct LeaderTableEntry { Value *Val; BasicBlock *BB; - NumberTableEntry *Next; + LeaderTableEntry *Next; }; - DenseMap NumberTable; + DenseMap NumberTable; BumpPtrAllocator TableAllocator; - /// insert_table - Push a new Value to the NumberTable onto the list for + /// addToLeaderTable - Push a new Value to the NumberTable onto the list for /// its value number. - void insert_table(uint32_t N, Value *V, BasicBlock *BB) { - NumberTableEntry& Curr = NumberTable[N]; + void addToLeaderTable(uint32_t N, Value *V, BasicBlock *BB) { + LeaderTableEntry& Curr = NumberTable[N]; if (!Curr.Val) { Curr.Val = V; Curr.BB = BB; return; } - NumberTableEntry* Node = TableAllocator.Allocate(); + LeaderTableEntry* Node = TableAllocator.Allocate(); Node->Val = V; Node->BB = BB; Node->Next = Curr.Next; Curr.Next = Node; } - /// erase_table - Scan the list of values corresponding to a given value + /// removeFromLeaderTable - Scan the list of values corresponding to a given value /// number, and remove the given value if encountered. - void erase_table(uint32_t N, Value *V, BasicBlock *BB) { - NumberTableEntry* Prev = 0; - NumberTableEntry* Curr = &NumberTable[N]; + void removeFromLeaderTable(uint32_t N, Value *V, BasicBlock *BB) { + LeaderTableEntry* Prev = 0; + LeaderTableEntry* Curr = &NumberTable[N]; while (Curr->Val != V || Curr->BB != BB) { Prev = Curr; @@ -463,7 +463,7 @@ Curr->Val = 0; Curr->BB = 0; } else { - NumberTableEntry* Next = Curr->Next; + LeaderTableEntry* Next = Curr->Next; Curr->Val = Next->Val; Curr->BB = Next->BB; Curr->Next = Next->Next; @@ -497,7 +497,7 @@ void dump(DenseMap& d); bool iterateOnFunction(Function &F); bool performPRE(Function& F); - Value *lookupNumber(BasicBlock *BB, uint32_t num); + Value *findLeader(BasicBlock *BB, uint32_t num); void cleanupGlobalSets(); void verifyRemoved(const Instruction *I) const; bool splitCriticalEdges(); @@ -1610,13 +1610,13 @@ return false; } -// lookupNumber - In order to find a leader for a given value number at a +// findLeader - In order to find a leader for a given value number at a // specific basic block, we first obtain the list of all Values for that number, // and then scan the list to find one whose block dominates the block in // question. This is fast because dominator tree queries consist of only // a few comparisons of DFS numbers. -Value *GVN::lookupNumber(BasicBlock *BB, uint32_t num) { - NumberTableEntry Vals = NumberTable[num]; +Value *GVN::findLeader(BasicBlock *BB, uint32_t num) { + LeaderTableEntry Vals = NumberTable[num]; if (!Vals.Val) return 0; Value *Val = 0; @@ -1625,7 +1625,7 @@ if (isa(Val)) return Val; } - NumberTableEntry* Next = Vals.Next; + LeaderTableEntry* Next = Vals.Next; while (Next) { if (DT->dominates(Next->BB, BB)) { if (isa(Next->Val)) return Next->Val; @@ -1665,7 +1665,7 @@ if (!Changed) { unsigned Num = VN.lookup_or_add(LI); - insert_table(Num, LI, LI->getParent()); + addToLeaderTable(Num, LI, LI->getParent()); } return Changed; @@ -1684,11 +1684,11 @@ BasicBlock *FalseSucc = BI->getSuccessor(1); if (TrueSucc->getSinglePredecessor()) - insert_table(CondVN, + addToLeaderTable(CondVN, ConstantInt::getTrue(TrueSucc->getContext()), TrueSucc); if (FalseSucc->getSinglePredecessor()) - insert_table(CondVN, + addToLeaderTable(CondVN, ConstantInt::getFalse(TrueSucc->getContext()), FalseSucc); @@ -1701,7 +1701,7 @@ // Allocations are always uniquely numbered, so we can save time and memory // by fast failing them. if (isa(I) || isa(I) || isa(I)) { - insert_table(Num, I, I->getParent()); + addToLeaderTable(Num, I, I->getParent()); return false; } @@ -1709,16 +1709,16 @@ // need to do a lookup to see if the number already exists // somewhere in the domtree: it can't! if (Num == NextNum) { - insert_table(Num, I, I->getParent()); + addToLeaderTable(Num, I, I->getParent()); return false; } // Perform fast-path value-number based elimination of values inherited from // dominators. - Value *repl = lookupNumber(I->getParent(), Num); + Value *repl = findLeader(I->getParent(), Num); if (repl == 0) { // Failure, just remember this instance for future use. - insert_table(Num, I, I->getParent()); + addToLeaderTable(Num, I, I->getParent()); return false; } @@ -1879,7 +1879,7 @@ break; } - Value* predV = lookupNumber(P, ValNo); + Value* predV = findLeader(P, ValNo); if (predV == 0) { PREPred = P; ++NumWithout; @@ -1921,7 +1921,7 @@ if (isa(Op) || isa(Op) || isa(Op)) continue; - if (Value *V = lookupNumber(PREPred, VN.lookup(Op))) { + if (Value *V = findLeader(PREPred, VN.lookup(Op))) { PREInstr->setOperand(i, V); } else { success = false; @@ -1945,7 +1945,7 @@ ++NumGVNPRE; // Update the availability map to include the new instruction. - insert_table(ValNo, PREInstr, PREPred); + addToLeaderTable(ValNo, PREInstr, PREPred); // Create a PHI to make the value available in this block. PHINode* Phi = PHINode::Create(CurInst->getType(), @@ -1958,7 +1958,7 @@ } VN.add(Phi, ValNo); - insert_table(ValNo, Phi, CurrentBlock); + addToLeaderTable(ValNo, Phi, CurrentBlock); CurInst->replaceAllUsesWith(Phi); if (Phi->getType()->isPointerTy()) { @@ -1972,7 +1972,7 @@ MD->invalidateCachedPointerInfo(Phi); } VN.erase(CurInst); - erase_table(ValNo, CurInst, CurrentBlock); + removeFromLeaderTable(ValNo, CurInst, CurrentBlock); DEBUG(dbgs() << "GVN PRE removed: " << *CurInst << '\n'); if (MD) MD->removeInstruction(CurInst); @@ -2035,9 +2035,9 @@ // Walk through the value number scope to make sure the instruction isn't // ferreted away in it. - for (DenseMap::const_iterator + for (DenseMap::const_iterator I = NumberTable.begin(), E = NumberTable.end(); I != E; ++I) { - const NumberTableEntry *Node = &I->second; + const LeaderTableEntry *Node = &I->second; assert(Node->Val != Inst && "Inst still in value numbering scope!"); while (Node->Next) { From resistor at mac.com Tue Jan 4 13:24:58 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 04 Jan 2011 19:24:58 -0000 Subject: [llvm-commits] [llvm] r122826 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <20110104192458.1BFCE2A6C12C@llvm.org> Author: resistor Date: Tue Jan 4 13:24:57 2011 New Revision: 122826 URL: http://llvm.org/viewvc/llvm-project?rev=122826&view=rev Log: Prune #include's. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=122826&r1=122825&r2=122826&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Jan 4 13:24:57 2011 @@ -17,13 +17,9 @@ #define DEBUG_TYPE "gvn" #include "llvm/Transforms/Scalar.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" #include "llvm/GlobalVariable.h" -#include "llvm/Function.h" #include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" -#include "llvm/Operator.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/Dominators.h" @@ -36,21 +32,15 @@ #include "llvm/Assembly/Writer.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/SSAUpdater.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DepthFirstIterator.h" -#include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Allocator.h" -#include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/IRBuilder.h" -#include using namespace llvm; STATISTIC(NumGVNInstr, "Number of instructions deleted"); From resistor at mac.com Tue Jan 4 13:25:18 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 04 Jan 2011 19:25:18 -0000 Subject: [llvm-commits] [llvm] r122827 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <20110104192518.E61472A6C12C@llvm.org> Author: resistor Date: Tue Jan 4 13:25:18 2011 New Revision: 122827 URL: http://llvm.org/viewvc/llvm-project?rev=122827&view=rev Log: Fix typo in a comment. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=122827&r1=122826&r2=122827&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Jan 4 13:25:18 2011 @@ -408,7 +408,7 @@ ValueTable VN; - /// NumberTable - A mapping from value numers to lists of Value*'s that + /// NumberTable - A mapping from value numbers to lists of Value*'s that /// have that value number. Use findLeader to query it. struct LeaderTableEntry { Value *Val; From resistor at mac.com Tue Jan 4 13:29:47 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 04 Jan 2011 19:29:47 -0000 Subject: [llvm-commits] [llvm] r122828 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <20110104192947.21BF42A6C12C@llvm.org> Author: resistor Date: Tue Jan 4 13:29:46 2011 New Revision: 122828 URL: http://llvm.org/viewvc/llvm-project?rev=122828&view=rev Log: Complete the NumberTable --> LeaderTable rename. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=122828&r1=122827&r2=122828&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Jan 4 13:29:46 2011 @@ -408,20 +408,20 @@ ValueTable VN; - /// NumberTable - A mapping from value numbers to lists of Value*'s that + /// LeaderTable - A mapping from value numbers to lists of Value*'s that /// have that value number. Use findLeader to query it. struct LeaderTableEntry { Value *Val; BasicBlock *BB; LeaderTableEntry *Next; }; - DenseMap NumberTable; + DenseMap LeaderTable; BumpPtrAllocator TableAllocator; - /// addToLeaderTable - Push a new Value to the NumberTable onto the list for + /// addToLeaderTable - Push a new Value to the LeaderTable onto the list for /// its value number. void addToLeaderTable(uint32_t N, Value *V, BasicBlock *BB) { - LeaderTableEntry& Curr = NumberTable[N]; + LeaderTableEntry& Curr = LeaderTable[N]; if (!Curr.Val) { Curr.Val = V; Curr.BB = BB; @@ -435,11 +435,11 @@ Curr.Next = Node; } - /// removeFromLeaderTable - Scan the list of values corresponding to a given value - /// number, and remove the given value if encountered. + /// removeFromLeaderTable - Scan the list of values corresponding to a given + /// value number, and remove the given value if encountered. void removeFromLeaderTable(uint32_t N, Value *V, BasicBlock *BB) { LeaderTableEntry* Prev = 0; - LeaderTableEntry* Curr = &NumberTable[N]; + LeaderTableEntry* Curr = &LeaderTable[N]; while (Curr->Val != V || Curr->BB != BB) { Prev = Curr; @@ -1365,8 +1365,8 @@ // @1 = getelementptr (i8* p, ... // test p and branch if == 0 // load @1 - // It is valid to have the getelementptr before the test, even if p can be 0, - // as getelementptr only does address arithmetic. + // It is valid to have the getelementptr before the test, even if p can + // be 0, as getelementptr only does address arithmetic. // If we are not pushing the value through any multiple-successor blocks // we do not have this case. Otherwise, check that the load is safe to // put anywhere; this can be improved, but should be conservatively safe. @@ -1606,7 +1606,7 @@ // question. This is fast because dominator tree queries consist of only // a few comparisons of DFS numbers. Value *GVN::findLeader(BasicBlock *BB, uint32_t num) { - LeaderTableEntry Vals = NumberTable[num]; + LeaderTableEntry Vals = LeaderTable[num]; if (!Vals.Val) return 0; Value *Val = 0; @@ -2014,7 +2014,7 @@ void GVN::cleanupGlobalSets() { VN.clear(); - NumberTable.clear(); + LeaderTable.clear(); TableAllocator.Reset(); } @@ -2026,7 +2026,7 @@ // Walk through the value number scope to make sure the instruction isn't // ferreted away in it. for (DenseMap::const_iterator - I = NumberTable.begin(), E = NumberTable.end(); I != E; ++I) { + I = LeaderTable.begin(), E = LeaderTable.end(); I != E; ++I) { const LeaderTableEntry *Node = &I->second; assert(Node->Val != Inst && "Inst still in value numbering scope!"); From dalej at apple.com Tue Jan 4 13:31:24 2011 From: dalej at apple.com (Dale Johannesen) Date: Tue, 04 Jan 2011 19:31:24 -0000 Subject: [llvm-commits] [llvm] r122829 - /llvm/trunk/lib/Target/X86/X86FrameInfo.cpp Message-ID: <20110104193125.041D72A6C12C@llvm.org> Author: johannes Date: Tue Jan 4 13:31:24 2011 New Revision: 122829 URL: http://llvm.org/viewvc/llvm-project?rev=122829&view=rev Log: Eliminate a warning compiling with llvm-gcc. (IMO the warning is overzealous but gcc is what it is.) Modified: llvm/trunk/lib/Target/X86/X86FrameInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86FrameInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameInfo.cpp?rev=122829&r1=122828&r2=122829&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FrameInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FrameInfo.cpp Tue Jan 4 13:31:24 2011 @@ -153,7 +153,7 @@ if (ThisVal == (Is64Bit ? 8 : 4)) { // Use push / pop instead. unsigned Reg = isSub - ? (Is64Bit ? X86::RAX : X86::EAX) + ? (unsigned)(Is64Bit ? X86::RAX : X86::EAX) : findDeadCallerSavedReg(MBB, MBBI, TRI, Is64Bit); if (Reg) { Opc = isSub From richard at metafoo.co.uk Tue Jan 4 14:30:22 2011 From: richard at metafoo.co.uk (Richard Smith) Date: Tue, 4 Jan 2011 20:30:22 -0000 (UTC) Subject: [llvm-commits] [PATCH] [MC] Reading off end of buffer when disassembling truncated x86 asm (PR7710) In-Reply-To: <57603.10.0.16.53.1294058683.squirrel@webmail.cantab.net> References: <57603.10.0.16.53.1294058683.squirrel@webmail.cantab.net> Message-ID: <45726.10.0.16.53.1294173022.squirrel@webmail.cantab.net> Hi, On Mon, January 3, 2011 12:44, Richard Smith wrote: > The attached patch (also attached to PR7710) fixes two issues which cause > llvm-mc to incorrectly disassemble truncated asm The updated, attached patch also contains a test for these issues. Thanks, Richard -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-7710.diff Type: text/x-patch Size: 1604 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110104/850ff281/attachment.bin From stoklund at 2pi.dk Tue Jan 4 15:10:05 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 04 Jan 2011 21:10:05 -0000 Subject: [llvm-commits] [llvm] r122832 - in /llvm/trunk: include/llvm/CodeGen/EdgeBundles.h include/llvm/CodeGen/Passes.h include/llvm/InitializePasses.h lib/CodeGen/CMakeLists.txt lib/CodeGen/EdgeBundles.cpp lib/CodeGen/SplitKit.cpp lib/CodeGen/SplitKit.h lib/Target/X86/X86FloatingPoint.cpp Message-ID: <20110104211005.F0A0E2A6C12C@llvm.org> Author: stoklund Date: Tue Jan 4 15:10:05 2011 New Revision: 122832 URL: http://llvm.org/viewvc/llvm-project?rev=122832&view=rev Log: Turn the EdgeBundles class into a stand-alone machine CFG analysis pass. The analysis will be needed by both the greedy register allocator and the X86FloatingPoint pass. It only needs to be computed once when the CFG doesn't change. This pass is very fast, usually showing up as 0.0% wall time. Added: llvm/trunk/include/llvm/CodeGen/EdgeBundles.h llvm/trunk/lib/CodeGen/EdgeBundles.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/include/llvm/InitializePasses.h llvm/trunk/lib/CodeGen/CMakeLists.txt llvm/trunk/lib/CodeGen/SplitKit.cpp llvm/trunk/lib/CodeGen/SplitKit.h llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp Added: llvm/trunk/include/llvm/CodeGen/EdgeBundles.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/EdgeBundles.h?rev=122832&view=auto ============================================================================== --- llvm/trunk/include/llvm/CodeGen/EdgeBundles.h (added) +++ llvm/trunk/include/llvm/CodeGen/EdgeBundles.h Tue Jan 4 15:10:05 2011 @@ -0,0 +1,58 @@ +//===-------- EdgeBundles.h - Bundles of CFG edges --------------*- c++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The EdgeBundles analysis forms equivalence classes of CFG edges such that all +// edges leaving a machine basic block are in the same bundle, and all edges +// leaving a basic block are in the same bundle. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_EDGEBUNDLES_H +#define LLVM_CODEGEN_EDGEBUNDLES_H + +#include "llvm/ADT/IntEqClasses.h" +#include "llvm/CodeGen/MachineFunctionPass.h" + +namespace llvm { + +class EdgeBundles : public MachineFunctionPass { + const MachineFunction *MF; + + /// EC - Each edge bundle is an equivalence class. The keys are: + /// 2*BB->getNumber() -> Ingoing bundle. + /// 2*BB->getNumber()+1 -> Outgoing bundle. + IntEqClasses EC; + +public: + static char ID; + EdgeBundles() : MachineFunctionPass(ID) {} + + /// getBundle - Return the ingoing (Out = false) or outgoing (Out = true) + /// bundle number for basic block #N + unsigned getBundle(unsigned N, bool Out) const { return EC[2 * N + Out]; } + + /// getMachineFunction - Return the last machine function computed. + const MachineFunction *getMachineFunction() const { return MF; } + + /// view - Visualize the annotated bipartite CFG with Graphviz. + void view() const; + +private: + virtual bool runOnMachineFunction(MachineFunction&); + virtual void getAnalysisUsage(AnalysisUsage&) const; +}; + +/// Specialize WriteGraph, the standard implementation won't work. +raw_ostream &WriteGraph(raw_ostream &O, const EdgeBundles &G, + bool ShortNames = false, + const std::string &Title = ""); + +} // end namespace llvm + +#endif Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=122832&r1=122831&r2=122832&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Tue Jan 4 15:10:05 2011 @@ -54,6 +54,10 @@ /// extern char &MachineDominatorsID; + /// EdgeBundles analysis - Bundle machine CFG edges. + /// + extern char &EdgeBundlesID; + /// PHIElimination pass - This pass eliminates machine instruction PHI nodes /// by inserting copy instructions. This destroys SSA information, but is the /// desired input for some register allocators. This pass is "required" by Modified: llvm/trunk/include/llvm/InitializePasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=122832&r1=122831&r2=122832&view=diff ============================================================================== --- llvm/trunk/include/llvm/InitializePasses.h (original) +++ llvm/trunk/include/llvm/InitializePasses.h Tue Jan 4 15:10:05 2011 @@ -91,6 +91,7 @@ void initializeDomViewerPass(PassRegistry&); void initializeDominanceFrontierPass(PassRegistry&); void initializeDominatorTreePass(PassRegistry&); +void initializeEdgeBundlesPass(PassRegistry&); void initializeEdgeProfilerPass(PassRegistry&); void initializeEarlyCSEPass(PassRegistry&); void initializeExpandISelPseudosPass(PassRegistry&); Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=122832&r1=122831&r2=122832&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Tue Jan 4 15:10:05 2011 @@ -10,6 +10,7 @@ CriticalAntiDepBreaker.cpp DeadMachineInstructionElim.cpp DwarfEHPrepare.cpp + EdgeBundles.cpp ELFCodeEmitter.cpp ELFWriter.cpp ExpandISelPseudos.cpp Added: llvm/trunk/lib/CodeGen/EdgeBundles.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/EdgeBundles.cpp?rev=122832&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/EdgeBundles.cpp (added) +++ llvm/trunk/lib/CodeGen/EdgeBundles.cpp Tue Jan 4 15:10:05 2011 @@ -0,0 +1,79 @@ +//===-------- EdgeBundles.cpp - Bundles of CFG edges ----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the implementation of the EdgeBundles analysis. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/EdgeBundles.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Support/GraphWriter.h" + +using namespace llvm; + +char EdgeBundles::ID = 0; + +INITIALIZE_PASS(EdgeBundles, "edge-bundles", "Bundle Machine CFG Edges", + /* cfg = */true, /* analysis = */ true) + +char &llvm::EdgeBundlesID = EdgeBundles::ID; + +void EdgeBundles::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); +} + +bool EdgeBundles::runOnMachineFunction(MachineFunction &mf) { + MF = &mf; + EC.clear(); + EC.grow(2 * MF->size()); + + for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E; + ++I) { + const MachineBasicBlock &MBB = *I; + unsigned OutE = 2 * MBB.getNumber() + 1; + // Join the outgoing bundle with the ingoing bundles of all successors. + for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(), + SE = MBB.succ_end(); SI != SE; ++SI) + EC.join(OutE, 2 * (*SI)->getNumber()); + } + EC.compress(); + return false; +} + +/// view - Visualize the annotated bipartite CFG with Graphviz. +void EdgeBundles::view() const { + ViewGraph(*this, "EdgeBundles"); +} + +/// Specialize WriteGraph, the standard implementation won't work. +raw_ostream &llvm::WriteGraph(raw_ostream &O, const EdgeBundles &G, + bool ShortNames, + const std::string &Title) { + const MachineFunction *MF = G.getMachineFunction(); + + O << "digraph {\n"; + for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); + I != E; ++I) { + unsigned BB = I->getNumber(); + O << "\t\"BB#" << BB << "\" [ shape=box ]\n" + << '\t' << G.getBundle(BB, false) << " -> \"BB#" << BB << "\"\n" + << "\t\"BB#" << BB << "\" -> " << G.getBundle(BB, true) << '\n'; + for (MachineBasicBlock::const_succ_iterator SI = I->succ_begin(), + SE = I->succ_end(); SI != SE; ++SI) + O << "\t\"BB#" << BB << "\" -> \"BB#" << (*SI)->getNumber() + << "\" [ color=lightgray ]\n"; + } + O << "}\n"; + return O; +} + + Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=122832&r1=122831&r2=122832&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.cpp (original) +++ llvm/trunk/lib/CodeGen/SplitKit.cpp Tue Jan 4 15:10:05 2011 @@ -24,7 +24,6 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/GraphWriter.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" @@ -36,56 +35,6 @@ cl::desc("Allow critical edge splitting during spilling")); //===----------------------------------------------------------------------===// -// Edge Bundles -//===----------------------------------------------------------------------===// - -/// compute - Compute the edge bundles for MF. Bundles depend only on the CFG. -void EdgeBundles::compute(const MachineFunction *mf) { - MF = mf; - EC.clear(); - EC.grow(2 * MF->size()); - - for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E; - ++I) { - const MachineBasicBlock &MBB = *I; - unsigned OutE = 2 * MBB.getNumber() + 1; - // Join the outgoing bundle with the ingoing bundles of all successors. - for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(), - SE = MBB.succ_end(); SI != SE; ++SI) - EC.join(OutE, 2 * (*SI)->getNumber()); - } - EC.compress(); -} - -/// view - Visualize the annotated bipartite CFG with Graphviz. -void EdgeBundles::view() const { - ViewGraph(*this, "EdgeBundles"); -} - -/// Specialize WriteGraph, the standard implementation won't work. -raw_ostream &llvm::WriteGraph(raw_ostream &O, const EdgeBundles &G, - bool ShortNames, - const std::string &Title) { - const MachineFunction *MF = G.getMachineFunction(); - - O << "digraph {\n"; - for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); - I != E; ++I) { - unsigned BB = I->getNumber(); - O << "\t\"BB#" << BB << "\" [ shape=box ]\n" - << '\t' << G.getBundle(BB, false) << " -> \"BB#" << BB << "\"\n" - << "\t\"BB#" << BB << "\" -> " << G.getBundle(BB, true) << '\n'; - for (MachineBasicBlock::const_succ_iterator SI = I->succ_begin(), - SE = I->succ_end(); SI != SE; ++SI) - O << "\t\"BB#" << BB << "\" -> \"BB#" << (*SI)->getNumber() - << "\" [ color=lightgray ]\n"; - } - O << "}\n"; - return O; -} - - -//===----------------------------------------------------------------------===// // Split Analysis //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/CodeGen/SplitKit.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.h?rev=122832&r1=122831&r2=122832&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.h (original) +++ llvm/trunk/lib/CodeGen/SplitKit.h Tue Jan 4 15:10:05 2011 @@ -1,4 +1,4 @@ -//===-------- SplitKit.cpp - Toolkit for splitting live ranges --*- C++ -*-===// +//===-------- SplitKit.h - Toolkit for splitting live ranges ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -13,12 +13,9 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/IntEqClasses.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/CodeGen/SlotIndexes.h" -#include - namespace llvm { class LiveInterval; @@ -40,39 +37,6 @@ typedef DomTreeNodeBase MachineDomTreeNode; -/// EdgeBundles - Group CFG edges into equivalence classes where registers must -/// be allocated identically. This annotates the CFG to form a bipartite graph -/// where each block is connected to an ingoing and an outgoing bundle. -/// Edge bundles are simply numbered, there is no object representation. -class EdgeBundles { - const MachineFunction *MF; - - /// EC - Each edge bundle is an equivalence class. The keys are: - /// 2*BB->getNumber() -> Ingoing bundle. - /// 2*BB->getNumber()+1 -> Outgoing bundle. - IntEqClasses EC; - -public: - /// compute - Compute the edge bundles for MF. Bundles depend only on the CFG. - void compute(const MachineFunction *MF); - - /// getBundle - Return the ingoing (Out = false) or outgoing (Out = true) - /// bundle number for basic block #N - unsigned getBundle(unsigned N, bool Out) const { return EC[2 * N + Out]; } - - /// getMachineFunction - Return the last machine function computed. - const MachineFunction *getMachineFunction() const { return MF; } - - /// view - Visualize the annotated bipartite CFG with Graphviz. - void view() const; -}; - -/// Specialize WriteGraph, the standard implementation won't work. -raw_ostream &WriteGraph(raw_ostream &O, const EdgeBundles &G, - bool ShortNames = false, - const std::string &Title = ""); - - /// SplitAnalysis - Analyze a LiveInterval, looking for live range splitting /// opportunities. class SplitAnalysis { Modified: llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp?rev=122832&r1=122831&r2=122832&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp Tue Jan 4 15:10:05 2011 @@ -32,6 +32,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/CodeGen/EdgeBundles.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -51,6 +52,7 @@ struct FPS : public MachineFunctionPass { static char ID; FPS() : MachineFunctionPass(ID) { + initializeEdgeBundlesPass(*PassRegistry::getPassRegistry()); // This is really only to keep valgrind quiet. // The logic in isLive() is too much for it. memset(Stack, 0, sizeof(Stack)); @@ -59,6 +61,7 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); + AU.addRequired(); AU.addPreservedID(MachineLoopInfoID); AU.addPreservedID(MachineDominatorsID); MachineFunctionPass::getAnalysisUsage(AU); From stoklund at 2pi.dk Tue Jan 4 15:10:11 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 04 Jan 2011 21:10:11 -0000 Subject: [llvm-commits] [llvm] r122833 - in /llvm/trunk: include/llvm/CodeGen/EdgeBundles.h lib/Target/X86/X86FloatingPoint.cpp Message-ID: <20110104211011.B49E72A6C12D@llvm.org> Author: stoklund Date: Tue Jan 4 15:10:11 2011 New Revision: 122833 URL: http://llvm.org/viewvc/llvm-project?rev=122833&view=rev Log: Use the EdgeBundles analysis in X86FloatingPoint instead of recomputing CFG bundles in the pass. Modified: llvm/trunk/include/llvm/CodeGen/EdgeBundles.h llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp Modified: llvm/trunk/include/llvm/CodeGen/EdgeBundles.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/EdgeBundles.h?rev=122833&r1=122832&r2=122833&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/EdgeBundles.h (original) +++ llvm/trunk/include/llvm/CodeGen/EdgeBundles.h Tue Jan 4 15:10:11 2011 @@ -37,6 +37,9 @@ /// bundle number for basic block #N unsigned getBundle(unsigned N, bool Out) const { return EC[2 * N + Out]; } + /// getNumBundles - Return the total number of bundles in the CFG. + unsigned getNumBundles() const { return EC.getNumClasses(); } + /// getMachineFunction - Return the last machine function computed. const MachineFunction *getMachineFunction() const { return MF; } Modified: llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp?rev=122833&r1=122832&r2=122833&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp Tue Jan 4 15:10:11 2011 @@ -97,7 +97,7 @@ // FixStack[i] == getStackEntry(i) for all i < FixCount. unsigned char FixStack[8]; - LiveBundle(unsigned m = 0) : Mask(m), FixCount(0) {} + LiveBundle() : Mask(0), FixCount(0) {} // Have the live registers been assigned a stack order yet? bool isFixed() const { return !Mask || FixCount; } @@ -107,10 +107,8 @@ // with no live FP registers. SmallVector LiveBundles; - // Map each MBB in the current function to an (ingoing, outgoing) index into - // LiveBundles. Blocks with no FP registers live in or out map to (0, 0) - // and are not actually stored in the map. - DenseMap > BlockBundle; + // The edge bundle analysis provides indices into the LiveBundles vector. + EdgeBundles *Bundles; // Return a bitmask of FP registers in block's live-in list. unsigned calcLiveInMask(MachineBasicBlock *MBB) { @@ -287,6 +285,7 @@ // Early exit. if (!FPIsUsed) return false; + Bundles = &getAnalysis(); TII = MF.getTarget().getInstrInfo(); // Prepare cross-MBB liveness. @@ -311,7 +310,6 @@ if (Processed.insert(BB)) Changed |= processBasicBlock(MF, *BB); - BlockBundle.clear(); LiveBundles.clear(); return Changed; @@ -324,90 +322,16 @@ /// registers may be implicitly defined, or not used by all successors. void FPS::bundleCFG(MachineFunction &MF) { assert(LiveBundles.empty() && "Stale data in LiveBundles"); - assert(BlockBundle.empty() && "Stale data in BlockBundle"); - SmallPtrSet PropDown, PropUp; + LiveBundles.resize(Bundles->getNumBundles()); - // LiveBundle[0] is the empty live-in set. - LiveBundles.resize(1); - - // First gather the actual live-in masks for all MBBs. + // Gather the actual live-in masks for all MBBs. for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { MachineBasicBlock *MBB = I; const unsigned Mask = calcLiveInMask(MBB); if (!Mask) continue; - // Ingoing bundle index. - unsigned &Idx = BlockBundle[MBB].first; - // Already assigned an ingoing bundle? - if (Idx) - continue; - // Allocate a new LiveBundle struct for this block's live-ins. - const unsigned BundleIdx = Idx = LiveBundles.size(); - DEBUG(dbgs() << "Creating LB#" << BundleIdx << ": in:BB#" - << MBB->getNumber()); - LiveBundles.push_back(Mask); - LiveBundle &Bundle = LiveBundles.back(); - - // Make sure all predecessors have the same live-out set. - PropUp.insert(MBB); - - // Keep pushing liveness up and down the CFG until convergence. - // Only critical edges cause iteration here, but when they do, multiple - // blocks can be assigned to the same LiveBundle index. - do { - // Assign BundleIdx as liveout from predecessors in PropUp. - for (SmallPtrSet::iterator I = PropUp.begin(), - E = PropUp.end(); I != E; ++I) { - MachineBasicBlock *MBB = *I; - for (MachineBasicBlock::const_pred_iterator LinkI = MBB->pred_begin(), - LinkE = MBB->pred_end(); LinkI != LinkE; ++LinkI) { - MachineBasicBlock *PredMBB = *LinkI; - // PredMBB's liveout bundle should be set to LIIdx. - unsigned &Idx = BlockBundle[PredMBB].second; - if (Idx) { - assert(Idx == BundleIdx && "Inconsistent CFG"); - continue; - } - Idx = BundleIdx; - DEBUG(dbgs() << " out:BB#" << PredMBB->getNumber()); - // Propagate to siblings. - if (PredMBB->succ_size() > 1) - PropDown.insert(PredMBB); - } - } - PropUp.clear(); - - // Assign BundleIdx as livein to successors in PropDown. - for (SmallPtrSet::iterator I = PropDown.begin(), - E = PropDown.end(); I != E; ++I) { - MachineBasicBlock *MBB = *I; - for (MachineBasicBlock::const_succ_iterator LinkI = MBB->succ_begin(), - LinkE = MBB->succ_end(); LinkI != LinkE; ++LinkI) { - MachineBasicBlock *SuccMBB = *LinkI; - // LinkMBB's livein bundle should be set to BundleIdx. - unsigned &Idx = BlockBundle[SuccMBB].first; - if (Idx) { - assert(Idx == BundleIdx && "Inconsistent CFG"); - continue; - } - Idx = BundleIdx; - DEBUG(dbgs() << " in:BB#" << SuccMBB->getNumber()); - // Propagate to siblings. - if (SuccMBB->pred_size() > 1) - PropUp.insert(SuccMBB); - // Also accumulate the bundle liveness mask from the liveins here. - Bundle.Mask |= calcLiveInMask(SuccMBB); - } - } - PropDown.clear(); - } while (!PropUp.empty()); - DEBUG({ - dbgs() << " live:"; - for (unsigned i = 0; i < 8; ++i) - if (Bundle.Mask & (1<getBundle(MBB->getNumber(), false)].Mask |= Mask; } } @@ -495,13 +419,15 @@ return Changed; } -/// setupBlockStack - Use the BlockBundle map to set up our model of the stack +/// setupBlockStack - Use the live bundles to set up our model of the stack /// to match predecessors' live out stack. void FPS::setupBlockStack() { DEBUG(dbgs() << "\nSetting up live-ins for BB#" << MBB->getNumber() << " derived from " << MBB->getName() << ".\n"); StackTop = 0; - const LiveBundle &Bundle = LiveBundles[BlockBundle.lookup(MBB).first]; + // Get the live-in bundle for MBB. + const LiveBundle &Bundle = + LiveBundles[Bundles->getBundle(MBB->getNumber(), false)]; if (!Bundle.Mask) { DEBUG(dbgs() << "Block has no FP live-ins.\n"); @@ -538,7 +464,8 @@ DEBUG(dbgs() << "Setting up live-outs for BB#" << MBB->getNumber() << " derived from " << MBB->getName() << ".\n"); - unsigned BundleIdx = BlockBundle.lookup(MBB).second; + // Get MBB's live-out bundle. + unsigned BundleIdx = Bundles->getBundle(MBB->getNumber(), true); LiveBundle &Bundle = LiveBundles[BundleIdx]; // We may need to kill and define some registers to match successors. From clattner at apple.com Tue Jan 4 15:29:14 2011 From: clattner at apple.com (Chris Lattner) Date: Tue, 4 Jan 2011 13:29:14 -0800 Subject: [llvm-commits] [llvm] r122819 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp In-Reply-To: <20110104185418.581862A6C12C@llvm.org> References: <20110104185418.581862A6C12C@llvm.org> Message-ID: <514B69D5-B213-497B-A91A-3A4E6ACF17CA@apple.com> On Jan 4, 2011, at 10:54 AM, Owen Anderson wrote: > Author: resistor > Date: Tue Jan 4 12:54:18 2011 > New Revision: 122819 > > URL: http://llvm.org/viewvc/llvm-project?rev=122819&view=rev > Log: > Branch instructions don't produce values, so there's no need to generate a value number for them. This > avoids adding them to the various value numbering tables, resulting in a minor (~3%) speedup for GVN > on 40.gcc. Is there a way to handle "everything that returns void" in one place? Stores are pretty common as well. -Chris From resistor at mac.com Tue Jan 4 15:32:20 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 04 Jan 2011 13:32:20 -0800 Subject: [llvm-commits] [llvm] r122819 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp In-Reply-To: <514B69D5-B213-497B-A91A-3A4E6ACF17CA@apple.com> References: <20110104185418.581862A6C12C@llvm.org> <514B69D5-B213-497B-A91A-3A4E6ACF17CA@apple.com> Message-ID: <4A44F587-84E9-4CDB-8C21-050BFBDC8B8A@mac.com> On Jan 4, 2011, at 1:29 PM, Chris Lattner wrote: > > On Jan 4, 2011, at 10:54 AM, Owen Anderson wrote: > >> Author: resistor >> Date: Tue Jan 4 12:54:18 2011 >> New Revision: 122819 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122819&view=rev >> Log: >> Branch instructions don't produce values, so there's no need to generate a value number for them. This >> avoids adding them to the various value numbering tables, resulting in a minor (~3%) speedup for GVN >> on 40.gcc. > > Is there a way to handle "everything that returns void" in one place? Stores are pretty common as well. > > -Chris I actually experimented with adding a check for stores to do the same thing when I was writing this patch, but it made absolutely no difference in GVN's runtime. --Owen -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110104/0c890efc/attachment.html From clattner at apple.com Tue Jan 4 15:33:11 2011 From: clattner at apple.com (Chris Lattner) Date: Tue, 4 Jan 2011 13:33:11 -0800 Subject: [llvm-commits] [llvm] r122819 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp In-Reply-To: <4A44F587-84E9-4CDB-8C21-050BFBDC8B8A@mac.com> References: <20110104185418.581862A6C12C@llvm.org> <514B69D5-B213-497B-A91A-3A4E6ACF17CA@apple.com> <4A44F587-84E9-4CDB-8C21-050BFBDC8B8A@mac.com> Message-ID: <712916B2-4F6A-42BD-BD82-D099018DDFA6@apple.com> On Jan 4, 2011, at 1:32 PM, Owen Anderson wrote: > > On Jan 4, 2011, at 1:29 PM, Chris Lattner wrote: > >> >> On Jan 4, 2011, at 10:54 AM, Owen Anderson wrote: >> >>> Author: resistor >>> Date: Tue Jan 4 12:54:18 2011 >>> New Revision: 122819 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=122819&view=rev >>> Log: >>> Branch instructions don't produce values, so there's no need to generate a value number for them. This >>> avoids adding them to the various value numbering tables, resulting in a minor (~3%) speedup for GVN >>> on 40.gcc. >> >> Is there a way to handle "everything that returns void" in one place? Stores are pretty common as well. >> >> -Chris > > I actually experimented with adding a check for stores to do the same thing when I was writing this patch, but it made absolutely no difference in GVN's runtime. How about I->getType()->isVoidTy()? -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110104/1eba21ce/attachment-0001.html From evan.cheng at apple.com Tue Jan 4 15:41:03 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 4 Jan 2011 13:41:03 -0800 Subject: [llvm-commits] [llvm] r122743 - /llvm/trunk/include/llvm/Support/StandardPasses.h In-Reply-To: <4AA9515B-5C13-4B04-845B-78B0AB45C2C9@apple.com> References: <20110103075318.909D72A6C12C@llvm.org> <4AA9515B-5C13-4B04-845B-78B0AB45C2C9@apple.com> Message-ID: On Jan 3, 2011, at 3:33 PM, Chris Lattner wrote: > > On Jan 3, 2011, at 3:28 PM, Evan Cheng wrote: > >> >> On Jan 3, 2011, at 10:11 AM, Chris Lattner wrote: >> >>> >>> On Jan 2, 2011, at 11:53 PM, Evan Cheng wrote: >>> >>>> Author: evancheng >>>> Date: Mon Jan 3 01:53:18 2011 >>>> New Revision: 122743 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=122743&view=rev >>>> Log: >>>> Undo what looks like accidental removal of an instcombine pass in r122740. >>> >>> This wasn't accidental, is there a reason you want an instcombine here? >> >> No reason other than it was there before r122740 (which is only supposed to add the earlycse pass). Are you certain there is no loss from removing this instcombine pass? > > I'm not certain that there is no loss in no cases, but the performance comparisons I did had it removed and the intention of earlycse is to subsume that particular run of instcombine. I can remove it again if you feel comfortable with it. Evan > > -Chris From rdivacky at freebsd.org Tue Jan 4 15:46:13 2011 From: rdivacky at freebsd.org (Roman Divacky) Date: Tue, 4 Jan 2011 22:46:13 +0100 Subject: [llvm-commits] [llvm] r122740 - /llvm/trunk/include/llvm/Support/StandardPasses.h In-Reply-To: <80947CB2-DC50-41C6-8105-25268BE779E0@apple.com> References: <20110103061909.6C80C2A6C12C@llvm.org> <20110103073709.GA89749@freebsd.org> <80947CB2-DC50-41C6-8105-25268BE779E0@apple.com> Message-ID: <20110104214613.GA85309@freebsd.org> On Mon, Jan 03, 2011 at 03:34:45PM -0800, Chris Lattner wrote: > On Jan 2, 2011, at 11:37 PM, Roman Divacky wrote: > > On Mon, Jan 03, 2011 at 06:19:09AM -0000, Chris Lattner wrote: > >> +++ llvm/trunk/include/llvm/Support/StandardPasses.h Mon Jan 3 00:19:09 2011 > >> @@ -129,9 +129,9 @@ > >> > >> // Start of function pass. > >> PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas > >> + PM->add(createEarlyCSEPass()); // Catch trivial redundancies > >> if (SimplifyLibCalls) > >> PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations > >> - PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. > > > > was removing the InstructionCombiningPass intended? > > > > gnu screen compiles to 344992 bytes without InstructionCombiningPass (as in trunk) > > but to 344624 bytes with the InstructionCombiningPass kept... > > Hi Roman, > > Can you please file a bug with a .i file (along with the flags you're building with) for one of the files that is smaller with instcombine? It is entirely possible that an extra loop gets unrolled now or something like that, but I'd like to verify. Thanks! http://llvm.org/bugs/show_bug.cgi?id=8904 From resistor at mac.com Tue Jan 4 16:15:21 2011 From: resistor at mac.com (Owen Anderson) Date: Tue, 04 Jan 2011 22:15:21 -0000 Subject: [llvm-commits] [llvm] r122844 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <20110104221521.C94782A6C12C@llvm.org> Author: resistor Date: Tue Jan 4 16:15:21 2011 New Revision: 122844 URL: http://llvm.org/viewvc/llvm-project?rev=122844&view=rev Log: Don't bother value numbering instructions with void types in GVN. In theory this should allow us to insert fewer things into the value numbering maps, but any speedup is beneath the noise threshold on my machine on 403.gcc. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=122844&r1=122843&r2=122844&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Jan 4 16:15:21 2011 @@ -1685,6 +1685,10 @@ return false; } + // Instructions with void type don't return a value, so there's + // no point in trying to find redudancies in them. + if (I->getType()->isVoidTy()) return false; + uint32_t NextNum = VN.getNextUnusedValueNumber(); unsigned Num = VN.lookup_or_add(I); From echristo at apple.com Tue Jan 4 16:31:50 2011 From: echristo at apple.com (Eric Christopher) Date: Tue, 04 Jan 2011 22:31:50 -0000 Subject: [llvm-commits] [llvm] r122849 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <20110104223150.6027D2A6C12C@llvm.org> Author: echristo Date: Tue Jan 4 16:31:50 2011 New Revision: 122849 URL: http://llvm.org/viewvc/llvm-project?rev=122849&view=rev Log: Remove TODO, these appear to be implemented. 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=122849&r1=122848&r2=122849&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Jan 4 16:31:50 2011 @@ -2600,7 +2600,6 @@ // By default, atomic intrinsics are marked Legal and lowered. Targets // which don't support them directly, however, may want libcalls, in which // case they mark them Expand, and we get here. - // FIXME: Unimplemented for now. Add libcalls. case ISD::ATOMIC_SWAP: case ISD::ATOMIC_LOAD_ADD: case ISD::ATOMIC_LOAD_SUB: From sabre at nondot.org Tue Jan 4 19:03:32 2011 From: sabre at nondot.org (Chris Lattner) Date: Wed, 05 Jan 2011 01:03:32 -0000 Subject: [llvm-commits] [llvm] r122854 - /llvm/trunk/include/llvm/Support/StandardPasses.h Message-ID: <20110105010332.31B652A6C12C@llvm.org> Author: lattner Date: Tue Jan 4 19:03:32 2011 New Revision: 122854 URL: http://llvm.org/viewvc/llvm-project?rev=122854&view=rev Log: Fix PR8906: -fno-builtin should disable loop-idiom recognition. It forms memset and memcpy's, and will someday form popcount and other stuff. All of this is bad when compiling the implementation of memset, memcpy, popcount, etc. Modified: llvm/trunk/include/llvm/Support/StandardPasses.h Modified: llvm/trunk/include/llvm/Support/StandardPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=122854&r1=122853&r2=122854&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) +++ llvm/trunk/include/llvm/Support/StandardPasses.h Tue Jan 4 19:03:32 2011 @@ -97,7 +97,7 @@ bool OptimizeSize, bool UnitAtATime, bool UnrollLoops, - bool SimplifyLibCalls, + bool OptimizeBuiltins, bool HaveExceptions, Pass *InliningPass) { createStandardAliasAnalysisPasses(PM); @@ -130,7 +130,7 @@ // Start of function pass. PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas PM->add(createEarlyCSEPass()); // Catch trivial redundancies - if (SimplifyLibCalls) + if (OptimizeBuiltins) PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. PM->add(createJumpThreadingPass()); // Thread jumps. @@ -146,7 +146,8 @@ PM->add(createLoopUnswitchPass(OptimizeSize || OptimizationLevel < 3)); PM->add(createInstructionCombiningPass()); PM->add(createIndVarSimplifyPass()); // Canonicalize indvars - PM->add(createLoopIdiomPass()); // Recognize idioms like memset. + if (OptimizeBuiltins) + PM->add(createLoopIdiomPass()); // Recognize idioms like memset. PM->add(createLoopDeletionPass()); // Delete dead loops if (UnrollLoops) PM->add(createLoopUnrollPass()); // Unroll small loops From bob.wilson at apple.com Tue Jan 4 19:26:06 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 4 Jan 2011 17:26:06 -0800 Subject: [llvm-commits] [llvm] r122743 - /llvm/trunk/include/llvm/Support/StandardPasses.h In-Reply-To: References: <20110103075318.909D72A6C12C@llvm.org> <4AA9515B-5C13-4B04-845B-78B0AB45C2C9@apple.com> Message-ID: <6B4634E5-C461-4197-B791-A889DAAB221F@apple.com> On Jan 4, 2011, at 1:41 PM, Evan Cheng wrote: > > On Jan 3, 2011, at 3:33 PM, Chris Lattner wrote: > >> >> On Jan 3, 2011, at 3:28 PM, Evan Cheng wrote: >> >>> >>> On Jan 3, 2011, at 10:11 AM, Chris Lattner wrote: >>> >>>> >>>> On Jan 2, 2011, at 11:53 PM, Evan Cheng wrote: >>>> >>>>> Author: evancheng >>>>> Date: Mon Jan 3 01:53:18 2011 >>>>> New Revision: 122743 >>>>> >>>>> URL: http://llvm.org/viewvc/llvm-project?rev=122743&view=rev >>>>> Log: >>>>> Undo what looks like accidental removal of an instcombine pass in r122740. >>>> >>>> This wasn't accidental, is there a reason you want an instcombine here? >>> >>> No reason other than it was there before r122740 (which is only supposed to add the earlycse pass). Are you certain there is no loss from removing this instcombine pass? >> >> I'm not certain that there is no loss in no cases, but the performance comparisons I did had it removed and the intention of earlycse is to subsume that particular run of instcombine. > > I can remove it again if you feel comfortable with it. Bisecting the i386 chomp regression (http://llvm.org/perf/db_default/simple/nts/65/) blames the change that adds the instcombine pass back again. I haven't yet verified that removing it fixes the regression. I would not have expected that! From pichet2000 at gmail.com Tue Jan 4 19:30:20 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Tue, 4 Jan 2011 20:30:20 -0500 Subject: [llvm-commits] [llvm] r122754 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py In-Reply-To: References: <20110103173025.CCF792A6C12C@llvm.org> Message-ID: On Tue, Jan 4, 2011 at 10:20 AM, David A. Greene wrote: > Francois Pichet writes: > > > On Mon, Jan 3, 2011 at 12:30 PM, David Greene > wrote: > > > > Author: greened > > Date: Mon Jan 3 11:30:25 2011 > > New Revision: 122754 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=122754&view=rev > > Log: > > > > Reapply 122341 to fix PR8199 now that clang changes are in. > > > > Modified: > > llvm/trunk/docs/TestingGuide.html > > llvm/trunk/test/lit.cfg > > llvm/trunk/utils/lit/lit/TestRunner.py > > > > Hi, > > > > I disabled that fix on Windows. It doesn't work at all and cause all lit > tests to fail. > > Any ideas why? > > No. Do you have test output you can post? > > -Dave > Hi, example: 1>Exit Code: 1 1>Command Output (stdout): 1>-- 1>Command 0: "D:/Dev/llvm/llvm_trunk/bin/Release\clang.EXE" "-cc1" "-fsyntax-only" "-verify" "D:\Dev\llvm\llvm_trunk" "ools\clang" "est\CXX\special\class.ctor\p1.cpp" 1>Command 0 Result: 1 1>Command 0 Output: 1>Command 0 Stderr: 1>error: 'error' diagnostics seen but not expected: 1> (frontend): error reading 'D:\Dev\llvm\llvm_trunk' 1>error: 'error' diagnostics seen but not expected: 1> (frontend): error reading 'ools\clang' 1>error: 'error' diagnostics seen but not expected: 1> (frontend): error reading 'est\CXX\special\class.ctor\p1.cpp' 1>3 errors generated. 1>-- Notice how the file to test is cut in 3. I suspect a separator issue (backslash)? I currently don't have the time to investigate this problem. But with my patch r122808 all tests pass. (maybe we are lucky). If you don't know, I'll try to understand what really happen this weekend. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110104/abeb4c84/attachment.html From zwarich at apple.com Tue Jan 4 23:15:53 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 05 Jan 2011 05:15:53 -0000 Subject: [llvm-commits] [llvm] r122868 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Message-ID: <20110105051553.6AD372A6C12C@llvm.org> Author: zwarich Date: Tue Jan 4 23:15:53 2011 New Revision: 122868 URL: http://llvm.org/viewvc/llvm-project?rev=122868&view=rev Log: Change LoopInstSimplify back to a LoopPass. It revisits subloops rather than skipping them, but it should probably use a worklist and only revisit those instructions in subloops that have actually changed. It should probably also use a worklist after the first iteration like instsimplify now does. Regardless, it's only 0.3% of opt -O2 time on 403.gcc if it replaces the instcombine placed in the middle of the loop passes. Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp?rev=122868&r1=122867&r2=122868&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Tue Jan 4 23:15:53 2011 @@ -12,11 +12,11 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "loop-instsimplify" -#include "llvm/Function.h" -#include "llvm/Pass.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Support/Debug.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Local.h" @@ -26,19 +26,19 @@ STATISTIC(NumSimplified, "Number of redundant instructions simplified"); namespace { - class LoopInstSimplify : public FunctionPass { + class LoopInstSimplify : public LoopPass { public: static char ID; // Pass ID, replacement for typeid - LoopInstSimplify() : FunctionPass(ID) { + LoopInstSimplify() : LoopPass(ID) { initializeLoopInstSimplifyPass(*PassRegistry::getPassRegistry()); } - bool runOnFunction(Function &); + bool runOnLoop(Loop*, LPPassManager&); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired(); - AU.addPreserved(); + AU.addRequiredID(LoopSimplifyID); AU.addPreservedID(LCSSAID); } }; @@ -57,19 +57,34 @@ return new LoopInstSimplify(); } -bool LoopInstSimplify::runOnFunction(Function &F) { +bool LoopInstSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { DominatorTree *DT = getAnalysisIfAvailable(); LoopInfo *LI = &getAnalysis(); const TargetData *TD = getAnalysisIfAvailable(); + SmallVector ExitBlocks; + L->getUniqueExitBlocks(ExitBlocks); + array_pod_sort(ExitBlocks.begin(), ExitBlocks.end()); + + SmallVector VisitStack; + SmallPtrSet Visited; + bool Changed = false; bool LocalChanged; do { LocalChanged = false; - for (df_iterator DI = df_begin(&F.getEntryBlock()), - DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) - for (BasicBlock::iterator BI = DI->begin(), BE = DI->end(); BI != BE;) { + VisitStack.clear(); + Visited.clear(); + + VisitStack.push_back(L->getHeader()); + + while (!VisitStack.empty()) { + BasicBlock *BB = VisitStack.back(); + VisitStack.pop_back(); + + // Simplify instructions in the current basic block. + for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { Instruction *I = BI++; // Don't bother simplifying unused instructions. if (!I->use_empty()) { @@ -83,6 +98,17 @@ LocalChanged |= RecursivelyDeleteTriviallyDeadInstructions(I); } + // Add all successors to the worklist, except for loop exit blocks. + for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; + ++SI) { + BasicBlock *SuccBB = *SI; + bool IsExitBlock = std::binary_search(ExitBlocks.begin(), + ExitBlocks.end(), SuccBB); + if (!IsExitBlock && Visited.insert(SuccBB)) + VisitStack.push_back(SuccBB); + } + } + Changed |= LocalChanged; } while (LocalChanged); From zwarich at apple.com Tue Jan 4 23:47:47 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 05 Jan 2011 05:47:47 -0000 Subject: [llvm-commits] [llvm] r122869 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Message-ID: <20110105054747.33F2E2A6C12C@llvm.org> Author: zwarich Date: Tue Jan 4 23:47:47 2011 New Revision: 122869 URL: http://llvm.org/viewvc/llvm-project?rev=122869&view=rev Log: Use a worklist for later iterations just like ordinary instsimplify. The next step is to only process instructions in subloops if they have been modified by an earlier simplification. Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp?rev=122869&r1=122868&r2=122869&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Tue Jan 4 23:47:47 2011 @@ -66,6 +66,8 @@ L->getUniqueExitBlocks(ExitBlocks); array_pod_sort(ExitBlocks.begin(), ExitBlocks.end()); + SmallPtrSet S1, S2, *ToSimplify = &S1, *Next = &S2; + SmallVector VisitStack; SmallPtrSet Visited; @@ -86,10 +88,22 @@ // Simplify instructions in the current basic block. for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { Instruction *I = BI++; + + // The first time through the loop ToSimplify is empty and we try to + // simplify all instructions. On later iterations ToSimplify is not + // empty and we only bother simplifying instructions that are in it. + if (!ToSimplify->empty() && !ToSimplify->count(I)) + continue; + // Don't bother simplifying unused instructions. if (!I->use_empty()) { Value *V = SimplifyInstruction(I, TD, DT); if (V && LI->replacementPreservesLCSSAForm(I, V)) { + // Mark all uses for resimplification next time round the loop. + for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); + UI != UE; ++UI) + Next->insert(cast(*UI)); + I->replaceAllUsesWith(V); LocalChanged = true; ++NumSimplified; @@ -109,6 +123,11 @@ } } + // Place the list of instructions to simplify on the next loop iteration + // into ToSimplify. + std::swap(ToSimplify, Next); + Next->clear(); + Changed |= LocalChanged; } while (LocalChanged); From baldrick at free.fr Wed Jan 5 01:34:25 2011 From: baldrick at free.fr (Duncan Sands) Date: Wed, 05 Jan 2011 08:34:25 +0100 Subject: [llvm-commits] [llvm] r122868 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp In-Reply-To: <20110105051553.6AD372A6C12C@llvm.org> References: <20110105051553.6AD372A6C12C@llvm.org> Message-ID: <4D241F01.7080105@free.fr> Hi Cameron, > + while (!VisitStack.empty()) { > + BasicBlock *BB = VisitStack.back(); > + VisitStack.pop_back(); the above two lines can be replaced with one using pop_back_val. Ciao, Duncan. From aggarwa4 at illinois.edu Wed Jan 5 04:41:42 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Wed, 05 Jan 2011 10:41:42 -0000 Subject: [llvm-commits] [poolalloc] r122870 - /poolalloc/trunk/lib/PoolAllocate/AllNodesHeuristic.cpp Message-ID: <20110105104142.34D152A6C12C@llvm.org> Author: aggarwa4 Date: Wed Jan 5 04:41:42 2011 New Revision: 122870 URL: http://llvm.org/viewvc/llvm-project?rev=122870&view=rev Log: This code seems to cause 254.gap to fail. Commenting while we investigate. Modified: poolalloc/trunk/lib/PoolAllocate/AllNodesHeuristic.cpp Modified: poolalloc/trunk/lib/PoolAllocate/AllNodesHeuristic.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/AllNodesHeuristic.cpp?rev=122870&r1=122869&r2=122870&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/AllNodesHeuristic.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/AllNodesHeuristic.cpp Wed Jan 5 04:41:42 2011 @@ -72,7 +72,7 @@ // // Remove those global nodes which we know will never be pool allocated. // - std::vector toRemove; + /*std::vector toRemove; for (DenseSet::iterator I = NodesFromGlobals.begin(), E = NodesFromGlobals.end(); I != E; ) { DenseSet::iterator Last = I; ++I; @@ -91,7 +91,7 @@ // for (unsigned index = 0; index < toRemove.size(); ++index) { NodesFromGlobals.erase(toRemove[index]); - } + }*/ // // Now the fun part. Find DSNodes in the local graph that correspond to From fvbommel at gmail.com Wed Jan 5 09:10:24 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Wed, 05 Jan 2011 15:10:24 -0000 Subject: [llvm-commits] [llvm] r122873 - /llvm/trunk/test/lit.cfg Message-ID: <20110105151024.6F7E22A6C12C@llvm.org> Author: fvbommel Date: Wed Jan 5 09:10:24 2011 New Revision: 122873 URL: http://llvm.org/viewvc/llvm-project?rev=122873&view=rev Log: Fix lit for people whose LLVM path contains 'opt', which is a common directory name on Unix-like systems. Modified: llvm/trunk/test/lit.cfg Modified: llvm/trunk/test/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=122873&r1=122872&r2=122873&view=diff ============================================================================== --- llvm/trunk/test/lit.cfg (original) +++ llvm/trunk/test/lit.cfg Wed Jan 5 09:10:24 2011 @@ -176,9 +176,9 @@ r"\bllvm-stub\b", r"\bllvm2cpp\b", # Don't match '-llvmc'. r"(? http://llvm.org/bugs/show_bug.cgi?id=889 This bug is about removing virtual methods from Value and its subclasses. While playing with fixes for this bug, I noticed that FixedNumOperandTraits and VariadicOperandTraits only work for subclasses of User, where the instance data for User is at offset 0 in the instance data for the subclass. However, if the subclass has virtual methods but User does not, this is no longer true. (There are probably other cases where it would not be true, e.g. for a subclass that inherits from multiple base classes, and User is not the first base class.) The attached patch fixes this by making FixedNumOperandTraits and VariadicOperandTraits take an extra template argument specifying the type of the subclass. It passes "make check". OK to commit? Thanks, Jay. -------------- next part -------------- A non-text attachment was scrubbed... Name: fix-operandtraits Type: application/octet-stream Size: 12497 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110105/0ca618b9/attachment.obj From zwarich at apple.com Wed Jan 5 10:08:47 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 05 Jan 2011 16:08:47 -0000 Subject: [llvm-commits] [llvm] r122876 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Message-ID: <20110105160847.EDFEF2A6C12C@llvm.org> Author: zwarich Date: Wed Jan 5 10:08:47 2011 New Revision: 122876 URL: http://llvm.org/viewvc/llvm-project?rev=122876&view=rev Log: Use pop_back_val instead of back followed by pop_back. Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp?rev=122876&r1=122875&r2=122876&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Wed Jan 5 10:08:47 2011 @@ -82,8 +82,7 @@ VisitStack.push_back(L->getHeader()); while (!VisitStack.empty()) { - BasicBlock *BB = VisitStack.back(); - VisitStack.pop_back(); + BasicBlock *BB = VisitStack.pop_back_val(); // Simplify instructions in the current basic block. for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { From bigcheesegs at gmail.com Wed Jan 5 10:38:57 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Wed, 05 Jan 2011 16:38:57 -0000 Subject: [llvm-commits] [llvm] r122879 - in /llvm/trunk: lib/Support/Unix/PathV2.inc unittests/Support/Path.cpp Message-ID: <20110105163857.691762A6C12E@llvm.org> Author: mspencer Date: Wed Jan 5 10:38:57 2011 New Revision: 122879 URL: http://llvm.org/viewvc/llvm-project?rev=122879&view=rev Log: Support/PathV2: Implement directory iteration on POSIX. Modified: llvm/trunk/lib/Support/Unix/PathV2.inc llvm/trunk/unittests/Support/Path.cpp Modified: llvm/trunk/lib/Support/Unix/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/PathV2.inc?rev=122879&r1=122878&r2=122879&view=diff ============================================================================== --- llvm/trunk/lib/Support/Unix/PathV2.inc (original) +++ llvm/trunk/lib/Support/Unix/PathV2.inc Wed Jan 5 10:38:57 2011 @@ -23,6 +23,22 @@ #if HAVE_FCNTL_H #include #endif +#if HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +#endif #if HAVE_STDIO_H #include #endif @@ -408,6 +424,44 @@ return success; } +error_code directory_iterator_construct(directory_iterator &it, StringRef path){ + SmallString<128> path_null(path); + DIR *directory = ::opendir(path_null.c_str()); + if (directory == 0) + return error_code(errno, system_category()); + + it.IterationHandle = reinterpret_cast(directory); + // Add something for replace_filename to replace. + path::append(path_null, "."); + it.CurrentEntry = directory_entry(path_null.str()); + return directory_iterator_increment(it); +} + +error_code directory_iterator_destruct(directory_iterator& it) { + if (it.IterationHandle) + ::closedir(reinterpret_cast(it.IterationHandle)); + it.IterationHandle = 0; + it.CurrentEntry = directory_entry(); + return success; +} + +error_code directory_iterator_increment(directory_iterator& it) { + errno = 0; + dirent *cur_dir = ::readdir(reinterpret_cast(it.IterationHandle)); + if (cur_dir == 0 && errno != 0) { + return error_code(errno, system_category()); + } else if (cur_dir != 0) { + StringRef name(cur_dir->d_name, NAMLEN(cur_dir)); + if ((name.size() == 1 && name[0] == '.') || + (name.size() == 2 && name[0] == '.' && name[1] == '.')) + return directory_iterator_increment(it); + it.CurrentEntry.replace_filename(name); + } else + return directory_iterator_destruct(it); + + return success; +} + } // end namespace fs } // end namespace sys } // end namespace llvm Modified: llvm/trunk/unittests/Support/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Path.cpp?rev=122879&r1=122878&r2=122879&view=diff ============================================================================== --- llvm/trunk/unittests/Support/Path.cpp (original) +++ llvm/trunk/unittests/Support/Path.cpp Wed Jan 5 10:38:57 2011 @@ -176,8 +176,6 @@ ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists)); EXPECT_FALSE(TempFileExists); - // I've yet to do directory iteration on Unix. -#ifdef LLVM_ON_WIN32 error_code ec; for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec)) { if (ec) { @@ -186,7 +184,6 @@ report_fatal_error("Directory iteration failed!"); } } -#endif } } // anonymous namespace From bigcheesegs at gmail.com Wed Jan 5 10:39:05 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Wed, 05 Jan 2011 16:39:05 -0000 Subject: [llvm-commits] [llvm] r122880 - /llvm/trunk/unittests/Support/Path.cpp Message-ID: <20110105163905.5642E2A6C12E@llvm.org> Author: mspencer Date: Wed Jan 5 10:39:05 2011 New Revision: 122880 URL: http://llvm.org/viewvc/llvm-project?rev=122880&view=rev Log: UnitTests/PathV2: Setup a test fixture to make tracking created file system entities easier. Modified: llvm/trunk/unittests/Support/Path.cpp Modified: llvm/trunk/unittests/Support/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Path.cpp?rev=122880&r1=122879&r2=122880&view=diff ============================================================================== --- llvm/trunk/unittests/Support/Path.cpp (original) +++ llvm/trunk/unittests/Support/Path.cpp Wed Jan 5 10:39:05 2011 @@ -123,7 +123,29 @@ path::native(*i, temp_store); } +} + +class FileSystemTest : public testing::Test { +protected: + /// Unique temporary directory in which all created filesystem entities must + /// be placed. It is recursively removed at the end of each test. + SmallString<128> TestDirectory; + + virtual void SetUp() { + /*int fd; + ASSERT_NO_ERROR( + fs::unique_file("%%-%%-%%-%%/test-directory.anchor", fd, TestDirectory)); + // We don't care about this specific file. + ::close(fd);*/ + } + virtual void TearDown() { + /*uint32_t removed; + ASSERT_NO_ERROR(fs::remove_all(TestDirectory.str(), removed));*/ + } +}; + +TEST_F(FileSystemTest, TempFiles) { // Create a temp file. int FileDescriptor; SmallString<64> TempPath; @@ -175,7 +197,9 @@ // Make sure Temp1 doesn't exist. ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists)); EXPECT_FALSE(TempFileExists); +} +TEST_F(FileSystemTest, DirectoryIteration) { error_code ec; for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec)) { if (ec) { From bigcheesegs at gmail.com Wed Jan 5 10:39:13 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Wed, 05 Jan 2011 16:39:13 -0000 Subject: [llvm-commits] [llvm] r122881 - /llvm/trunk/lib/Support/PathV2.cpp Message-ID: <20110105163913.5B27C2A6C12E@llvm.org> Author: mspencer Date: Wed Jan 5 10:39:13 2011 New Revision: 122881 URL: http://llvm.org/viewvc/llvm-project?rev=122881&view=rev Log: Support/PathV2: Implement directory_entry::status. Modified: llvm/trunk/lib/Support/PathV2.cpp Modified: llvm/trunk/lib/Support/PathV2.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PathV2.cpp?rev=122881&r1=122880&r2=122881&view=diff ============================================================================== --- llvm/trunk/lib/Support/PathV2.cpp (original) +++ llvm/trunk/lib/Support/PathV2.cpp Wed Jan 5 10:39:13 2011 @@ -697,6 +697,10 @@ return success; } +error_code directory_entry::status(file_status &result) const { + return fs::status(Path, result); +} + } // end namespace fs } // end namespace sys } // end namespace llvm From bigcheesegs at gmail.com Wed Jan 5 10:39:22 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Wed, 05 Jan 2011 16:39:22 -0000 Subject: [llvm-commits] [llvm] r122882 - /llvm/trunk/lib/Support/Windows/PathV2.inc Message-ID: <20110105163922.2C4AC2A6C12F@llvm.org> Author: mspencer Date: Wed Jan 5 10:39:22 2011 New Revision: 122882 URL: http://llvm.org/viewvc/llvm-project?rev=122882&view=rev Log: Support/Windows/PathV2: Fix remove to handle both files and directories. Modified: llvm/trunk/lib/Support/Windows/PathV2.inc Modified: llvm/trunk/lib/Support/Windows/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/PathV2.inc?rev=122882&r1=122881&r2=122882&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/PathV2.inc (original) +++ llvm/trunk/lib/Support/Windows/PathV2.inc Wed Jan 5 10:39:22 2011 @@ -268,17 +268,31 @@ SmallString<128> path_storage; SmallVector path_utf16; + file_status st; + if (error_code ec = status(path, st)) + return ec; + if (error_code ec = UTF8ToUTF16(path.toStringRef(path_storage), path_utf16)) return ec; - if (!::DeleteFileW(path_utf16.begin())) { - error_code ec = windows_error(::GetLastError()); - if (ec != windows_error::file_not_found) - return ec; - existed = false; - } else - existed = true; + if (st.type() == file_type::directory_file) { + if (!::RemoveDirectoryW(c_str(path_utf16))) { + error_code ec = windows_error(::GetLastError()); + if (ec != windows_error::file_not_found) + return ec; + existed = false; + } else + existed = true; + } else { + if (!::DeleteFileW(c_str(path_utf16))) { + error_code ec = windows_error(::GetLastError()); + if (ec != windows_error::file_not_found) + return ec; + existed = false; + } else + existed = true; + } return success; } From bigcheesegs at gmail.com Wed Jan 5 10:39:30 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Wed, 05 Jan 2011 16:39:30 -0000 Subject: [llvm-commits] [llvm] r122883 - /llvm/trunk/lib/Support/Windows/PathV2.inc Message-ID: <20110105163930.D0C512A6C12E@llvm.org> Author: mspencer Date: Wed Jan 5 10:39:30 2011 New Revision: 122883 URL: http://llvm.org/viewvc/llvm-project?rev=122883&view=rev Log: Support/Windows/PathV2: Make directory iteration ignore . and .. Modified: llvm/trunk/lib/Support/Windows/PathV2.inc Modified: llvm/trunk/lib/Support/Windows/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/PathV2.inc?rev=122883&r1=122882&r2=122883&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/PathV2.inc (original) +++ llvm/trunk/lib/Support/Windows/PathV2.inc Wed Jan 5 10:39:30 2011 @@ -639,16 +639,30 @@ if (!FindHandle) return windows_error(::GetLastError()); + size_t FilenameLen = ::wcslen(FirstFind.cFileName); + while ((FilenameLen == 1 && FirstFind.cFileName[0] == L'.') || + (FilenameLen == 2 && FirstFind.cFileName[0] == L'.' && + FirstFind.cFileName[1] == L'.')) + if (!::FindNextFileW(FindHandle, &FirstFind)) { + error_code ec = windows_error(::GetLastError()); + // Check for end. + if (ec == windows_error::no_more_files) + return directory_iterator_destruct(it); + return ec; + } else + FilenameLen = ::wcslen(FirstFind.cFileName); + // Construct the current directory entry. - SmallString<128> directory_entry_path_utf8; + SmallString<128> directory_entry_name_utf8; if (error_code ec = UTF16ToUTF8(FirstFind.cFileName, ::wcslen(FirstFind.cFileName), - directory_entry_path_utf8)) + directory_entry_name_utf8)) return ec; it.IterationHandle = intptr_t(FindHandle.take()); - it.CurrentEntry = directory_entry(path); - it.CurrentEntry.replace_filename(Twine(directory_entry_path_utf8)); + SmallString<128> directory_entry_path(path); + path::append(directory_entry_path, directory_entry_name_utf8.str()); + it.CurrentEntry = directory_entry(directory_entry_path.str()); return success; } @@ -672,6 +686,12 @@ return ec; } + size_t FilenameLen = ::wcslen(FindData.cFileName); + if ((FilenameLen == 1 && FindData.cFileName[0] == L'.') || + (FilenameLen == 2 && FindData.cFileName[0] == L'.' && + FindData.cFileName[1] == L'.')) + return directory_iterator_increment(it); + SmallString<128> directory_entry_path_utf8; if (error_code ec = UTF16ToUTF8(FindData.cFileName, ::wcslen(FindData.cFileName), From bigcheesegs at gmail.com Wed Jan 5 10:39:38 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Wed, 05 Jan 2011 16:39:38 -0000 Subject: [llvm-commits] [llvm] r122884 - /llvm/trunk/lib/Support/PathV2.cpp Message-ID: <20110105163938.BB3522A6C12E@llvm.org> Author: mspencer Date: Wed Jan 5 10:39:38 2011 New Revision: 122884 URL: http://llvm.org/viewvc/llvm-project?rev=122884&view=rev Log: Support/PathV2: Implement remove_all. Modified: llvm/trunk/lib/Support/PathV2.cpp Modified: llvm/trunk/lib/Support/PathV2.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PathV2.cpp?rev=122884&r1=122883&r2=122884&view=diff ============================================================================== --- llvm/trunk/lib/Support/PathV2.cpp (original) +++ llvm/trunk/lib/Support/PathV2.cpp Wed Jan 5 10:39:38 2011 @@ -697,6 +697,43 @@ return success; } +namespace { +error_code remove_all_r(StringRef path, file_type ft, uint32_t &count) { + if (ft == file_type::directory_file) { + // This code would be a lot better with exceptions ;/. + error_code ec; + for (directory_iterator i(path, ec), e; i != e; i.increment(ec)) { + if (ec) return ec; + file_status st; + if (error_code ec = i->status(st)) return ec; + if (error_code ec = remove_all_r(i->path(), st.type(), count)) return ec; + } + bool obviously_this_exists; + if (error_code ec = remove(path, obviously_this_exists)) return ec; + assert(obviously_this_exists); + ++count; // Include the directory itself in the items removed. + } else { + bool obviously_this_exists; + if (error_code ec = remove(path, obviously_this_exists)) return ec; + assert(obviously_this_exists); + ++count; + } + + return success; +} +} + +error_code remove_all(const Twine &path, uint32_t &num_removed) { + SmallString<128> path_storage; + StringRef p = path.toStringRef(path_storage); + + file_status fs; + if (error_code ec = status(path, fs)) + return ec; + num_removed = 0; + return remove_all_r(p, fs.type(), num_removed); +} + error_code directory_entry::status(file_status &result) const { return fs::status(Path, result); } From bigcheesegs at gmail.com Wed Jan 5 10:39:46 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Wed, 05 Jan 2011 16:39:46 -0000 Subject: [llvm-commits] [llvm] r122885 - /llvm/trunk/unittests/Support/Path.cpp Message-ID: <20110105163946.5FAF42A6C12E@llvm.org> Author: mspencer Date: Wed Jan 5 10:39:46 2011 New Revision: 122885 URL: http://llvm.org/viewvc/llvm-project?rev=122885&view=rev Log: UnitTests/Path: Fix typo, add error number, and enable the directory cleanup code. Modified: llvm/trunk/unittests/Support/Path.cpp Modified: llvm/trunk/unittests/Support/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Path.cpp?rev=122885&r1=122884&r2=122885&view=diff ============================================================================== --- llvm/trunk/unittests/Support/Path.cpp (original) +++ llvm/trunk/unittests/Support/Path.cpp Wed Jan 5 10:39:46 2011 @@ -19,9 +19,10 @@ #define ASSERT_NO_ERROR(x) \ if (error_code ec = x) { \ SmallString<128> Message; \ - GTEST_FATAL_FAILURE_((Twine(#x) + ": did not return errc::success.\n" + \ + GTEST_FATAL_FAILURE_((Twine(#x ": did not return errc::success.\n") + \ + "error number: " + Twine(ec.value()) + "\n" + \ "error message: " + \ - x.message()).toNullTerminatedStringRef(Message).data()); \ + ec.message()).toNullTerminatedStringRef(Message).data()); \ } else {} namespace { @@ -132,16 +133,20 @@ SmallString<128> TestDirectory; virtual void SetUp() { - /*int fd; + int fd; ASSERT_NO_ERROR( - fs::unique_file("%%-%%-%%-%%/test-directory.anchor", fd, TestDirectory)); + fs::unique_file("file-system-test-%%-%%-%%-%%/test-directory.anchor", fd, + TestDirectory)); // We don't care about this specific file. - ::close(fd);*/ + ::close(fd); + TestDirectory = path::parent_path(TestDirectory); + errs() << "Test Directory: " << TestDirectory << '\n'; + errs().flush(); } virtual void TearDown() { - /*uint32_t removed; - ASSERT_NO_ERROR(fs::remove_all(TestDirectory.str(), removed));*/ + uint32_t removed; + ASSERT_NO_ERROR(fs::remove_all(TestDirectory.str(), removed)); } }; From peckw at wesleypeck.com Wed Jan 5 11:01:57 2011 From: peckw at wesleypeck.com (Wesley Peck) Date: Wed, 05 Jan 2011 17:01:57 -0000 Subject: [llvm-commits] [llvm] r122886 - /llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Message-ID: <20110105170157.5E23B2A6C12D@llvm.org> Author: peckw Date: Wed Jan 5 11:01:57 2011 New Revision: 122886 URL: http://llvm.org/viewvc/llvm-project?rev=122886&view=rev Log: Fix small bug in setDebugInfoAvailability. Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=122886&r1=122885&r2=122886&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Wed Jan 5 11:01:57 2011 @@ -209,7 +209,7 @@ /// hasDebugInfo - Returns true if valid debug info is present. /// bool hasDebugInfo() const { return DbgInfoAvailable; } - void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = true; } + void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = avail; } bool callsEHReturn() const { return CallsEHReturn; } void setCallsEHReturn(bool b) { CallsEHReturn = b; } From zwarich at apple.com Wed Jan 5 11:27:28 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 05 Jan 2011 17:27:28 -0000 Subject: [llvm-commits] [llvm] r122887 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <20110105172728.0EE162A6C12C@llvm.org> Author: zwarich Date: Wed Jan 5 11:27:27 2011 New Revision: 122887 URL: http://llvm.org/viewvc/llvm-project?rev=122887&view=rev Log: Add some stats to CodeGenPrepare to make it easier to speed it up without regressing code quality. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=122887&r1=122886&r2=122887&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Jan 5 11:27:27 2011 @@ -44,7 +44,15 @@ using namespace llvm; using namespace llvm::PatternMatch; -STATISTIC(NumElim, "Number of blocks eliminated"); +STATISTIC(NumBlocksElim, "Number of blocks eliminated"); +STATISTIC(NumCmpUses, "Number of uses of Cmp expressions replaced with uses of " + "sunken Cmps"); +STATISTIC(NumCastUses, "Number of uses of Cast expressions replaced with uses " + "of sunken Casts"); +STATISTIC(NumMemoryInsts, "Number of memory instructions whose address " + "computations were sunk"); +STATISTIC(NumExtsMoved, "Number of [s|z]ext instructions combined with loads"); +STATISTIC(NumExtUses, "Number of uses of [s|z]ext instructions optimized"); static cl::opt CriticalEdgeSplit("cgp-critical-edge-splitting", @@ -310,7 +318,7 @@ PFI->removeEdge(ProfileInfo::getEdge(BB, DestBB)); } BB->eraseFromParent(); - ++NumElim; + ++NumBlocksElim; DEBUG(dbgs() << "AFTER:\n" << *DestBB << "\n\n\n"); } @@ -489,6 +497,7 @@ // Replace a use of the cast with a use of the new cast. TheUse = InsertedCast; + ++NumCastUses; } // If we removed all uses, nuke the cast. @@ -546,6 +555,7 @@ // Replace a use of the cmp with a use of the new cmp. TheUse = InsertedCmp; + ++NumCmpUses; } // If we removed all uses, nuke the cmp. @@ -793,6 +803,7 @@ // we don't want to match some completely different instruction. SunkAddrs[Addr] = 0; } + ++NumMemoryInsts; return true; } @@ -858,6 +869,7 @@ // can fold it. I->removeFromParent(); I->insertAfter(LI); + ++NumExtsMoved; return true; } @@ -929,7 +941,7 @@ // Replace a use of the {s|z}ext source with a use of the result. TheUse = InsertedTrunc; - + ++NumExtUses; MadeChange = true; } From peckw at wesleypeck.com Wed Jan 5 11:34:20 2011 From: peckw at wesleypeck.com (Wesley Peck) Date: Wed, 05 Jan 2011 17:34:20 -0000 Subject: [llvm-commits] [llvm] r122889 - in /llvm/trunk/lib/Target/MBlaze: MBlazeFrameInfo.cpp MBlazeFrameInfo.h MBlazeMachineFunction.h Message-ID: <20110105173420.8DDF22A6C12C@llvm.org> Author: peckw Date: Wed Jan 5 11:34:20 2011 New Revision: 122889 URL: http://llvm.org/viewvc/llvm-project?rev=122889&view=rev Log: Commit 122778 broke DWARF debug output when using the MBlaze backend. Fixed by overriding TargetFrameInfo::getFrameIndexOffset to take into account the new frame index information. Modified: llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.h llvm/trunk/lib/Target/MBlaze/MBlazeMachineFunction.h Modified: llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp?rev=122889&r1=122888&r2=122889&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.cpp Wed Jan 5 11:34:20 2011 @@ -43,6 +43,7 @@ static void replaceFrameIndexes(MachineFunction &MF, SmallVector, 16> &FR) { MachineFrameInfo *MFI = MF.getFrameInfo(); + MBlazeFunctionInfo *MBlazeFI = MF.getInfo(); const SmallVector, 16>::iterator FRB = FR.begin(); const SmallVector, 16>::iterator FRE = FR.end(); @@ -50,6 +51,7 @@ for (; FRI != FRE; ++FRI) { MFI->RemoveStackObject(FRI->first); int NFI = MFI->CreateFixedObject(4, FRI->second, true); + MBlazeFI->recordReplacement(FRI->first, NFI); for (MachineFunction::iterator MB=MF.begin(), ME=MF.end(); MB!=ME; ++MB) { MachineBasicBlock::iterator MBB = MB->begin(); @@ -321,6 +323,14 @@ DEBUG(dbgs() << "Aligned Frame Size: " << FrameSize << "\n" ); } +int MBlazeFrameInfo::getFrameIndexOffset(const MachineFunction &MF, int FI) + const { + const MBlazeFunctionInfo *MBlazeFI = MF.getInfo(); + if (MBlazeFI->hasReplacement(FI)) + FI = MBlazeFI->getReplacement(FI); + return TargetFrameInfo::getFrameIndexOffset(MF,FI); +} + // hasFP - Return true if the specified function should have a dedicated frame // pointer register. This is true if the function has variable sized allocas or // if frame pointer elimination is disabled. Modified: llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.h?rev=122889&r1=122888&r2=122889&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.h (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeFrameInfo.h Wed Jan 5 11:34:20 2011 @@ -42,6 +42,8 @@ bool hasFP(const MachineFunction &MF) const; + int getFrameIndexOffset(const MachineFunction &MF, int FI) const; + virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS) const; }; Modified: llvm/trunk/lib/Target/MBlaze/MBlazeMachineFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeMachineFunction.h?rev=122889&r1=122888&r2=122889&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeMachineFunction.h (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeMachineFunction.h Wed Jan 5 11:34:20 2011 @@ -14,6 +14,7 @@ #ifndef MBLAZE_MACHINE_FUNCTION_INFO_H #define MBLAZE_MACHINE_FUNCTION_INFO_H +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/VectorExtras.h" #include "llvm/CodeGen/MachineFunction.h" @@ -63,6 +64,11 @@ SmallVector FnStoreVarArgs; bool HasStoreVarArgs; + // When determining the final stack layout some of the frame indexes may + // be replaced by new frame indexes that reside in the caller's stack + // frame. The replacements are recorded in this structure. + DenseMap FIReplacements; + /// SRetReturnReg - Some subtargets require that sret lowering includes /// returning the value of the returned struct in a register. This field /// holds the virtual register into which the sret argument is passed. @@ -115,6 +121,18 @@ const SmallVector& getLiveIn() const { return LiveInFI; } + void recordReplacement(int OFI, int NFI) { + FIReplacements.insert(std::make_pair(OFI,NFI)); + } + + bool hasReplacement(int OFI) const { + return FIReplacements.find(OFI) != FIReplacements.end(); + } + + int getReplacement(int OFI) const { + return FIReplacements.lookup(OFI); + } + void recordLoadArgsFI(int FI, int SPOffset) { if (!HasLoadArgs) HasLoadArgs=true; FnLoadArgs.push_back(MBlazeFIHolder(FI, SPOffset)); From zwarich at apple.com Wed Jan 5 11:47:38 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 05 Jan 2011 17:47:38 -0000 Subject: [llvm-commits] [llvm] r122891 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <20110105174738.5FC912A6C12C@llvm.org> Author: zwarich Date: Wed Jan 5 11:47:38 2011 New Revision: 122891 URL: http://llvm.org/viewvc/llvm-project?rev=122891&view=rev Log: Add some more statistics to CodeGenPrepare. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=122891&r1=122890&r2=122891&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Jan 5 11:47:38 2011 @@ -45,6 +45,8 @@ using namespace llvm::PatternMatch; STATISTIC(NumBlocksElim, "Number of blocks eliminated"); +STATISTIC(NumPHIsElim, "Number of trivial PHIs eliminated"); +STATISTIC(NumGEPsElim, "Number of GEPs converted to casts"); STATISTIC(NumCmpUses, "Number of uses of Cmp expressions replaced with uses of " "sunken Cmps"); STATISTIC(NumCastUses, "Number of uses of Cast expressions replaced with uses " @@ -981,6 +983,7 @@ if (Value *V = SimplifyInstruction(P)) { P->replaceAllUsesWith(V); P->eraseFromParent(); + ++NumPHIsElim; } } else if (CastInst *CI = dyn_cast(I)) { // If the source of the cast is a constant, then this should have @@ -1020,6 +1023,7 @@ GEPI->getName(), GEPI); GEPI->replaceAllUsesWith(NC); GEPI->eraseFromParent(); + ++NumGEPsElim; MadeChange = true; BBI = NC; } From daniel at zuster.org Wed Jan 5 11:52:55 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 05 Jan 2011 17:52:55 -0000 Subject: [llvm-commits] [zorg] r122892 - /zorg/trunk/lnt/lnt/db/runinfo.py Message-ID: <20110105175255.866A02A6C12C@llvm.org> Author: ddunbar Date: Wed Jan 5 11:52:55 2011 New Revision: 122892 URL: http://llvm.org/viewvc/llvm-project?rev=122892&view=rev Log: LNT: Fix a crash when missing run_values. Modified: zorg/trunk/lnt/lnt/db/runinfo.py Modified: zorg/trunk/lnt/lnt/db/runinfo.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/db/runinfo.py?rev=122892&r1=122891&r2=122892&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/db/runinfo.py (original) +++ zorg/trunk/lnt/lnt/db/runinfo.py Wed Jan 5 11:52:55 2011 @@ -169,7 +169,7 @@ # If we have multiple values for this run, use that to estimate the # distribution. - if len(run_values) > 1: + if run_values and len(run_values) > 1: stddev = stats.standard_deviation(run_values) MAD = stats.median_absolute_deviation(run_values) else: From sabre at nondot.org Wed Jan 5 12:41:05 2011 From: sabre at nondot.org (Chris Lattner) Date: Wed, 05 Jan 2011 18:41:05 -0000 Subject: [llvm-commits] [llvm] r122893 - /llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Message-ID: <20110105184105.43A2A2A6C12C@llvm.org> Author: lattner Date: Wed Jan 5 12:41:05 2011 New Revision: 122893 URL: http://llvm.org/viewvc/llvm-project?rev=122893&view=rev Log: fix some -Wself-assign warnings. Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=122893&r1=122892&r2=122893&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Wed Jan 5 12:41:05 2011 @@ -1451,7 +1451,7 @@ case CCValAssign::SExt: { bool Emitted = FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(), Arg, ArgVT, Arg); - assert(Emitted && "Failed to emit a sext!"); Emitted=Emitted; + assert(Emitted && "Failed to emit a sext!"); (void)Emitted; Emitted = true; ArgVT = VA.getLocVT(); break; @@ -1459,7 +1459,7 @@ case CCValAssign::ZExt: { bool Emitted = FastEmitExtend(ISD::ZERO_EXTEND, VA.getLocVT(), Arg, ArgVT, Arg); - assert(Emitted && "Failed to emit a zext!"); Emitted=Emitted; + assert(Emitted && "Failed to emit a zext!"); (void)Emitted; Emitted = true; ArgVT = VA.getLocVT(); break; @@ -1474,7 +1474,7 @@ Emitted = FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(), Arg, ArgVT, Arg); - assert(Emitted && "Failed to emit a aext!"); Emitted=Emitted; + assert(Emitted && "Failed to emit a aext!"); (void)Emitted; ArgVT = VA.getLocVT(); break; } From gkistanova at gmail.com Wed Jan 5 13:56:12 2011 From: gkistanova at gmail.com (Galina Kistanova) Date: Wed, 05 Jan 2011 19:56:12 -0000 Subject: [llvm-commits] [zorg] r122899 - /zorg/trunk/buildbot/osuosl/master/config/builders.py Message-ID: <20110105195612.2F8FD2A6C12C@llvm.org> Author: gkistanova Date: Wed Jan 5 13:56:12 2011 New Revision: 122899 URL: http://llvm.org/viewvc/llvm-project?rev=122899&view=rev Log: Added new buildbot builder for build on i686-pc-mingw32 of cross llvm-gcc for arm-none-linux-gnueabi. Modified: zorg/trunk/buildbot/osuosl/master/config/builders.py Modified: zorg/trunk/buildbot/osuosl/master/config/builders.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/buildbot/osuosl/master/config/builders.py?rev=122899&r1=122898&r2=122899&view=diff ============================================================================== --- zorg/trunk/buildbot/osuosl/master/config/builders.py (original) +++ zorg/trunk/buildbot/osuosl/master/config/builders.py Wed Jan 5 13:56:12 2011 @@ -612,6 +612,44 @@ 'haltOnFailure' : True },]), 'category' : 'llvm-gcc' }, + {'name' : "llvm-gcc-mingw32-cross-arm-linux-gnueabi-hard-float", + 'slavenames': [ "kistanova5" ], + 'builddir' : "llvm-gcc-mingw32-cross-arm-linux-gnueabi-hard-float", + 'factory' : ScriptedBuilder.getScriptedBuildFactory( + source_code = [SVN(name='svn-llvm', + mode='update', baseURL='http://llvm.org/svn/llvm-project/llvm/', + defaultBranch='trunk', + workdir="llvm.src"), + SVN(name='svn-llvm-gcc', + mode='update', baseURL='http://llvm.org/svn/llvm-project/llvm-gcc-4.2/', + defaultBranch='trunk', + workdir="llvm-gcc.src"),], + launcher = 'llvm-gcc.src/extras/buildbot-launcher', + build_script = 'llvm-gcc.src/extras/llvm-gcc-mingw32-cross-arm-linux-gnueabi-hard-float', + extra_args = [], + build_steps = [{'name' : 'clean', + 'description' : 'clean', + 'haltOnFailure' : True }, + {'name' : 'copy_cross_tools', + 'description' : 'copy cross-tools', + 'haltOnFailure' : True }, + {'name' : 'configure_llvm', + 'description' : 'configure llvm', + 'haltOnFailure' : True }, + {'name' : 'make_llvm', + 'description' : 'make llvm', + 'haltOnFailure' : True }, + {'name' : 'configure_llvmgcc', + 'description' : 'configure llvm-gcc', + 'haltOnFailure' : True }, + {'name' : 'make_llvmgcc', + 'description' : 'make llvm-gcc', + 'haltOnFailure' : True }, + {'name' : 'install_llvmgcc', + 'description' : 'install llvm-gcc', + 'haltOnFailure' : True },]), + 'category' : 'llvm-gcc' }, + {'name' : "clang-i686-linux-selfhost-rel", 'slavenames' : ["osu8"], 'builddir' : "clang-i686-linux-selfhost-rel", From resistor at mac.com Wed Jan 5 15:15:29 2011 From: resistor at mac.com (Owen Anderson) Date: Wed, 05 Jan 2011 21:15:29 -0000 Subject: [llvm-commits] [llvm] r122906 - /llvm/trunk/lib/Analysis/LazyValueInfo.cpp Message-ID: <20110105211529.DF6152A6C12C@llvm.org> Author: resistor Date: Wed Jan 5 15:15:29 2011 New Revision: 122906 URL: http://llvm.org/viewvc/llvm-project?rev=122906&view=rev Log: Re-convert several of LazyValueInfo's internal maps to Dense{Map|Set}, and fix the issue in hasBlockValue() that was causing iterator invalidations. Many thanks to Dimitry Andric for tracking down those invalidations! Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=122906&r1=122905&r2=122906&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Wed Jan 5 15:15:29 2011 @@ -287,6 +287,67 @@ //===----------------------------------------------------------------------===// namespace { + /// LVIValueHandle - A callback value handle update the cache when + /// values are erased. + class LazyValueInfoCache; + struct LVIValueHandle : public CallbackVH { + LazyValueInfoCache *Parent; + + LVIValueHandle(Value *V, LazyValueInfoCache *P) + : CallbackVH(V), Parent(P) { } + + void deleted(); + void allUsesReplacedWith(Value *V) { + deleted(); + } + }; +} + +namespace llvm { + template<> + struct DenseMapInfo { + typedef DenseMapInfo PointerInfo; + static inline LVIValueHandle getEmptyKey() { + return LVIValueHandle(PointerInfo::getEmptyKey(), + static_cast(0)); + } + static inline LVIValueHandle getTombstoneKey() { + return LVIValueHandle(PointerInfo::getTombstoneKey(), + static_cast(0)); + } + static unsigned getHashValue(const LVIValueHandle &Val) { + return PointerInfo::getHashValue(Val); + } + static bool isEqual(const LVIValueHandle &LHS, const LVIValueHandle &RHS) { + return LHS == RHS; + } + }; + + template<> + struct DenseMapInfo, Value*> > { + typedef std::pair, Value*> PairTy; + typedef DenseMapInfo > APointerInfo; + typedef DenseMapInfo BPointerInfo; + static inline PairTy getEmptyKey() { + return std::make_pair(APointerInfo::getEmptyKey(), + BPointerInfo::getEmptyKey()); + } + static inline PairTy getTombstoneKey() { + return std::make_pair(APointerInfo::getTombstoneKey(), + BPointerInfo::getTombstoneKey()); + } + static unsigned getHashValue( const PairTy &Val) { + return APointerInfo::getHashValue(Val.first) ^ + BPointerInfo::getHashValue(Val.second); + } + static bool isEqual(const PairTy &LHS, const PairTy &RHS) { + return APointerInfo::isEqual(LHS.first, RHS.first) && + BPointerInfo::isEqual(LHS.second, RHS.second); + } + }; +} + +namespace { /// LazyValueInfoCache - This is the cache kept by LazyValueInfo which /// maintains information about queries across the clients' queries. class LazyValueInfoCache { @@ -297,19 +358,7 @@ typedef std::map, LVILatticeVal> ValueCacheEntryTy; private: - /// LVIValueHandle - A callback value handle update the cache when - /// values are erased. - struct LVIValueHandle : public CallbackVH { - LazyValueInfoCache *Parent; - - LVIValueHandle(Value *V, LazyValueInfoCache *P) - : CallbackVH(V), Parent(P) { } - - void deleted(); - void allUsesReplacedWith(Value *V) { - deleted(); - } - }; + friend struct LVIValueHandle; /// OverDefinedCacheUpdater - A helper object that ensures that the /// OverDefinedCache is updated whenever solveBlockValue returns. @@ -332,12 +381,13 @@ /// ValueCache - This is all of the cached information for all values, /// mapped from Value* to key information. - std::map ValueCache; + DenseMap ValueCache; /// OverDefinedCache - This tracks, on a per-block basis, the set of /// values that are over-defined at the end of that block. This is required /// for cache updating. - std::set, Value*> > OverDefinedCache; + typedef std::pair, Value*> OverDefinedPairTy; + DenseSet OverDefinedCache; LVILatticeVal getBlockValue(Value *Val, BasicBlock *BB); bool getEdgeValue(Value *V, BasicBlock *F, BasicBlock *T, @@ -389,32 +439,40 @@ }; } // end anonymous namespace -void LazyValueInfoCache::LVIValueHandle::deleted() { - for (std::set, Value*> >::iterator +void LVIValueHandle::deleted() { + typedef std::pair, Value*> OverDefinedPairTy; + + SmallVector ToErase; + for (DenseSet::iterator I = Parent->OverDefinedCache.begin(), E = Parent->OverDefinedCache.end(); - I != E; ) { - std::set, Value*> >::iterator tmp = I; - ++I; - if (tmp->second == getValPtr()) - Parent->OverDefinedCache.erase(tmp); + I != E; ++I) { + if (I->second == getValPtr()) + ToErase.push_back(*I); } + for (SmallVector::iterator I = ToErase.begin(), + E = ToErase.end(); I != E; ++I) + Parent->OverDefinedCache.erase(*I); + // This erasure deallocates *this, so it MUST happen after we're done // using any and all members of *this. Parent->ValueCache.erase(*this); } void LazyValueInfoCache::eraseBlock(BasicBlock *BB) { - for (std::set, Value*> >::iterator - I = OverDefinedCache.begin(), E = OverDefinedCache.end(); I != E; ) { - std::set, Value*> >::iterator tmp = I; - ++I; - if (tmp->first == BB) - OverDefinedCache.erase(tmp); + SmallVector ToErase; + for (DenseSet::iterator I = OverDefinedCache.begin(), + E = OverDefinedCache.end(); I != E; ++I) { + if (I->first == BB) + ToErase.push_back(*I); } + + for (SmallVector::iterator I = ToErase.begin(), + E = ToErase.end(); I != E; ++I) + OverDefinedCache.erase(*I); - for (std::map::iterator + for (DenseMap::iterator I = ValueCache.begin(), E = ValueCache.end(); I != E; ++I) I->second.erase(BB); } @@ -432,7 +490,9 @@ if (isa(Val)) return true; - return lookup(Val).count(BB); + LVIValueHandle ValHandle(Val, this); + if (!ValueCache.count(ValHandle)) return false; + return ValueCache[ValHandle].count(BB); } LVILatticeVal LazyValueInfoCache::getBlockValue(Value *Val, BasicBlock *BB) { @@ -856,8 +916,8 @@ worklist.push_back(OldSucc); DenseSet ClearSet; - for (std::set, Value*> >::iterator - I = OverDefinedCache.begin(), E = OverDefinedCache.end(); I != E; ++I) { + for (DenseSet::iterator I = OverDefinedCache.begin(), + E = OverDefinedCache.end(); I != E; ++I) { if (I->first == OldSucc) ClearSet.insert(I->second); } @@ -877,7 +937,7 @@ for (DenseSet::iterator I = ClearSet.begin(), E = ClearSet.end(); I != E; ++I) { // If a value was marked overdefined in OldSucc, and is here too... - std::set, Value*> >::iterator OI = + DenseSet::iterator OI = OverDefinedCache.find(std::make_pair(ToUpdate, *I)); if (OI == OverDefinedCache.end()) continue; From bob.wilson at apple.com Wed Jan 5 15:16:50 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 05 Jan 2011 21:16:50 -0000 Subject: [llvm-commits] [llvm] r122907 - /llvm/trunk/include/llvm/Support/StandardPasses.h Message-ID: <20110105211650.B9DDF2A6C12C@llvm.org> Author: bwilson Date: Wed Jan 5 15:16:50 2011 New Revision: 122907 URL: http://llvm.org/viewvc/llvm-project?rev=122907&view=rev Log: Revert svn 122743, removing the instcombine pass that was replaced by earlycse. My i386 llvm-gcc nightly tester found a regression for SingleSource/Benchmarks/McGill/chomp that a bisect blamed on 122743. That seems strange but apparently the combination of earlycse and instcombine did something bad. Chris says he intended to remove the instcombine pass, so let's go ahead and try that. We'll see if there are any performance losses. Modified: llvm/trunk/include/llvm/Support/StandardPasses.h Modified: llvm/trunk/include/llvm/Support/StandardPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=122907&r1=122906&r2=122907&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StandardPasses.h (original) +++ llvm/trunk/include/llvm/Support/StandardPasses.h Wed Jan 5 15:16:50 2011 @@ -132,7 +132,6 @@ PM->add(createEarlyCSEPass()); // Catch trivial redundancies if (OptimizeBuiltins) PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations - PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. PM->add(createJumpThreadingPass()); // Thread jumps. PM->add(createCorrelatedValuePropagationPass()); // Propagate conditionals PM->add(createCFGSimplificationPass()); // Merge & remove BBs From resistor at mac.com Wed Jan 5 15:37:18 2011 From: resistor at mac.com (Owen Anderson) Date: Wed, 05 Jan 2011 21:37:18 -0000 Subject: [llvm-commits] [llvm] r122908 - /llvm/trunk/lib/Analysis/LazyValueInfo.cpp Message-ID: <20110105213718.50E8F2A6C12C@llvm.org> Author: resistor Date: Wed Jan 5 15:37:18 2011 New Revision: 122908 URL: http://llvm.org/viewvc/llvm-project?rev=122908&view=rev Log: When computing the value on an edge, in certain cases LVI would fail to compute the value range in the predecessor block, leading to an incorrect conclusion for the edge value. Found by inspection. Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=122908&r1=122907&r2=122908&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Wed Jan 5 15:37:18 2011 @@ -817,6 +817,11 @@ if (!isTrueDest) TrueValues = TrueValues.inverse(); // Figure out the possible values of the query BEFORE this branch. + if (!hasBlockValue(Val, BBFrom)) { + block_value_stack.push(std::make_pair(BBFrom, Val)); + return false; + } + LVILatticeVal InBlock = getBlockValue(Val, BBFrom); if (!InBlock.isConstantRange()) { Result = LVILatticeVal::getRange(TrueValues); From echristo at apple.com Wed Jan 5 15:45:56 2011 From: echristo at apple.com (Eric Christopher) Date: Wed, 05 Jan 2011 21:45:56 -0000 Subject: [llvm-commits] [llvm] r122909 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <20110105214557.0505F2A6C12C@llvm.org> Author: echristo Date: Wed Jan 5 15:45:56 2011 New Revision: 122909 URL: http://llvm.org/viewvc/llvm-project?rev=122909&view=rev Log: 80-cols. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=122909&r1=122908&r2=122909&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Jan 5 15:45:56 2011 @@ -180,7 +180,8 @@ // SelectionDAGISel code //===----------------------------------------------------------------------===// -SelectionDAGISel::SelectionDAGISel(const TargetMachine &tm, CodeGenOpt::Level OL) : +SelectionDAGISel::SelectionDAGISel(const TargetMachine &tm, + CodeGenOpt::Level OL) : MachineFunctionPass(ID), TM(tm), TLI(*tm.getTargetLowering()), FuncInfo(new FunctionLoweringInfo(TLI)), CurDAG(new SelectionDAG(tm)), From stoklund at 2pi.dk Wed Jan 5 15:50:21 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 05 Jan 2011 21:50:21 -0000 Subject: [llvm-commits] [llvm] r122911 - /llvm/trunk/lib/VMCore/PassRegistry.cpp Message-ID: <20110105215021.BD5442A6C12C@llvm.org> Author: stoklund Date: Wed Jan 5 15:50:21 2011 New Revision: 122911 URL: http://llvm.org/viewvc/llvm-project?rev=122911&view=rev Log: Silence a warning from non-standard warning avoidance code. Modified: llvm/trunk/lib/VMCore/PassRegistry.cpp Modified: llvm/trunk/lib/VMCore/PassRegistry.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/PassRegistry.cpp?rev=122911&r1=122910&r2=122911&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/PassRegistry.cpp (original) +++ llvm/trunk/lib/VMCore/PassRegistry.cpp Wed Jan 5 15:50:21 2011 @@ -106,7 +106,8 @@ PassRegistryImpl *Impl = static_cast(getImpl()); bool Inserted = Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; - assert(Inserted && "Pass registered multiple times!"); Inserted=Inserted; + assert(Inserted && "Pass registered multiple times!"); + (void)Inserted; Impl->PassInfoStringMap[PI.getPassArgument()] = &PI; // Notify any listeners. From stoklund at 2pi.dk Wed Jan 5 15:50:24 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 05 Jan 2011 21:50:24 -0000 Subject: [llvm-commits] [llvm] r122912 - /llvm/trunk/lib/CodeGen/EdgeBundles.cpp Message-ID: <20110105215024.496B32A6C12D@llvm.org> Author: stoklund Date: Wed Jan 5 15:50:24 2011 New Revision: 122912 URL: http://llvm.org/viewvc/llvm-project?rev=122912&view=rev Log: Add a hidden command line option to display edge bundle graphs as they are calculated. Modified: llvm/trunk/lib/CodeGen/EdgeBundles.cpp Modified: llvm/trunk/lib/CodeGen/EdgeBundles.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/EdgeBundles.cpp?rev=122912&r1=122911&r2=122912&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/EdgeBundles.cpp (original) +++ llvm/trunk/lib/CodeGen/EdgeBundles.cpp Wed Jan 5 15:50:24 2011 @@ -15,10 +15,15 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/GraphWriter.h" using namespace llvm; +static cl::opt +ViewEdgeBundles("view-edge-bundles", cl::Hidden, + cl::desc("Pop up a window to show edge bundle graphs")); + char EdgeBundles::ID = 0; INITIALIZE_PASS(EdgeBundles, "edge-bundles", "Bundle Machine CFG Edges", @@ -46,6 +51,8 @@ EC.join(OutE, 2 * (*SI)->getNumber()); } EC.compress(); + if (ViewEdgeBundles) + view(); return false; } From sabre at nondot.org Wed Jan 5 16:26:53 2011 From: sabre at nondot.org (Chris Lattner) Date: Wed, 05 Jan 2011 22:26:53 -0000 Subject: [llvm-commits] [llvm] r122920 - /llvm/trunk/lib/Target/X86/X86FastISel.cpp Message-ID: <20110105222653.0F5132A6C12C@llvm.org> Author: lattner Date: Wed Jan 5 16:26:52 2011 New Revision: 122920 URL: http://llvm.org/viewvc/llvm-project?rev=122920&view=rev Log: silence more self assignment warnings. 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=122920&r1=122919&r2=122920&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Wed Jan 5 16:26:52 2011 @@ -1547,7 +1547,7 @@ case CCValAssign::SExt: { bool Emitted = X86FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(), Arg, ArgVT, Arg); - assert(Emitted && "Failed to emit a sext!"); Emitted=Emitted; + assert(Emitted && "Failed to emit a sext!"); (void)Emitted; Emitted = true; ArgVT = VA.getLocVT(); break; @@ -1555,7 +1555,7 @@ case CCValAssign::ZExt: { bool Emitted = X86FastEmitExtend(ISD::ZERO_EXTEND, VA.getLocVT(), Arg, ArgVT, Arg); - assert(Emitted && "Failed to emit a zext!"); Emitted=Emitted; + assert(Emitted && "Failed to emit a zext!"); (void)Emitted; Emitted = true; ArgVT = VA.getLocVT(); break; @@ -1573,7 +1573,7 @@ Emitted = X86FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(), Arg, ArgVT, Arg); - assert(Emitted && "Failed to emit a aext!"); Emitted=Emitted; + assert(Emitted && "Failed to emit a aext!"); (void)Emitted; ArgVT = VA.getLocVT(); break; } From sabre at nondot.org Wed Jan 5 16:28:46 2011 From: sabre at nondot.org (Chris Lattner) Date: Wed, 05 Jan 2011 22:28:46 -0000 Subject: [llvm-commits] [llvm] r122921 - in /llvm/trunk: lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/sse2.ll Message-ID: <20110105222846.960AF2A6C12C@llvm.org> Author: lattner Date: Wed Jan 5 16:28:46 2011 New Revision: 122921 URL: http://llvm.org/viewvc/llvm-project?rev=122921&view=rev Log: fix PR8900, a shuffle miscompilation. Patch by Nadav Rotem! Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/test/CodeGen/X86/sse2.ll Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=122921&r1=122920&r2=122921&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Jan 5 16:28:46 2011 @@ -5597,9 +5597,9 @@ // Shuffle with UNPCKLPD def : Pat<(v2f64 (X86Unpcklpd VR128:$src1, (memopv2f64 addr:$src2))), - (VUNPCKLPSrm VR128:$src1, addr:$src2)>, Requires<[HasAVX]>; + (VUNPCKLPDrm VR128:$src1, addr:$src2)>, Requires<[HasAVX]>; def : Pat<(v2f64 (X86Unpcklpd VR128:$src1, (memopv2f64 addr:$src2))), - (UNPCKLPSrm VR128:$src1, addr:$src2)>; + (UNPCKLPDrm VR128:$src1, addr:$src2)>; def : Pat<(v2f64 (X86Unpcklpd VR128:$src1, VR128:$src2)), (VUNPCKLPDrr VR128:$src1, VR128:$src2)>, Requires<[HasAVX]>; @@ -5608,9 +5608,9 @@ // Shuffle with UNPCKHPD def : Pat<(v2f64 (X86Unpckhpd VR128:$src1, (memopv2f64 addr:$src2))), - (VUNPCKLPSrm VR128:$src1, addr:$src2)>, Requires<[HasAVX]>; + (VUNPCKHPDrm VR128:$src1, addr:$src2)>, Requires<[HasAVX]>; def : Pat<(v2f64 (X86Unpckhpd VR128:$src1, (memopv2f64 addr:$src2))), - (UNPCKLPSrm VR128:$src1, addr:$src2)>; + (UNPCKHPDrm VR128:$src1, addr:$src2)>; def : Pat<(v2f64 (X86Unpckhpd VR128:$src1, VR128:$src2)), (VUNPCKHPDrr VR128:$src1, VR128:$src2)>, Requires<[HasAVX]>; Modified: llvm/trunk/test/CodeGen/X86/sse2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sse2.ll?rev=122921&r1=122920&r2=122921&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/sse2.ll (original) +++ llvm/trunk/test/CodeGen/X86/sse2.ll Wed Jan 5 16:28:46 2011 @@ -192,3 +192,16 @@ ; CHECK: test15: ; CHECK: movhlps %xmm1, %xmm0 } + +; PR8900 +; CHECK: test16: +; CHECK: unpcklpd +; CHECK: ret + +define <2 x double> @test16(<4 x double> * nocapture %srcA, <2 x double>* nocapture %dst) { + %i5 = getelementptr inbounds <4 x double>* %srcA, i32 3 + %i6 = load <4 x double>* %i5, align 32 + %i7 = shufflevector <4 x double> %i6, <4 x double> undef, <2 x i32> + ret <2 x double> %i7 +} + From zwarich at apple.com Wed Jan 5 16:53:50 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 5 Jan 2011 14:53:50 -0800 Subject: [llvm-commits] [llvm] r122801 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: <1CC24B63-4E25-4134-B9D4-D213A19001B6@2pi.dk> References: <20110104044331.3BD3E2A6C12C@llvm.org> <26A75B47-71D0-4125-B7FB-8FF965D0EB70@2pi.dk> <1CC24B63-4E25-4134-B9D4-D213A19001B6@2pi.dk> Message-ID: <35B5659B-6502-49B8-8799-3ADA45CA8781@apple.com> On Jan 3, 2011, at 10:10 PM, Jakob Stoklund Olesen wrote: >>> Is the fix-point loop in CodeGenPrepare still necessary? When critical edge splitting is disabled? >> >> I've just been running some experiments on this. The fixed point loop is probably necessary for the 'ext' optimizations, as a lot of 'ext' casts get optimized after other instructions have been sunk into their block. On all of test-suite + SPEC2000 & SPEC2006, there are only 4 noop copies optimized in a later iteration (these don't really matter as they will be eliminated by the coalescer later), but there are 15 memory instructions that have their addressing code sunk into their BB in a later iteration. I was thinking of just iterating the ext optimizations afterwards, possibly based on a worklist, but it would be nice to know why these memory instructions have sinkable addressing code after the first iteration. > > It is probably chained bitcast / ext / gep instructions getting lowered one at a time. > > If that is the case, you could probably get away with iterating over each basic block separately instead of re-checking the whole function. That assumes that the chains to be lowered already were in the same basic block. I have no idea if that is generally true. > > It would be safer and faster to add the operands of lowered instructions to a work list, but that is a bit more work to implement. I tried implementing this, only reiterating over each basic block after optimizing a memory instruction instead of rechecking the whole function. I got the following results on test-suite + SPEC2000 & SPEC2006. This seems to disagree with my previous printf-based approach to counting the extra improvements. Before: 153583 Number of GEPs converted to casts 14501 Number of [s|z]ext instructions combined with loads 85788 Number of blocks eliminated 210298 Number of memory instructions whose address computations were sunk 150811 Number of uses of Cast expressions replaced with uses of sunken Casts 28255 Number of uses of Cmp expressions replaced with uses of sunken Cmps 17221 Number of uses of [s|z]ext instructions optimized After: 153583 Number of GEPs converted to casts 14459 Number of [s|z]ext instructions combined with loads 85788 Number of blocks eliminated 208697 Number of memory instructions whose address computations were sunk 150126 Number of uses of Cast expressions replaced with uses of sunken Casts 28230 Number of uses of Cmp expressions replaced with uses of sunken Cmps 17263 Number of uses of [s|z]ext instructions optimized I guess I'll still have to work at getting it closer in code quality. Maybe I'll need to make all of the optimizations feed into a worklist, which could be tricky. Currently, it's about a 10% improvement in total llc time, though. Cameron From evan.cheng at apple.com Wed Jan 5 17:06:50 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 05 Jan 2011 23:06:50 -0000 Subject: [llvm-commits] [llvm] r122925 - in /llvm/trunk: lib/CodeGen/SelectionDAG/InstrEmitter.cpp test/CodeGen/X86/zext-extract_subreg.ll Message-ID: <20110105230650.233042A6C12C@llvm.org> Author: evancheng Date: Wed Jan 5 17:06:49 2011 New Revision: 122925 URL: http://llvm.org/viewvc/llvm-project?rev=122925&view=rev Log: Optimize: r1025 = s/zext r1024, 4 r1026 = extract_subreg r1025, 4 to: r1026 = copy r1024 Added: llvm/trunk/test/CodeGen/X86/zext-extract_subreg.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp?rev=122925&r1=122924&r2=122925&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp Wed Jan 5 17:06:49 2011 @@ -428,31 +428,47 @@ // Figure out the register class to create for the destreg. unsigned VReg = getVR(Node->getOperand(0), VRBaseMap); - const TargetRegisterClass *TRC = MRI->getRegClass(VReg); - const TargetRegisterClass *SRC = TRC->getSubRegisterRegClass(SubIdx); - assert(SRC && "Invalid subregister index in EXTRACT_SUBREG"); - - // Figure out the register class to create for the destreg. - // Note that if we're going to directly use an existing register, - // it must be precisely the required class, and not a subclass - // thereof. - if (VRBase == 0 || SRC != MRI->getRegClass(VRBase)) { - // Create the reg - assert(SRC && "Couldn't find source register class"); - VRBase = MRI->createVirtualRegister(SRC); - } + MachineInstr *DefMI = MRI->getVRegDef(VReg); + unsigned SrcReg, DstReg, DefSubIdx; + if (DefMI && + TII->isCoalescableExtInstr(*DefMI, SrcReg, DstReg, DefSubIdx) && + SubIdx == DefSubIdx) { + // Optimize these: + // r1025 = s/zext r1024, 4 + // r1026 = extract_subreg r1025, 4 + // to a copy + // r1026 = copy r1024 + const TargetRegisterClass *TRC = MRI->getRegClass(SrcReg); + VRBase = MRI->createVirtualRegister(TRC); + BuildMI(*MBB, InsertPos, Node->getDebugLoc(), + TII->get(TargetOpcode::COPY), VRBase).addReg(SrcReg); + } else { + const TargetRegisterClass *TRC = MRI->getRegClass(VReg); + const TargetRegisterClass *SRC = TRC->getSubRegisterRegClass(SubIdx); + assert(SRC && "Invalid subregister index in EXTRACT_SUBREG"); + + // Figure out the register class to create for the destreg. + // Note that if we're going to directly use an existing register, + // it must be precisely the required class, and not a subclass + // thereof. + if (VRBase == 0 || SRC != MRI->getRegClass(VRBase)) { + // Create the reg + assert(SRC && "Couldn't find source register class"); + VRBase = MRI->createVirtualRegister(SRC); + } - // Create the extract_subreg machine instruction. - MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), - TII->get(TargetOpcode::COPY), VRBase); + // Create the extract_subreg machine instruction. + MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), + TII->get(TargetOpcode::COPY), VRBase); - // Add source, and subreg index - AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap, /*IsDebug=*/false, - IsClone, IsCloned); - assert(TargetRegisterInfo::isVirtualRegister(MI->getOperand(1).getReg()) && - "Cannot yet extract from physregs"); - MI->getOperand(1).setSubReg(SubIdx); - MBB->insert(InsertPos, MI); + // Add source, and subreg index + AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap, /*IsDebug=*/false, + IsClone, IsCloned); + assert(TargetRegisterInfo::isVirtualRegister(MI->getOperand(1).getReg())&& + "Cannot yet extract from physregs"); + MI->getOperand(1).setSubReg(SubIdx); + MBB->insert(InsertPos, MI); + } } else if (Opc == TargetOpcode::INSERT_SUBREG || Opc == TargetOpcode::SUBREG_TO_REG) { SDValue N0 = Node->getOperand(0); Added: llvm/trunk/test/CodeGen/X86/zext-extract_subreg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/zext-extract_subreg.ll?rev=122925&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/zext-extract_subreg.ll (added) +++ llvm/trunk/test/CodeGen/X86/zext-extract_subreg.ll Wed Jan 5 17:06:49 2011 @@ -0,0 +1,60 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s + +define void @t() nounwind ssp { +; CHECK: t: +entry: + br i1 undef, label %return, label %if.end.i + +if.end.i: ; preds = %entry + %tmp7.i = load i32* undef, align 4, !tbaa !0 + br i1 undef, label %return, label %if.end + +if.end: ; preds = %if.end.i +; CHECK: %if.end +; CHECK: movl (%{{.*}}), [[REG:%[a-z]+]] +; CHECK-NOT: movl [[REG]], [[REG]] +; CHECK-NEXT: xorb + %tmp138 = select i1 undef, i32 0, i32 %tmp7.i + %tmp867 = zext i32 %tmp138 to i64 + br label %while.cond + +while.cond: ; preds = %while.body, %if.end + %tmp869 = sub i64 %tmp867, 0 + %scale2.0 = trunc i64 %tmp869 to i32 + %cmp149 = icmp eq i32 %scale2.0, 0 + br i1 %cmp149, label %while.end, label %land.rhs + +land.rhs: ; preds = %while.cond + br i1 undef, label %while.body, label %while.end + +while.body: ; preds = %land.rhs + br label %while.cond + +while.end: ; preds = %land.rhs, %while.cond + br i1 undef, label %cond.false205, label %cond.true190 + +cond.true190: ; preds = %while.end + br i1 undef, label %cond.false242, label %cond.true225 + +cond.false205: ; preds = %while.end + unreachable + +cond.true225: ; preds = %cond.true190 + br i1 undef, label %cond.false280, label %cond.true271 + +cond.false242: ; preds = %cond.true190 + unreachable + +cond.true271: ; preds = %cond.true225 + unreachable + +cond.false280: ; preds = %cond.true225 + unreachable + +return: ; preds = %if.end.i, %entry + ret void +} + +!0 = metadata !{metadata !"int", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA", null} From resistor at mac.com Wed Jan 5 17:26:23 2011 From: resistor at mac.com (Owen Anderson) Date: Wed, 05 Jan 2011 23:26:23 -0000 Subject: [llvm-commits] [llvm] r122929 - /llvm/trunk/lib/Analysis/LazyValueInfo.cpp Message-ID: <20110105232623.291292A6C12C@llvm.org> Author: resistor Date: Wed Jan 5 17:26:22 2011 New Revision: 122929 URL: http://llvm.org/viewvc/llvm-project?rev=122929&view=rev Log: Reorder, rename, and document some members to make this easier to follow. Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=122929&r1=122928&r2=122929&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Wed Jan 5 17:26:22 2011 @@ -351,13 +351,26 @@ /// LazyValueInfoCache - This is the cache kept by LazyValueInfo which /// maintains information about queries across the clients' queries. class LazyValueInfoCache { - public: /// ValueCacheEntryTy - This is all of the cached block information for /// exactly one Value*. The entries are sorted by the BasicBlock* of the /// entries, allowing us to do a lookup with a binary search. typedef std::map, LVILatticeVal> ValueCacheEntryTy; - private: + /// ValueCache - This is all of the cached information for all values, + /// mapped from Value* to key information. + DenseMap ValueCache; + + /// OverDefinedCache - This tracks, on a per-block basis, the set of + /// values that are over-defined at the end of that block. This is required + /// for cache updating. + typedef std::pair, Value*> OverDefinedPairTy; + DenseSet OverDefinedCache; + + /// BlockValueStack - This stack holds the state of the value solver + /// during a query. It basically emulates the callstack of the naive + /// recursive value lookup process. + std::stack > BlockValueStack; + friend struct LVIValueHandle; /// OverDefinedCacheUpdater - A helper object that ensures that the @@ -378,16 +391,8 @@ return changed; } }; - - /// ValueCache - This is all of the cached information for all values, - /// mapped from Value* to key information. - DenseMap ValueCache; - /// OverDefinedCache - This tracks, on a per-block basis, the set of - /// values that are over-defined at the end of that block. This is required - /// for cache updating. - typedef std::pair, Value*> OverDefinedPairTy; - DenseSet OverDefinedCache; + LVILatticeVal getBlockValue(Value *Val, BasicBlock *BB); bool getEdgeValue(Value *V, BasicBlock *F, BasicBlock *T, @@ -410,8 +415,6 @@ ValueCacheEntryTy &lookup(Value *V) { return ValueCache[LVIValueHandle(V, this)]; } - - std::stack > block_value_stack; public: /// getValueInBlock - This is the query interface to determine the lattice @@ -478,10 +481,10 @@ } void LazyValueInfoCache::solve() { - while (!block_value_stack.empty()) { - std::pair &e = block_value_stack.top(); + while (!BlockValueStack.empty()) { + std::pair &e = BlockValueStack.top(); if (solveBlockValue(e.second, e.first)) - block_value_stack.pop(); + BlockValueStack.pop(); } } @@ -688,7 +691,7 @@ BasicBlock *BB) { // Figure out the range of the LHS. If that fails, bail. if (!hasBlockValue(BBI->getOperand(0), BB)) { - block_value_stack.push(std::make_pair(BB, BBI->getOperand(0))); + BlockValueStack.push(std::make_pair(BB, BBI->getOperand(0))); return false; } @@ -818,7 +821,7 @@ // Figure out the possible values of the query BEFORE this branch. if (!hasBlockValue(Val, BBFrom)) { - block_value_stack.push(std::make_pair(BBFrom, Val)); + BlockValueStack.push(std::make_pair(BBFrom, Val)); return false; } @@ -872,7 +875,7 @@ Result = getBlockValue(Val, BBFrom); return true; } - block_value_stack.push(std::make_pair(BBFrom, Val)); + BlockValueStack.push(std::make_pair(BBFrom, Val)); return false; } @@ -880,7 +883,7 @@ DEBUG(dbgs() << "LVI Getting block end value " << *V << " at '" << BB->getName() << "'\n"); - block_value_stack.push(std::make_pair(BB, V)); + BlockValueStack.push(std::make_pair(BB, V)); solve(); LVILatticeVal Result = getBlockValue(V, BB); From stoklund at 2pi.dk Wed Jan 5 17:44:01 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 5 Jan 2011 15:44:01 -0800 Subject: [llvm-commits] [llvm] r122801 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: <35B5659B-6502-49B8-8799-3ADA45CA8781@apple.com> References: <20110104044331.3BD3E2A6C12C@llvm.org> <26A75B47-71D0-4125-B7FB-8FF965D0EB70@2pi.dk> <1CC24B63-4E25-4134-B9D4-D213A19001B6@2pi.dk> <35B5659B-6502-49B8-8799-3ADA45CA8781@apple.com> Message-ID: On Jan 5, 2011, at 2:53 PM, Cameron Zwarich wrote: > I tried implementing this, only reiterating over each basic block after optimizing a memory instruction instead of rechecking the whole function. I got the following results on test-suite + SPEC2000 & SPEC2006. This seems to disagree with my previous printf-based approach to counting the extra improvements. [... almost, but not quite identical results ..] > I guess I'll still have to work at getting it closer in code quality. Maybe I'll need to make all of the optimizations feed into a worklist, which could be tricky. I think an instruction-based work list should give you even better performance than anything basic on basic blocks. Whenever an instruction is sunk, add all its operands to the work list. You should probably use a SetVector for stable results. > Currently, it's about a 10% improvement in total llc time, though. That is quite significant! /jakob From zwarich at apple.com Wed Jan 5 18:42:50 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Thu, 06 Jan 2011 00:42:50 -0000 Subject: [llvm-commits] [llvm] r122932 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <20110106004250.5DD402A6C12C@llvm.org> Author: zwarich Date: Wed Jan 5 18:42:50 2011 New Revision: 122932 URL: http://llvm.org/viewvc/llvm-project?rev=122932&view=rev Log: Stop reallocating SunkAddrs for each basic block. When we move to an instruction worklist, the key will need to become std::pair. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=122932&r1=122931&r2=122932&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Jan 5 18:42:50 2011 @@ -71,6 +71,12 @@ /// BackEdges - Keep a set of all the loop back edges. /// SmallSet, 8> BackEdges; + + // Keeps track of non-local addresses that have been sunk into a block. This + // allows us to avoid inserting duplicate code for blocks with multiple + // load/stores of the same address. + DenseMap SunkAddrs; + public: static char ID; // Pass identification, replacement for typeid explicit CodeGenPrepare(const TargetLowering *tli = 0) @@ -141,6 +147,9 @@ MadeChange |= OptimizeBlock(*BB); EverMadeChange |= MadeChange; } + + SunkAddrs.clear(); + return EverMadeChange; } @@ -968,10 +977,7 @@ } } - // Keep track of non-local addresses that have been sunk into this block. - // This allows us to avoid inserting duplicate code for blocks with multiple - // load/stores of the same address. - DenseMap SunkAddrs; + SunkAddrs.clear(); for (BasicBlock::iterator BBI = BB.begin(), E = BB.end(); BBI != E; ) { Instruction *I = BBI++; From isanbard at gmail.com Wed Jan 5 18:47:10 2011 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 06 Jan 2011 00:47:10 -0000 Subject: [llvm-commits] [llvm] r122933 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <20110106004710.347232A6C12C@llvm.org> Author: void Date: Wed Jan 5 18:47:10 2011 New Revision: 122933 URL: http://llvm.org/viewvc/llvm-project?rev=122933&view=rev Log: PR8918 - When used with MinGW64, LLVM generates a "calll __main" at the beginning of the "main" function. The assembler complains about the invalid suffix for the 'call' instruction. The right instruction is "callq __main". Patch by KS Sreeram! Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=122933&r1=122932&r2=122933&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Jan 5 18:47:10 2011 @@ -530,9 +530,12 @@ void X86DAGToDAGISel::EmitSpecialCodeForMain(MachineBasicBlock *BB, MachineFrameInfo *MFI) { const TargetInstrInfo *TII = TM.getInstrInfo(); - if (Subtarget->isTargetCygMing()) + if (Subtarget->isTargetCygMing()) { + unsigned CallOp = + Subtarget->is64Bit() ? X86::CALL64pcrel32 : X86::CALLpcrel32; BuildMI(BB, DebugLoc(), - TII->get(X86::CALLpcrel32)).addExternalSymbol("__main"); + TII->get(CallOp)).addExternalSymbol("__main"); + } } void X86DAGToDAGISel::EmitFunctionEntryCode() { From isanbard at gmail.com Wed Jan 5 18:50:34 2011 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 06 Jan 2011 00:50:34 -0000 Subject: [llvm-commits] [llvm] r122934 - /llvm/trunk/lib/Target/X86/X86FrameInfo.cpp Message-ID: <20110106005034.DE5522A6C12C@llvm.org> Author: void Date: Wed Jan 5 18:50:34 2011 New Revision: 122934 URL: http://llvm.org/viewvc/llvm-project?rev=122934&view=rev Log: PR8919 - LLVM incorrectly generates "_alloca" as the stack probing call. That works only on MinGW32. On 64-bit, the function to call is "__chkstk". Patch by KS Sreeram! Modified: llvm/trunk/lib/Target/X86/X86FrameInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86FrameInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameInfo.cpp?rev=122934&r1=122933&r2=122934&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FrameInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FrameInfo.cpp Wed Jan 5 18:50:34 2011 @@ -566,6 +566,8 @@ const char *StackProbeSymbol = STI.isTargetWindows() ? "_chkstk" : "_alloca"; + if (Is64Bit && STI.isTargetCygMing()) + StackProbeSymbol = "__chkstk"; unsigned CallOp = Is64Bit ? X86::CALL64pcrel32 : X86::CALLpcrel32; if (!isEAXAlive) { BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX) From evan.cheng at apple.com Wed Jan 5 19:02:45 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 06 Jan 2011 01:02:45 -0000 Subject: [llvm-commits] [llvm] r122935 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/X86/switch-bt.ll Message-ID: <20110106010245.234602A6C12C@llvm.org> Author: evancheng Date: Wed Jan 5 19:02:44 2011 New Revision: 122935 URL: http://llvm.org/viewvc/llvm-project?rev=122935&view=rev Log: Avoid zero extend bit test operands to pointer type if all the masks fit in the original type of the switch statement key. rdar://8781238 Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/test/CodeGen/X86/switch-bt.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=122935&r1=122934&r2=122935&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Jan 5 19:02:44 2011 @@ -1615,12 +1615,28 @@ Sub, DAG.getConstant(B.Range, VT), ISD::SETUGT); - SDValue ShiftOp = DAG.getZExtOrTrunc(Sub, getCurDebugLoc(), - TLI.getPointerTy()); + // Determine the type of the test operands. + bool UsePtrType = false; + if (!TLI.isTypeLegal(VT)) + UsePtrType = true; + else { + for (unsigned i = 0, e = B.Cases.size(); i != e; ++i) + if ((uint64_t)((int64_t)B.Cases[i].Mask >> VT.getSizeInBits()) + 1 >= 2) { + // Switch table case range are encoded into series of masks. + // Just use pointer type, it's guaranteed to fit. + UsePtrType = true; + break; + } + } + if (UsePtrType) { + VT = TLI.getPointerTy(); + Sub = DAG.getZExtOrTrunc(Sub, getCurDebugLoc(), VT); + } - B.Reg = FuncInfo.CreateReg(TLI.getPointerTy()); + B.RegVT = VT; + B.Reg = FuncInfo.CreateReg(VT); SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), getCurDebugLoc(), - B.Reg, ShiftOp); + B.Reg, Sub); // Set NextBlock to be the MBB immediately after the current one, if any. // This is used to avoid emitting unnecessary branches to the next block. @@ -1646,36 +1662,34 @@ } /// visitBitTestCase - this function produces one "bit test" -void SelectionDAGBuilder::visitBitTestCase(MachineBasicBlock* NextMBB, +void SelectionDAGBuilder::visitBitTestCase(BitTestBlock &BB, + MachineBasicBlock* NextMBB, unsigned Reg, BitTestCase &B, MachineBasicBlock *SwitchBB) { - SDValue ShiftOp = DAG.getCopyFromReg(getControlRoot(), getCurDebugLoc(), Reg, - TLI.getPointerTy()); + EVT VT = BB.RegVT; + SDValue ShiftOp = DAG.getCopyFromReg(getControlRoot(), getCurDebugLoc(), + Reg, VT); SDValue Cmp; if (CountPopulation_64(B.Mask) == 1) { // Testing for a single bit; just compare the shift count with what it // would need to be to shift a 1 bit in that position. Cmp = DAG.getSetCC(getCurDebugLoc(), - TLI.getSetCCResultType(ShiftOp.getValueType()), + TLI.getSetCCResultType(VT), ShiftOp, - DAG.getConstant(CountTrailingZeros_64(B.Mask), - TLI.getPointerTy()), + DAG.getConstant(CountTrailingZeros_64(B.Mask), VT), ISD::SETEQ); } else { // Make desired shift - SDValue SwitchVal = DAG.getNode(ISD::SHL, getCurDebugLoc(), - TLI.getPointerTy(), - DAG.getConstant(1, TLI.getPointerTy()), - ShiftOp); + SDValue SwitchVal = DAG.getNode(ISD::SHL, getCurDebugLoc(), VT, + DAG.getConstant(1, VT), ShiftOp); // Emit bit tests and jumps SDValue AndOp = DAG.getNode(ISD::AND, getCurDebugLoc(), - TLI.getPointerTy(), SwitchVal, - DAG.getConstant(B.Mask, TLI.getPointerTy())); + VT, SwitchVal, DAG.getConstant(B.Mask, VT)); Cmp = DAG.getSetCC(getCurDebugLoc(), - TLI.getSetCCResultType(AndOp.getValueType()), - AndOp, DAG.getConstant(0, TLI.getPointerTy()), + TLI.getSetCCResultType(VT), + AndOp, DAG.getConstant(0, VT), ISD::SETNE); } @@ -2219,7 +2233,7 @@ } BitTestBlock BTB(lowBound, cmpRange, SV, - -1U, (CR.CaseBB == SwitchBB), + -1U, MVT::Other, (CR.CaseBB == SwitchBB), CR.CaseBB, Default, BTC); if (CR.CaseBB == SwitchBB) Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=122935&r1=122934&r2=122935&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h Wed Jan 5 19:02:44 2011 @@ -258,15 +258,16 @@ struct BitTestBlock { BitTestBlock(APInt F, APInt R, const Value* SV, - unsigned Rg, bool E, + unsigned Rg, EVT RgVT, bool E, MachineBasicBlock* P, MachineBasicBlock* D, const BitTestInfo& C): - First(F), Range(R), SValue(SV), Reg(Rg), Emitted(E), + First(F), Range(R), SValue(SV), Reg(Rg), RegVT(RgVT), Emitted(E), Parent(P), Default(D), Cases(C) { } APInt First; APInt Range; const Value *SValue; unsigned Reg; + EVT RegVT; bool Emitted; MachineBasicBlock *Parent; MachineBasicBlock *Default; @@ -435,7 +436,8 @@ void visitSwitchCase(CaseBlock &CB, MachineBasicBlock *SwitchBB); void visitBitTestHeader(BitTestBlock &B, MachineBasicBlock *SwitchBB); - void visitBitTestCase(MachineBasicBlock* NextMBB, + void visitBitTestCase(BitTestBlock &BB, + MachineBasicBlock* NextMBB, unsigned Reg, BitTestCase &B, MachineBasicBlock *SwitchBB); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=122935&r1=122934&r2=122935&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Jan 5 19:02:44 2011 @@ -1017,12 +1017,14 @@ FuncInfo->InsertPt = FuncInfo->MBB->end(); // Emit the code if (j+1 != ej) - SDB->visitBitTestCase(SDB->BitTestCases[i].Cases[j+1].ThisBB, + SDB->visitBitTestCase(SDB->BitTestCases[i], + SDB->BitTestCases[i].Cases[j+1].ThisBB, SDB->BitTestCases[i].Reg, SDB->BitTestCases[i].Cases[j], FuncInfo->MBB); else - SDB->visitBitTestCase(SDB->BitTestCases[i].Default, + SDB->visitBitTestCase(SDB->BitTestCases[i], + SDB->BitTestCases[i].Default, SDB->BitTestCases[i].Reg, SDB->BitTestCases[i].Cases[j], FuncInfo->MBB); Modified: llvm/trunk/test/CodeGen/X86/switch-bt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/switch-bt.ll?rev=122935&r1=122934&r2=122935&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/switch-bt.ll (original) +++ llvm/trunk/test/CodeGen/X86/switch-bt.ll Wed Jan 5 19:02:44 2011 @@ -49,3 +49,33 @@ } declare void @foo(i32) + +; Don't zero extend the test operands to pointer type if it can be avoided. +; rdar://8781238 +define void @test2(i32 %x) nounwind ssp { +; CHECK: test2: +; CHECK: cmpl $6 +; CHECK: ja + +; CHECK-NEXT: movl $91 +; CHECK-NOT: movl +; CHECK-NEXT: btl +; CHECK-NEXT: jb +entry: + switch i32 %x, label %if.end [ + i32 6, label %if.then + i32 4, label %if.then + i32 3, label %if.then + i32 1, label %if.then + i32 0, label %if.then + ] + +if.then: ; preds = %entry, %entry, %entry, %entry, %entry + tail call void @bar() nounwind + ret void + +if.end: ; preds = %entry + ret void +} + +declare void @bar() From evan.cheng at apple.com Wed Jan 5 19:04:47 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 06 Jan 2011 01:04:47 -0000 Subject: [llvm-commits] [llvm] r122936 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAG.cpp test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll test/CodeGen/X86/memcpy.ll Message-ID: <20110106010447.C6A7A2A6C12C@llvm.org> Author: evancheng Date: Wed Jan 5 19:04:47 2011 New Revision: 122936 URL: http://llvm.org/viewvc/llvm-project?rev=122936&view=rev Log: r105228 reduced the memcpy / memset inline limit to 4 with -Os to avoid blowing up freebsd bootloader. However, this doesn't make much sense for Darwin, whose -Os is meant to optimize for size only if it doesn't hurt performance. rdar://8821501 Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll llvm/trunk/test/CodeGen/X86/memcpy.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=122936&r1=122935&r2=122936&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Jan 5 19:04:47 2011 @@ -50,6 +50,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Triple.h" #include #include using namespace llvm; @@ -3286,8 +3287,14 @@ // the size of a call to memcpy or memset (3 arguments + call). if (Limit != ~0U) { const Function *F = DAG.getMachineFunction().getFunction(); - if (F->hasFnAttr(Attribute::OptimizeForSize)) - Limit = 4; + if (F->hasFnAttr(Attribute::OptimizeForSize)) { + Triple T(((LLVMTargetMachine&)TLI.getTargetMachine()).getTargetTriple()); + if (T.getOS() != Triple::Darwin) + // A pretty terrible hack to defat the wild guess. On Darwin, -Os means + // optimize for size without hurting performance so we don't want to + // bump down the limit. + Limit = 4; + } } unsigned NumMemOps = 0; Modified: llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll?rev=122936&r1=122935&r2=122936&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll Wed Jan 5 19:04:47 2011 @@ -1,4 +1,4 @@ -; RUN: llc -O1 -mtriple=x86_64-apple-darwin10 -relocation-model=pic -disable-fp-elim < %s | FileCheck %s +; RUN: llc -O1 -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic -disable-fp-elim < %s | FileCheck %s ; %struct.type = type { %struct.subtype*, i32, i8, i32, i8, i32, i32, i32, i32, i32, i8, i32, i32, i32, i32, i32, [256 x i32], i32, [257 x i32], [257 x i32], i32*, i16*, i8*, i32, i32, i32, i32, i32, [256 x i8], [16 x i8], [256 x i8], [4096 x i8], [16 x i32], [18002 x i8], [18002 x i8], [6 x [258 x i8]], [6 x [258 x i32]], [6 x [258 x i32]], [6 x [258 x i32]], [6 x i32], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32*, i32*, i32* } @@ -21,9 +21,9 @@ ; statement. It can be an ADD or LEA instruction, it's not important which one ; it is. ; -; CHECK: ## %bb -; CHECK-NEXT: addq $64036, %rdi -; CHECK: rep;stosl +; CHECK: # %bb +; CHECK: addq $64036, %rdi +; CHECK: rep;stosl %tmp5 = bitcast i32* %tmp4 to i8* call void @llvm.memset.p0i8.i64(i8* %tmp5, i8 0, i64 84, i32 4, i1 false) Modified: llvm/trunk/test/CodeGen/X86/memcpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memcpy.ll?rev=122936&r1=122935&r2=122936&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memcpy.ll (original) +++ llvm/trunk/test/CodeGen/X86/memcpy.ll Wed Jan 5 19:04:47 2011 @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=x86-64 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s -check-prefix=LINUX +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s -check-prefix=DARWIN declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind @@ -9,8 +10,8 @@ tail call void @llvm.memcpy.p0i8.p0i8.i64( i8* %a, i8* %b, i64 %n, i32 1, i1 0 ) ret i8* %a -; CHECK: test1: -; CHECK: memcpy +; LINUX: test1: +; LINUX: memcpy } ; Variable memcpy's should lower to calls. @@ -21,18 +22,41 @@ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp14, i8* %tmp25, i64 %n, i32 8, i1 0 ) ret i8* %tmp14 -; CHECK: test2: -; CHECK: memcpy +; LINUX: test2: +; LINUX: memcpy } ; Large constant memcpy's should lower to a call when optimizing for size. ; PR6623 + +; On the other hand, Darwin's definition of -Os is optimizing for size without +; hurting performance so it should just ignore optsize when expanding memcpy. +; rdar://8821501 define void @test3(i8* nocapture %A, i8* nocapture %B) nounwind optsize noredzone { entry: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i32 1, i1 false) ret void -; CHECK: test3: -; CHECK: memcpy +; LINUX: test3: +; LINUX: memcpy + +; DARWIN: test3: +; DARWIN-NOT: memcpy +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq } ; Large constant memcpy's should be inlined when not optimizing for size. @@ -40,18 +64,18 @@ entry: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i32 1, i1 false) ret void -; CHECK: test4: -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq +; LINUX: test4: +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq } From isanbard at gmail.com Wed Jan 5 19:09:35 2011 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 06 Jan 2011 01:09:35 -0000 Subject: [llvm-commits] [llvm] r122937 - /llvm/trunk/test/CodeGen/X86/win_chkstk.ll Message-ID: <20110106010935.60F432A6C12C@llvm.org> Author: void Date: Wed Jan 5 19:09:35 2011 New Revision: 122937 URL: http://llvm.org/viewvc/llvm-project?rev=122937&view=rev Log: Fix test to coincide with r122934 change from PR8919. Modified: llvm/trunk/test/CodeGen/X86/win_chkstk.ll Modified: llvm/trunk/test/CodeGen/X86/win_chkstk.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win_chkstk.ll?rev=122937&r1=122936&r2=122937&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/win_chkstk.ll (original) +++ llvm/trunk/test/CodeGen/X86/win_chkstk.ll Wed Jan 5 19:09:35 2011 @@ -16,7 +16,7 @@ ; WIN_X32: calll __chkstk ; WIN_X64: callq __chkstk ; MINGW_X32: calll __alloca -; MINGW_X64: callq _alloca +; MINGW_X64: callq __chkstk ; LINUX-NOT: call __chkstk %array4096 = alloca [4096 x i8], align 16 ; <[4096 x i8]*> [#uses=0] ret i32 0 From stoklund at 2pi.dk Wed Jan 5 19:21:54 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 06 Jan 2011 01:21:54 -0000 Subject: [llvm-commits] [llvm] r122938 - in /llvm/trunk: include/llvm/CodeGen/Passes.h include/llvm/InitializePasses.h lib/CodeGen/CMakeLists.txt lib/CodeGen/SpillPlacement.cpp lib/CodeGen/SpillPlacement.h Message-ID: <20110106012154.2D46B2A6C12C@llvm.org> Author: stoklund Date: Wed Jan 5 19:21:53 2011 New Revision: 122938 URL: http://llvm.org/viewvc/llvm-project?rev=122938&view=rev Log: Add the SpillPlacement analysis pass. This pass precomputes CFG block frequency information that can be used by the register allocator to find optimal spill code placement. Given an interference pattern, placeSpills() will compute which basic blocks should have the current variable enter or exit in a register, and which blocks prefer the stack. The algorithm is ready to consume block frequencies from profiling data, but for now it gets by with the static estimates used for spill weights. This is a work in progress and still not hooked up to RegAllocGreedy. Added: llvm/trunk/lib/CodeGen/SpillPlacement.cpp llvm/trunk/lib/CodeGen/SpillPlacement.h Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/include/llvm/InitializePasses.h llvm/trunk/lib/CodeGen/CMakeLists.txt Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=122938&r1=122937&r2=122938&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed Jan 5 19:21:53 2011 @@ -88,6 +88,11 @@ /// register allocators. extern char &TwoAddressInstructionPassID; + /// SpillPlacement analysis. Suggest optimal placement of spill code between + /// basic blocks. + /// + extern char &SpillPlacementID; + /// UnreachableMachineBlockElimination pass - This pass removes unreachable /// machine basic blocks. extern char &UnreachableMachineBlockElimID; Modified: llvm/trunk/include/llvm/InitializePasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=122938&r1=122937&r2=122938&view=diff ============================================================================== --- llvm/trunk/include/llvm/InitializePasses.h (original) +++ llvm/trunk/include/llvm/InitializePasses.h Wed Jan 5 19:21:53 2011 @@ -203,6 +203,7 @@ void initializeSingleLoopExtractorPass(PassRegistry&); void initializeSinkingPass(PassRegistry&); void initializeSlotIndexesPass(PassRegistry&); +void initializeSpillPlacementPass(PassRegistry&); void initializeStackProtectorPass(PassRegistry&); void initializeStackSlotColoringPass(PassRegistry&); void initializeStripDeadDebugInfoPass(PassRegistry&); Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=122938&r1=122937&r2=122938&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Wed Jan 5 19:21:53 2011 @@ -80,6 +80,7 @@ SjLjEHPrepare.cpp SlotIndexes.cpp Spiller.cpp + SpillPlacement.cpp SplitKit.cpp Splitter.cpp StackProtector.cpp Added: llvm/trunk/lib/CodeGen/SpillPlacement.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SpillPlacement.cpp?rev=122938&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SpillPlacement.cpp (added) +++ llvm/trunk/lib/CodeGen/SpillPlacement.cpp Wed Jan 5 19:21:53 2011 @@ -0,0 +1,354 @@ +//===-- SpillPlacement.cpp - Optimal Spill Code Placement -----------------===// +// +// 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 spill code placement analysis. +// +// Each edge bundle corresponds to a node in a Hopfield network. Constraints on +// basic blocks are weighted by the block frequency and added to become the node +// bias. +// +// Transparent basic blocks have the variable live through, but don't care if it +// is spilled or in a register. These blocks become connections in the Hopfield +// network, again weighted by block frequency. +// +// The Hopfield network minimizes (possibly locally) its energy function: +// +// E = -sum_n V_n * ( B_n + sum_{n, m linked by b} V_m * F_b ) +// +// The energy function represents the expected spill code execution frequency, +// or the cost of spilling. This is a Lyapunov function which never increases +// when a node is updated. It is guaranteed to converge to a local minimum. +// +//===----------------------------------------------------------------------===// + +#include "SpillPlacement.h" +#include "llvm/CodeGen/EdgeBundles.h" +#include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" + +using namespace llvm; + +char SpillPlacement::ID = 0; +INITIALIZE_PASS_BEGIN(SpillPlacement, "spill-code-placement", + "Spill Code Placement Analysis", true, true) +INITIALIZE_PASS_DEPENDENCY(EdgeBundles) +INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) +INITIALIZE_PASS_END(SpillPlacement, "spill-code-placement", + "Spill Code Placement Analysis", true, true) + +char &llvm::SpillPlacementID = SpillPlacement::ID; + +void SpillPlacement::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequiredTransitive(); + AU.addRequiredTransitive(); + MachineFunctionPass::getAnalysisUsage(AU); +} + +/// Node - Each edge bundle corresponds to a Hopfield node. +/// +/// The node contains precomputed frequency data that only depends on the CFG, +/// but Bias and Links are computed each time placeSpills is called. +/// +/// The node Value is positive when the variable should be in a register. The +/// value can change when linked nodes change, but convergence is very fast +/// because all weights are positive. +/// +struct SpillPlacement::Node { + /// Frequency - Total block frequency feeding into[0] or out of[1] the bundle. + /// Ideally, these two numbers should be identical, but inaccuracies in the + /// block frequency estimates means that we need to normalize ingoing and + /// outgoing frequencies separately so they are commensurate. + float Frequency[2]; + + /// Bias - Normalized contributions from non-transparent blocks. + /// A bundle connected to a MustSpill block has a huge negative bias, + /// otherwise it is a number in the range [-2;2]. + float Bias; + + /// Value - Output value of this node computed from the Bias and links. + /// This is always in the range [-1;1]. A positive number means the variable + /// should go in a register through this bundle. + float Value; + + typedef SmallVector, 4> LinkVector; + + /// Links - (Weight, BundleNo) for all transparent blocks connecting to other + /// bundles. The weights are all positive and add up to at most 2, weights + /// from ingoing and outgoing nodes separately add up to a most 1. The weight + /// sum can be less than 2 when the variable is not live into / out of some + /// connected basic blocks. + LinkVector Links; + + /// preferReg - Return true when this node prefers to be in a register. + bool preferReg() const { + // Undecided nodes (Value==0) go on the stack. + return Value > 0; + } + + /// mustSpill - Return True if this node is so biased that it must spill. + bool mustSpill() const { + // Actually, we must spill if Bias < sum(weights). + // It may be worth it to compute the weight sum here? + return Bias < -2.0f; + } + + /// Node - Create a blank Node. + Node() { + Frequency[0] = Frequency[1] = 0; + } + + /// clear - Reset per-query data, but preserve frequencies that only depend on + // the CFG. + void clear() { + Bias = Value = 0; + Links.clear(); + } + + /// addLink - Add a link to bundle b with weight w. + /// out=0 for an ingoing link, and 1 for an outgoing link. + void addLink(unsigned b, float w, bool out) { + // Normalize w relative to all connected blocks from that direction. + w /= Frequency[out]; + + // There can be multiple links to the same bundle, add them up. + for (LinkVector::iterator I = Links.begin(), E = Links.end(); I != E; ++I) + if (I->second == b) { + I->first += w; + return; + } + // This must be the first link to b. + Links.push_back(std::make_pair(w, b)); + } + + /// addBias - Bias this node from an ingoing[0] or outgoing[1] link. + void addBias(float w, bool out) { + // Normalize w relative to all connected blocks from that direction. + w /= Frequency[out]; + Bias += w; + } + + /// update - Recompute Value from Bias and Links. Return true when node + /// preference changes. + bool update(const Node nodes[]) { + // Compute the weighted sum of inputs. + float Sum = Bias; + for (LinkVector::iterator I = Links.begin(), E = Links.end(); I != E; ++I) + Sum += I->first * nodes[I->second].Value; + + // The weighted sum is going to be in the range [-2;2]. Ideally, we should + // simply set Value = sign(Sum), but we will add a dead zone around 0 for + // two reasons: + // 1. It avoids arbitrary bias when all links are 0 as is possible during + // initial iterations. + // 2. It helps tame rounding errors when the links nominally sum to 0. + const float Thres = 1e-4; + bool Before = preferReg(); + if (Sum < -Thres) + Value = -1; + else if (Sum > Thres) + Value = 1; + else + Value = 0; + return Before != preferReg(); + } +}; + +bool SpillPlacement::runOnMachineFunction(MachineFunction &mf) { + MF = &mf; + bundles = &getAnalysis(); + loops = &getAnalysis(); + + assert(!nodes && "Leaking node array"); + nodes = new Node[bundles->getNumBundles()]; + + // Compute total ingoing and outgoing block frequencies for all bundles. + for (MachineFunction::iterator I = mf.begin(), E = mf.end(); I != E; ++I) { + float Freq = getBlockFrequency(I); + unsigned Num = I->getNumber(); + nodes[bundles->getBundle(Num, 1)].Frequency[0] += Freq; + nodes[bundles->getBundle(Num, 0)].Frequency[1] += Freq; + } + + // We never change the function. + return false; +} + +void SpillPlacement::releaseMemory() { + delete[] nodes; + nodes = 0; +} + +/// activate - mark node n as active if it wasn't already. +void SpillPlacement::activate(unsigned n) { + if (ActiveNodes->test(n)) + return; + ActiveNodes->set(n); + nodes[n].clear(); +} + + +/// prepareNodes - Compute node biases and weights from a set of constraints. +/// Set a bit in NodeMask for each active node. +void SpillPlacement:: +prepareNodes(const SmallVectorImpl &LiveBlocks) { + DEBUG(dbgs() << "Building Hopfield network from " << LiveBlocks.size() + << " constraint blocks:\n"); + for (SmallVectorImpl::const_iterator I = LiveBlocks.begin(), + E = LiveBlocks.end(); I != E; ++I) { + MachineBasicBlock *MBB = MF->getBlockNumbered(I->Number); + float Freq = getBlockFrequency(MBB); + DEBUG(dbgs() << " BB#" << I->Number << format(", Freq = %.1f", Freq)); + + // Is this a transparent block? Link ingoing and outgoing bundles. + if (I->Entry == DontCare && I->Exit == DontCare) { + unsigned ib = bundles->getBundle(I->Number, 0); + unsigned ob = bundles->getBundle(I->Number, 1); + DEBUG(dbgs() << ", transparent EB#" << ib << " -> EB#" << ob << '\n'); + + // Ignore self-loops. + if (ib == ob) + continue; + activate(ib); + activate(ob); + nodes[ib].addLink(ob, Freq, 1); + nodes[ob].addLink(ib, Freq, 0); + continue; + } + + // This block is not transparent, but it can still add bias. + const float Bias[] = { + 0, // DontCare, + 1, // PrefReg, + -1, // PrefSpill + -HUGE_VALF // MustSpill + }; + + // Live-in to block? + if (I->Entry != DontCare) { + unsigned ib = bundles->getBundle(I->Number, 0); + activate(ib); + nodes[ib].addBias(Freq * Bias[I->Entry], 1); + DEBUG(dbgs() << format(", entry EB#%u %+.1f", ib, Freq * Bias[I->Entry])); + } + + // Live-out from block? + if (I->Exit != DontCare) { + unsigned ob = bundles->getBundle(I->Number, 1); + activate(ob); + nodes[ob].addBias(Freq * Bias[I->Exit], 0); + DEBUG(dbgs() << format(", exit EB#%u %+.1f", ob, Freq * Bias[I->Exit])); + } + + DEBUG(dbgs() << '\n'); + } +} + +/// iterate - Repeatedly update the Hopfield nodes until stability or the +/// maximum number of iterations is reached. +/// @param Linked - Numbers of linked nodes that need updating. +void SpillPlacement::iterate(const SmallVectorImpl &Linked) { + DEBUG(dbgs() << "Iterating over " << Linked.size() << " linked nodes:\n"); + if (Linked.empty()) + return; + + // Run up to 10 iterations. The edge bundle numbering is closely related to + // basic block numbering, so there is a strong tendency towards chains of + // linked nodes with sequential numbers. By scanning the linked nodes + // backwards and forwards, we make it very likely that a single node can + // affect the entire network in a single iteration. That means very fast + // convergence, usually in a single iteration. + for (unsigned iteration = 0; iteration != 10; ++iteration) { + // Scan backwards, skipping the last node which was just updated. + bool Changed = false; + for (SmallVectorImpl::const_reverse_iterator I = + llvm::next(Linked.rbegin()), E = Linked.rend(); I != E; ++I) { + unsigned n = *I; + bool C = nodes[n].update(nodes); + Changed |= C; + DEBUG(dbgs() << " \\EB#" << n << format(" = %+2.0f", nodes[n].Value) + << (C ? " *\n" : "\n")); + } + if (!Changed) + return; + + // Scan forwards, skipping the first node which was just updated. + Changed = false; + for (SmallVectorImpl::const_iterator I = + llvm::next(Linked.begin()), E = Linked.end(); I != E; ++I) { + unsigned n = *I; + bool C = nodes[n].update(nodes); + Changed |= C; + DEBUG(dbgs() << " /EB#" << n << format(" = %+2.0f", nodes[n].Value) + << (C ? " *\n" : "\n")); + } + if (!Changed) + return; + } +} + +bool +SpillPlacement::placeSpills(const SmallVectorImpl &LiveBlocks, + BitVector &RegBundles) { + // Reuse RegBundles as our ActiveNodes vector. + ActiveNodes = &RegBundles; + ActiveNodes->clear(); + ActiveNodes->resize(bundles->getNumBundles()); + + // Compute active nodes, links and biases. + prepareNodes(LiveBlocks); + + // Update all active nodes, and find the ones that are actually linked to + // something so their value may change when iterating. + DEBUG(dbgs() << "Network has " << RegBundles.count() << " active nodes:\n"); + SmallVector Linked; + for (int n = RegBundles.find_first(); n>=0; n = RegBundles.find_next(n)) { + nodes[n].update(nodes); + // A node that must spill, or a node without any links is not going to + // change its value ever again, so exclude it from iterations. + if (!nodes[n].Links.empty() && !nodes[n].mustSpill()) + Linked.push_back(n); + + DEBUG({ + dbgs() << " EB#" << n << format(" = %+2.0f", nodes[n].Value) + << format(", Bias %+.2f", nodes[n].Bias) + << format(", Freq %.1f/%.1f", nodes[n].Frequency[0], + nodes[n].Frequency[1]); + for (unsigned i = 0, e = nodes[n].Links.size(); i != e; ++i) + dbgs() << format(", %.2f -> EB#%u", nodes[n].Links[i].first, + nodes[n].Links[i].second); + dbgs() << '\n'; + }); + } + + // Iterate the network to convergence. + iterate(Linked); + + // Write preferences back to RegBundles. + bool Perfect = true; + for (int n = RegBundles.find_first(); n>=0; n = RegBundles.find_next(n)) + if (!nodes[n].preferReg()) { + RegBundles.reset(n); + Perfect = false; + } + return Perfect; +} + +/// getBlockFrequency - Return our best estimate of the block frequency which is +/// the expected number of block executions per function invocation. +float SpillPlacement::getBlockFrequency(const MachineBasicBlock *MBB) { + // Use the unnormalized spill weight for real block frequencies. + return LiveIntervals::getSpillWeight(true, false, loops->getLoopDepth(MBB)); +} + Added: llvm/trunk/lib/CodeGen/SpillPlacement.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SpillPlacement.h?rev=122938&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SpillPlacement.h (added) +++ llvm/trunk/lib/CodeGen/SpillPlacement.h Wed Jan 5 19:21:53 2011 @@ -0,0 +1,105 @@ +//===-- SpillPlacement.h - Optimal Spill Code Placement --------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This analysis computes the optimal spill code placement between basic blocks. +// +// The runOnMachineFunction() method only precomputes some profiling information +// about the CFG. The real work is done by placeSpills() which is called by the +// register allocator. +// +// Given a variable that is live across multiple basic blocks, and given +// constraints on the basic blocks where the variable is live, determine which +// edge bundles should have the variable in a register and which edge bundles +// should have the variable in a stack slot. +// +// The returned bit vector can be used to place optimal spill code at basic +// block entries and exits. Spill code placement inside a basic block is not +// considered. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_SPILLPLACEMENT_H +#define LLVM_CODEGEN_SPILLPLACEMENT_H + +#include "llvm/CodeGen/MachineFunctionPass.h" + +namespace llvm { + +class BitVector; +class EdgeBundles; +class MachineBasicBlock; +class MachineLoopInfo; +template class SmallVectorImpl; + +class SpillPlacement : public MachineFunctionPass { + struct Node; + const MachineFunction *MF; + const EdgeBundles *bundles; + const MachineLoopInfo *loops; + Node *nodes; + + // Nodes that are active in the current computation. Owned by the placeSpills + // caller. + BitVector *ActiveNodes; + +public: + static char ID; // Pass identification, replacement for typeid. + + SpillPlacement() : MachineFunctionPass(ID), nodes(0) {} + ~SpillPlacement() { releaseMemory(); } + + /// BorderConstraint - A basic block has separate constraints for entry and + /// exit. + enum BorderConstraint { + DontCare, ///< Block doesn't care / variable not live. + PrefReg, ///< Block entry/exit prefers a register. + PrefSpill, ///< Block entry/exit prefers a stack slot. + MustSpill ///< A register is impossible, variable must be spilled. + }; + + /// BlockConstraint - Entry and exit constraints for a basic block. + struct BlockConstraint { + unsigned Number; ///< Basic block number (from MBB::getNumber()). + BorderConstraint Entry : 8; ///< Constraint on block entry. + BorderConstraint Exit : 8; ///< Constraint on block exit. + }; + + /// placeSpills - Compute the optimal spill code placement given the + /// constraints. No MustSpill constraints will be violated, and the smallest + /// possible number of PrefX constraints will be violated, weighted by + /// expected execution frequencies. + /// @param LiveBlocks Constraints for blocks that have the variable live in or + /// live out. DontCare/DontCare means the variable is live + /// through the block. DontCare/X means the variable is live + /// out, but not live in. + /// @param RegBundles Bit vector to receive the edge bundles where the + /// variable should be kept in a register. Each bit + /// corresponds to an edge bundle, a set bit means the + /// variable should be kept in a register through the + /// bundle. A clear bit means the variable should be + /// spilled. + /// @return True if a perfect solution was found, allowing the variable to be + /// in a register through all relevant bundles. + bool placeSpills(const SmallVectorImpl &LiveBlocks, + BitVector &RegBundles); + +private: + virtual bool runOnMachineFunction(MachineFunction&); + virtual void getAnalysisUsage(AnalysisUsage&) const; + virtual void releaseMemory(); + + void activate(unsigned); + float getBlockFrequency(const MachineBasicBlock*); + void prepareNodes(const SmallVectorImpl&); + void iterate(const SmallVectorImpl&); +}; + +} // end namespace llvm + +#endif From gkistanova at gmail.com Wed Jan 5 19:31:52 2011 From: gkistanova at gmail.com (Galina Kistanova) Date: Thu, 06 Jan 2011 01:31:52 -0000 Subject: [llvm-commits] [zorg] r122939 - /zorg/trunk/buildbot/osuosl/master/config/slaves.py Message-ID: <20110106013152.21D8B2A6C12C@llvm.org> Author: gkistanova Date: Wed Jan 5 19:31:51 2011 New Revision: 122939 URL: http://llvm.org/viewvc/llvm-project?rev=122939&view=rev Log: Added new slave for build on i686-pc-mingw32 of cross llvm-gcc for arm-none-linux-gnueabi. Modified: zorg/trunk/buildbot/osuosl/master/config/slaves.py Modified: zorg/trunk/buildbot/osuosl/master/config/slaves.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/buildbot/osuosl/master/config/slaves.py?rev=122939&r1=122938&r2=122939&view=diff ============================================================================== --- zorg/trunk/buildbot/osuosl/master/config/slaves.py (original) +++ zorg/trunk/buildbot/osuosl/master/config/slaves.py Wed Jan 5 19:31:51 2011 @@ -54,6 +54,9 @@ # CentOS 5.4. create_slave("kistanova4", properties={'jobs' : 1}, max_builds=2), + # Win XP SP3. + create_slave("kistanova5", properties={'jobs' : 1}, max_builds=1), + # Quad Core x86_64, Solaris / AurorAUX create_slave("evocallaghan", properties={'jobs' : 4}, max_builds=1), From stoklund at 2pi.dk Wed Jan 5 19:33:22 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 06 Jan 2011 01:33:22 -0000 Subject: [llvm-commits] [llvm] r122940 - in /llvm/trunk/lib: CodeGen/RegAllocLinearScan.cpp Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp Message-ID: <20110106013322.A9A542A6C12C@llvm.org> Author: stoklund Date: Wed Jan 5 19:33:22 2011 New Revision: 122940 URL: http://llvm.org/viewvc/llvm-project?rev=122940&view=rev Log: Zap the last two -Wself-assign warnings in llvm. Simplify RALinScan::DowngradeRegister with TRI::getOverlaps while we are there. Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp llvm/trunk/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=122940&r1=122939&r2=122940&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Wed Jan 5 19:33:22 2011 @@ -933,13 +933,9 @@ } void RALinScan::DowngradeRegister(LiveInterval *li, unsigned Reg) { - bool isNew = DowngradedRegs.insert(Reg); - (void)isNew; // Silence compiler warning. - assert(isNew && "Multiple reloads holding the same register?"); - DowngradeMap.insert(std::make_pair(li->reg, Reg)); - for (const unsigned *AS = tri_->getAliasSet(Reg); *AS; ++AS) { - isNew = DowngradedRegs.insert(*AS); - isNew = isNew; // Silence compiler warning. + for (const unsigned *AS = tri_->getOverlaps(Reg); *AS; ++AS) { + bool isNew = DowngradedRegs.insert(*AS); + (void)isNew; // Silence compiler warning. assert(isNew && "Multiple reloads holding the same register?"); DowngradeMap.insert(std::make_pair(li->reg, *AS)); } Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp?rev=122940&r1=122939&r2=122940&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp Wed Jan 5 19:33:22 2011 @@ -97,7 +97,8 @@ InlineFunctionInfo IFI(0, TD); bool B = InlineFunction(Call, IFI); - assert(B && "half_powr didn't inline?"); B=B; + assert(B && "half_powr didn't inline?"); + (void)B; BasicBlock *NewBody = NewBlock->getSinglePredecessor(); assert(NewBody); From zwarich at apple.com Wed Jan 5 20:16:26 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 5 Jan 2011 18:16:26 -0800 Subject: [llvm-commits] [llvm] r122801 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: References: <20110104044331.3BD3E2A6C12C@llvm.org> <26A75B47-71D0-4125-B7FB-8FF965D0EB70@2pi.dk> <1CC24B63-4E25-4134-B9D4-D213A19001B6@2pi.dk> <35B5659B-6502-49B8-8799-3ADA45CA8781@apple.com> Message-ID: On Jan 5, 2011, at 3:44 PM, Jakob Stoklund Olesen wrote: > On Jan 5, 2011, at 2:53 PM, Cameron Zwarich wrote: >> I tried implementing this, only reiterating over each basic block after optimizing a memory instruction instead of rechecking the whole function. I got the following results on test-suite + SPEC2000 & SPEC2006. This seems to disagree with my previous printf-based approach to counting the extra improvements. > > [... almost, but not quite identical results ..] > >> I guess I'll still have to work at getting it closer in code quality. Maybe I'll need to make all of the optimizations feed into a worklist, which could be tricky. > > I think an instruction-based work list should give you even better performance than anything basic on basic blocks. > > Whenever an instruction is sunk, add all its operands to the work list. You should probably use a SetVector for stable results. At first glance, this looked a bit iffy with a worklist: } else if (CallInst *CI = dyn_cast(I)) { // If we found an inline asm expession, and if the target knows how to // lower it to normal LLVM code, do so now. if (TLI && isa(CI->getCalledValue())) { if (TLI->ExpandInlineAsm(CI)) { BBI = BB.begin(); // Avoid processing instructions out of order, which could cause // reuse before a value is defined. SunkAddrs.clear(); } else // Sink address computing for memory operands into the block. MadeChange |= OptimizeInlineAsmInst(I, &(*CI), SunkAddrs); } else { // Other CallInst optimizations that don't need to muck with the // enclosing iterator here. MadeChange |= OptimizeCallInst(CI); } } However, we could expand the inline assembly on the first pass and then do OptimizeInlineAsmInst and OptimizeCallInst on subsequent visits via the worklist. Cameron From zwarich at apple.com Wed Jan 5 20:37:26 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Thu, 06 Jan 2011 02:37:26 -0000 Subject: [llvm-commits] [llvm] r122943 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <20110106023726.A1BDC2A6C12C@llvm.org> Author: zwarich Date: Wed Jan 5 20:37:26 2011 New Revision: 122943 URL: http://llvm.org/viewvc/llvm-project?rev=122943&view=rev Log: Split the optimizations in CodeGenPrepare that don't manipulate the iterators into a separate function, so that it can be called from a loop using a worklist rather than a loop traversing a whole basic block. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=122943&r1=122942&r2=122943&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Jan 5 20:37:26 2011 @@ -98,6 +98,7 @@ bool CanMergeBlocks(const BasicBlock *BB, const BasicBlock *DestBB) const; void EliminateMostlyEmptyBlock(BasicBlock *BB); bool OptimizeBlock(BasicBlock &BB); + bool OptimizeInst(Instruction *I); bool OptimizeMemoryInst(Instruction *I, Value *Addr, const Type *AccessTy, DenseMap &SunkAddrs); bool OptimizeInlineAsmInst(Instruction *I, CallSite CS, @@ -959,6 +960,54 @@ return MadeChange; } +bool CodeGenPrepare::OptimizeInst(Instruction *I) { + bool MadeChange = false; + + if (PHINode *P = dyn_cast(I)) { + // It is possible for very late stage optimizations (such as SimplifyCFG) + // to introduce PHI nodes too late to be cleaned up. If we detect such a + // trivial PHI, go ahead and zap it here. + if (Value *V = SimplifyInstruction(P)) { + P->replaceAllUsesWith(V); + P->eraseFromParent(); + ++NumPHIsElim; + } + } else if (CastInst *CI = dyn_cast(I)) { + // If the source of the cast is a constant, then this should have + // already been constant folded. The only reason NOT to constant fold + // it is if something (e.g. LSR) was careful to place the constant + // evaluation in a block other than then one that uses it (e.g. to hoist + // the address of globals out of a loop). If this is the case, we don't + // want to forward-subst the cast. + if (isa(CI->getOperand(0))) + return false; + + bool Change = false; + if (TLI) { + Change = OptimizeNoopCopyExpression(CI, *TLI); + MadeChange |= Change; + } + + if (!Change && (isa(I) || isa(I))) { + MadeChange |= MoveExtToFormExtLoad(I); + MadeChange |= OptimizeExtUses(I); + } + } else if (CmpInst *CI = dyn_cast(I)) { + MadeChange |= OptimizeCmpExpression(CI); + } else if (LoadInst *LI = dyn_cast(I)) { + if (TLI) + MadeChange |= OptimizeMemoryInst(I, I->getOperand(0), LI->getType(), + SunkAddrs); + } else if (StoreInst *SI = dyn_cast(I)) { + if (TLI) + MadeChange |= OptimizeMemoryInst(I, SI->getOperand(1), + SI->getOperand(0)->getType(), + SunkAddrs); + } + + return MadeChange; +} + // In this pass we look for GEP and cast instructions that are used // across basic blocks and rewrite them to improve basic-block-at-a-time // selection. @@ -982,47 +1031,7 @@ for (BasicBlock::iterator BBI = BB.begin(), E = BB.end(); BBI != E; ) { Instruction *I = BBI++; - if (PHINode *P = dyn_cast(I)) { - // It is possible for very late stage optimizations (such as SimplifyCFG) - // to introduce PHI nodes too late to be cleaned up. If we detect such a - // trivial PHI, go ahead and zap it here. - if (Value *V = SimplifyInstruction(P)) { - P->replaceAllUsesWith(V); - P->eraseFromParent(); - ++NumPHIsElim; - } - } else if (CastInst *CI = dyn_cast(I)) { - // If the source of the cast is a constant, then this should have - // already been constant folded. The only reason NOT to constant fold - // it is if something (e.g. LSR) was careful to place the constant - // evaluation in a block other than then one that uses it (e.g. to hoist - // the address of globals out of a loop). If this is the case, we don't - // want to forward-subst the cast. - if (isa(CI->getOperand(0))) - continue; - - bool Change = false; - if (TLI) { - Change = OptimizeNoopCopyExpression(CI, *TLI); - MadeChange |= Change; - } - - if (!Change && (isa(I) || isa(I))) { - MadeChange |= MoveExtToFormExtLoad(I); - MadeChange |= OptimizeExtUses(I); - } - } else if (CmpInst *CI = dyn_cast(I)) { - MadeChange |= OptimizeCmpExpression(CI); - } else if (LoadInst *LI = dyn_cast(I)) { - if (TLI) - MadeChange |= OptimizeMemoryInst(I, I->getOperand(0), LI->getType(), - SunkAddrs); - } else if (StoreInst *SI = dyn_cast(I)) { - if (TLI) - MadeChange |= OptimizeMemoryInst(I, SI->getOperand(1), - SI->getOperand(0)->getType(), - SunkAddrs); - } else if (GetElementPtrInst *GEPI = dyn_cast(I)) { + if (GetElementPtrInst *GEPI = dyn_cast(I)) { if (GEPI->hasAllZeroIndices()) { /// The GEP operand must be a pointer, so must its result -> BitCast Instruction *NC = new BitCastInst(GEPI->getOperand(0), GEPI->getType(), @@ -1050,6 +1059,8 @@ // enclosing iterator here. MadeChange |= OptimizeCallInst(CI); } + } else { + MadeChange |= OptimizeInst(I); } } From stoklund at 2pi.dk Wed Jan 5 20:40:58 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 5 Jan 2011 18:40:58 -0800 Subject: [llvm-commits] [llvm] r122801 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: References: <20110104044331.3BD3E2A6C12C@llvm.org> <26A75B47-71D0-4125-B7FB-8FF965D0EB70@2pi.dk> <1CC24B63-4E25-4134-B9D4-D213A19001B6@2pi.dk> <35B5659B-6502-49B8-8799-3ADA45CA8781@apple.com> Message-ID: <29B10D4F-6FAA-4DCB-B959-41EA89D0DBF8@2pi.dk> On Jan 5, 2011, at 6:16 PM, Cameron Zwarich wrote: > However, we could expand the inline assembly on the first pass and then do OptimizeInlineAsmInst and OptimizeCallInst on subsequent visits via the worklist. Maybe you could go even further. It seems to me that only OptimizeNoopCopyExpression, OptimizeExtUses, and OptimizeCmpExpression can change anything on a second pass, but perhaps the AddressingModeMatcher used by OptimizeMemoryInst could also be affected? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110105/fa8af832/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1929 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110105/fa8af832/attachment.bin From zwarich at apple.com Wed Jan 5 20:42:08 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 5 Jan 2011 18:42:08 -0800 Subject: [llvm-commits] [llvm] r122801 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: <29B10D4F-6FAA-4DCB-B959-41EA89D0DBF8@2pi.dk> References: <20110104044331.3BD3E2A6C12C@llvm.org> <26A75B47-71D0-4125-B7FB-8FF965D0EB70@2pi.dk> <1CC24B63-4E25-4134-B9D4-D213A19001B6@2pi.dk> <35B5659B-6502-49B8-8799-3ADA45CA8781@apple.com> <29B10D4F-6FAA-4DCB-B959-41EA89D0DBF8@2pi.dk> Message-ID: <1D0F8595-FBD2-4C22-9B45-1558FA233C63@apple.com> On Jan 5, 2011, at 6:40 PM, Jakob Stoklund Olesen wrote: > On Jan 5, 2011, at 6:16 PM, Cameron Zwarich wrote: > >> However, we could expand the inline assembly on the first pass and then do OptimizeInlineAsmInst and OptimizeCallInst on subsequent visits via the worklist. > > Maybe you could go even further. It seems to me that only OptimizeNoopCopyExpression, OptimizeExtUses, and OptimizeCmpExpression can change anything on a second pass, but perhaps the AddressingModeMatcher used by OptimizeMemoryInst could also be affected? There are definitely memory inst optimizations triggered by later passes, although I haven't looked at any in particular. Cameron -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110105/769b4fcd/attachment.html From zwarich at apple.com Wed Jan 5 20:44:52 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Thu, 06 Jan 2011 02:44:52 -0000 Subject: [llvm-commits] [llvm] r122944 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <20110106024452.89CF52A6C12C@llvm.org> Author: zwarich Date: Wed Jan 5 20:44:52 2011 New Revision: 122944 URL: http://llvm.org/viewvc/llvm-project?rev=122944&view=rev Log: Move the GEP handling in CodeGenPrepare to OptimizeInst(). Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=122944&r1=122943&r2=122944&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Jan 5 20:44:52 2011 @@ -1003,6 +1003,17 @@ MadeChange |= OptimizeMemoryInst(I, SI->getOperand(1), SI->getOperand(0)->getType(), SunkAddrs); + } else if (GetElementPtrInst *GEPI = dyn_cast(I)) { + if (GEPI->hasAllZeroIndices()) { + /// The GEP operand must be a pointer, so must its result -> BitCast + Instruction *NC = new BitCastInst(GEPI->getOperand(0), GEPI->getType(), + GEPI->getName(), GEPI); + GEPI->replaceAllUsesWith(NC); + GEPI->eraseFromParent(); + ++NumGEPsElim; + MadeChange = true; + OptimizeInst(NC); + } } return MadeChange; @@ -1031,18 +1042,7 @@ for (BasicBlock::iterator BBI = BB.begin(), E = BB.end(); BBI != E; ) { Instruction *I = BBI++; - if (GetElementPtrInst *GEPI = dyn_cast(I)) { - if (GEPI->hasAllZeroIndices()) { - /// The GEP operand must be a pointer, so must its result -> BitCast - Instruction *NC = new BitCastInst(GEPI->getOperand(0), GEPI->getType(), - GEPI->getName(), GEPI); - GEPI->replaceAllUsesWith(NC); - GEPI->eraseFromParent(); - ++NumGEPsElim; - MadeChange = true; - BBI = NC; - } - } else if (CallInst *CI = dyn_cast(I)) { + if (CallInst *CI = dyn_cast(I)) { // If we found an inline asm expession, and if the target knows how to // lower it to normal LLVM code, do so now. if (TLI && isa(CI->getCalledValue())) { From zwarich at apple.com Wed Jan 5 20:56:42 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Thu, 06 Jan 2011 02:56:42 -0000 Subject: [llvm-commits] [llvm] r122945 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <20110106025642.47BA92A6C12C@llvm.org> Author: zwarich Date: Wed Jan 5 20:56:42 2011 New Revision: 122945 URL: http://llvm.org/viewvc/llvm-project?rev=122945&view=rev Log: Add the CallInst optimizations that don't involve expanding inline assembly to OptimizeInst() so that they can be used on a worklist instruction. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=122945&r1=122944&r2=122945&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Jan 5 20:56:42 2011 @@ -1014,6 +1014,13 @@ MadeChange = true; OptimizeInst(NC); } + } else if (CallInst *CI = dyn_cast(I)) { + if (TLI && isa(CI->getCalledValue())) { + // Sink address computing for memory operands into the block. + MadeChange |= OptimizeInlineAsmInst(I, &(*CI), SunkAddrs); + } else { + MadeChange |= OptimizeCallInst(CI); + } } return MadeChange; From bigcheesegs at gmail.com Wed Jan 5 23:57:54 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Thu, 06 Jan 2011 05:57:54 -0000 Subject: [llvm-commits] [llvm] r122947 - /llvm/trunk/unittests/Support/Path.cpp Message-ID: <20110106055754.82ADD2A6C12C@llvm.org> Author: mspencer Date: Wed Jan 5 23:57:54 2011 New Revision: 122947 URL: http://llvm.org/viewvc/llvm-project?rev=122947&view=rev Log: UnitTests/Path: More ASSERT_NO_ERROR cleanup. Modified: llvm/trunk/unittests/Support/Path.cpp Modified: llvm/trunk/unittests/Support/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Path.cpp?rev=122947&r1=122946&r2=122947&view=diff ============================================================================== --- llvm/trunk/unittests/Support/Path.cpp (original) +++ llvm/trunk/unittests/Support/Path.cpp Wed Jan 5 23:57:54 2011 @@ -10,6 +10,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/PathV2.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include "gtest/gtest.h" @@ -17,12 +18,13 @@ using namespace llvm::sys; #define ASSERT_NO_ERROR(x) \ - if (error_code ec = x) { \ - SmallString<128> Message; \ - GTEST_FATAL_FAILURE_((Twine(#x ": did not return errc::success.\n") + \ - "error number: " + Twine(ec.value()) + "\n" + \ - "error message: " + \ - ec.message()).toNullTerminatedStringRef(Message).data()); \ + if (error_code ASSERT_NO_ERROR_ec = x) { \ + SmallString<128> MessageStorage; \ + raw_svector_ostream Message(MessageStorage); \ + Message << #x ": did not return errc::success.\n" \ + << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \ + << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \ + GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \ } else {} namespace { @@ -206,12 +208,9 @@ TEST_F(FileSystemTest, DirectoryIteration) { error_code ec; - for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec)) { - if (ec) { - errs() << ec.message() << '\n'; - errs().flush(); - report_fatal_error("Directory iteration failed!"); - } + for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec)) + ASSERT_NO_ERROR(ec); +} } } From bigcheesegs at gmail.com Wed Jan 5 23:58:02 2011 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Thu, 06 Jan 2011 05:58:02 -0000 Subject: [llvm-commits] [llvm] r122948 - /llvm/trunk/unittests/Support/Path.cpp Message-ID: <20110106055802.9F5352A6C12C@llvm.org> Author: mspencer Date: Wed Jan 5 23:58:02 2011 New Revision: 122948 URL: http://llvm.org/viewvc/llvm-project?rev=122948&view=rev Log: UnitTests/Path: Add magical tests. This will also test identify_magic. Modified: llvm/trunk/unittests/Support/Path.cpp Modified: llvm/trunk/unittests/Support/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Path.cpp?rev=122948&r1=122947&r2=122948&view=diff ============================================================================== --- llvm/trunk/unittests/Support/Path.cpp (original) +++ llvm/trunk/unittests/Support/Path.cpp Wed Jan 5 23:58:02 2011 @@ -211,6 +211,29 @@ for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec)) ASSERT_NO_ERROR(ec); } + +TEST_F(FileSystemTest, Magic) { + struct type { + const char *filename; + const char *magic_str; + size_t magic_str_len; + } types [] = {{"magic.archive", "!\x0A", 8}}; + + // Create some files filled with magic. + for (type *i = types, *e = types + (sizeof(types) / sizeof(type)); i != e; + ++i) { + SmallString<128> file_pathname(TestDirectory); + path::append(file_pathname, i->filename); + std::string ErrMsg; + raw_fd_ostream file(file_pathname.c_str(), ErrMsg, + raw_fd_ostream::F_Binary); + ASSERT_FALSE(file.has_error()); + StringRef magic(i->magic_str, i->magic_str_len); + file << magic; + file.flush(); + bool res = false; + ASSERT_NO_ERROR(fs::has_magic(file_pathname.c_str(), magic, res)); + EXPECT_TRUE(res); } } From evan.cheng at apple.com Thu Jan 6 00:17:53 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 06 Jan 2011 06:17:53 -0000 Subject: [llvm-commits] [llvm] r122949 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAG.cpp test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll test/CodeGen/X86/memcpy.ll Message-ID: <20110106061754.0D0542A6C12C@llvm.org> Author: evancheng Date: Thu Jan 6 00:17:53 2011 New Revision: 122949 URL: http://llvm.org/viewvc/llvm-project?rev=122949&view=rev Log: Revert r122936. I'll re-implement the change. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll llvm/trunk/test/CodeGen/X86/memcpy.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=122949&r1=122948&r2=122949&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Jan 6 00:17:53 2011 @@ -50,7 +50,6 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/Triple.h" #include #include using namespace llvm; @@ -3287,14 +3286,8 @@ // the size of a call to memcpy or memset (3 arguments + call). if (Limit != ~0U) { const Function *F = DAG.getMachineFunction().getFunction(); - if (F->hasFnAttr(Attribute::OptimizeForSize)) { - Triple T(((LLVMTargetMachine&)TLI.getTargetMachine()).getTargetTriple()); - if (T.getOS() != Triple::Darwin) - // A pretty terrible hack to defat the wild guess. On Darwin, -Os means - // optimize for size without hurting performance so we don't want to - // bump down the limit. - Limit = 4; - } + if (F->hasFnAttr(Attribute::OptimizeForSize)) + Limit = 4; } unsigned NumMemOps = 0; Modified: llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll?rev=122949&r1=122948&r2=122949&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll Thu Jan 6 00:17:53 2011 @@ -1,4 +1,4 @@ -; RUN: llc -O1 -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic -disable-fp-elim < %s | FileCheck %s +; RUN: llc -O1 -mtriple=x86_64-apple-darwin10 -relocation-model=pic -disable-fp-elim < %s | FileCheck %s ; %struct.type = type { %struct.subtype*, i32, i8, i32, i8, i32, i32, i32, i32, i32, i8, i32, i32, i32, i32, i32, [256 x i32], i32, [257 x i32], [257 x i32], i32*, i16*, i8*, i32, i32, i32, i32, i32, [256 x i8], [16 x i8], [256 x i8], [4096 x i8], [16 x i32], [18002 x i8], [18002 x i8], [6 x [258 x i8]], [6 x [258 x i32]], [6 x [258 x i32]], [6 x [258 x i32]], [6 x i32], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32*, i32*, i32* } @@ -21,9 +21,9 @@ ; statement. It can be an ADD or LEA instruction, it's not important which one ; it is. ; -; CHECK: # %bb -; CHECK: addq $64036, %rdi -; CHECK: rep;stosl +; CHECK: ## %bb +; CHECK-NEXT: addq $64036, %rdi +; CHECK: rep;stosl %tmp5 = bitcast i32* %tmp4 to i8* call void @llvm.memset.p0i8.i64(i8* %tmp5, i8 0, i64 84, i32 4, i1 false) Modified: llvm/trunk/test/CodeGen/X86/memcpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memcpy.ll?rev=122949&r1=122948&r2=122949&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memcpy.ll (original) +++ llvm/trunk/test/CodeGen/X86/memcpy.ll Thu Jan 6 00:17:53 2011 @@ -1,5 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s -check-prefix=LINUX -; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s -check-prefix=DARWIN +; RUN: llc < %s -march=x86-64 | FileCheck %s declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind @@ -10,8 +9,8 @@ tail call void @llvm.memcpy.p0i8.p0i8.i64( i8* %a, i8* %b, i64 %n, i32 1, i1 0 ) ret i8* %a -; LINUX: test1: -; LINUX: memcpy +; CHECK: test1: +; CHECK: memcpy } ; Variable memcpy's should lower to calls. @@ -22,41 +21,18 @@ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp14, i8* %tmp25, i64 %n, i32 8, i1 0 ) ret i8* %tmp14 -; LINUX: test2: -; LINUX: memcpy +; CHECK: test2: +; CHECK: memcpy } ; Large constant memcpy's should lower to a call when optimizing for size. ; PR6623 - -; On the other hand, Darwin's definition of -Os is optimizing for size without -; hurting performance so it should just ignore optsize when expanding memcpy. -; rdar://8821501 define void @test3(i8* nocapture %A, i8* nocapture %B) nounwind optsize noredzone { entry: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i32 1, i1 false) ret void -; LINUX: test3: -; LINUX: memcpy - -; DARWIN: test3: -; DARWIN-NOT: memcpy -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq +; CHECK: test3: +; CHECK: memcpy } ; Large constant memcpy's should be inlined when not optimizing for size. @@ -64,18 +40,18 @@ entry: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i32 1, i1 false) ret void -; LINUX: test4: -; LINUX movq -; LINUX movq -; LINUX movq -; LINUX movq -; LINUX movq -; LINUX movq -; LINUX movq -; LINUX movq -; LINUX movq -; LINUX movq -; LINUX movq -; LINUX movq +; CHECK: test4: +; CHECK: movq +; CHECK: movq +; CHECK: movq +; CHECK: movq +; CHECK: movq +; CHECK: movq +; CHECK: movq +; CHECK: movq +; CHECK: movq +; CHECK: movq +; CHECK: movq +; CHECK: movq } From sabre at nondot.org Thu Jan 6 00:19:46 2011 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Jan 2011 06:19:46 -0000 Subject: [llvm-commits] [llvm] r122950 - in /llvm/trunk: lib/Analysis/ConstantFolding.cpp test/Transforms/InstCombine/constant-fold-gep.ll Message-ID: <20110106061946.A48182A6C12C@llvm.org> Author: lattner Date: Thu Jan 6 00:19:46 2011 New Revision: 122950 URL: http://llvm.org/viewvc/llvm-project?rev=122950&view=rev Log: implement constant folding support for an exotic constant expr: ret i64 ptrtoint (i8* getelementptr ([1000 x i8]* @X, i64 1, i64 sub (i64 0, i64 ptrtoint ([1000 x i8]* @X to i64))) to i64) to "ret i64 1000". This allows us to correctly compute the trip count on a loop in PR8883, which occurs with std::fill on a char array. This allows us to transform it into a memset with a constant size. Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=122950&r1=122949&r2=122950&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Thu Jan 6 00:19:46 2011 @@ -575,8 +575,26 @@ // If this is a constant expr gep that is effectively computing an // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12' for (unsigned i = 1; i != NumOps; ++i) - if (!isa(Ops[i])) + if (!isa(Ops[i])) { + + // If this is "gep i8* Ptr, (sub 0, V)", fold this as: + // "inttoptr (sub (ptrtoint Ptr), V)" + if (NumOps == 2 && + cast(ResultTy)->getElementType()->isIntegerTy(8)) { + ConstantExpr *CE = dyn_cast(Ops[1]); + if (CE && CE->getOpcode() == Instruction::Sub && + isa(CE->getOperand(0)) && + cast(CE->getOperand(0))->isZero()) { + Constant *Res = ConstantExpr::getPtrToInt(Ptr, CE->getType()); + Res = ConstantExpr::getSub(Res, CE->getOperand(1)); + Res = ConstantExpr::getIntToPtr(Res, ResultTy); + if (ConstantExpr *ResCE = dyn_cast(Res)) + Res = ConstantFoldConstantExpression(ResCE, TD); + return Res; + } + } return 0; + } APInt Offset = APInt(BitWidth, TD->getIndexedOffset(Ptr->getType(), Modified: llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll?rev=122950&r1=122949&r2=122950&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll Thu Jan 6 00:19:46 2011 @@ -53,3 +53,22 @@ store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 19), align 8 ret void } + + +; PR8883 - Constant fold exotic gep subtract +; CHECK: @test2 + at X = global [1000 x i8] zeroinitializer, align 16 + +define i64 @test2() { +entry: + %A = bitcast i8* getelementptr inbounds ([1000 x i8]* @X, i64 1, i64 0) to i8* + %B = bitcast i8* getelementptr inbounds ([1000 x i8]* @X, i64 0, i64 0) to i8* + + %B2 = ptrtoint i8* %B to i64 + %C = sub i64 0, %B2 + %D = getelementptr i8* %A, i64 %C + %E = ptrtoint i8* %D to i64 + + ret i64 %E + ; CHECK: ret i64 1000 +} From clattner at apple.com Thu Jan 6 00:49:12 2011 From: clattner at apple.com (Chris Lattner) Date: Wed, 5 Jan 2011 22:49:12 -0800 Subject: [llvm-commits] [PATCH] Fix: instcombine does not get max if hidden by sext In-Reply-To: <4D22A780.6060209@fim.uni-passau.de> References: <4D22A780.6060209@fim.uni-passau.de> Message-ID: <48360275-C1A1-4AB1-A1A2-F5609C52094B@apple.com> On Jan 3, 2011, at 8:52 PM, Tobias Grosser wrote: > Hi, > > I fixed a recent bug report, that blocked me on a large FORTRAN test case: > > InstCombine: > X = sext x ; x < c ? X : C-1 > --> > X = sext x; X > C-1 ? C-1 : X > > Instead of calculating this with mixed types promote all to the > larger type. This enables scalar evolution to analyze this > expression. PR8866 Cool, thanks for tackling this. A couple comments though: Generally, the logic involved is complex enough that it is probably best to pull it out into a static helper function. This should make it easier to read. Instead of things like: + SExtInst *TrueValSExt = dyn_cast(TrueVal); + SExtInst *FalseValSExt = dyn_cast(FalseVal); + + AdjustedRHS = ConstantExpr::getSExt(AdjustedRHS, SI.getType()); + + if (TrueValSExt && CmpLHS == TrueValSExt->getOperand(0) + && AdjustedRHS == FalseVal) + CmpLHS = TrueVal; Please use: if (match(TrueVal, m_SExt(m_Specific(CmpLHS))) && AdjustedRHS == FalseVal) CmpLHS = TrueVal; It's probably also good to get Frits to review this, he has a keen eye :) Thanks for working on this! -Chris From evan.cheng at apple.com Thu Jan 6 00:52:41 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 06 Jan 2011 06:52:41 -0000 Subject: [llvm-commits] [llvm] r122952 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/XCore/XCoreISelLowering.cpp test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll test/CodeGen/X86/memcpy.ll Message-ID: <20110106065242.40D422A6C12C@llvm.org> Author: evancheng Date: Thu Jan 6 00:52:41 2011 New Revision: 122952 URL: http://llvm.org/viewvc/llvm-project?rev=122952&view=rev Log: Re-implement r122936 with proper target hooks. Now getMaxStoresPerMemcpy etc. takes an option OptSize. If OptSize is true, it would return the inline limit for functions with attribute OptSize. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll llvm/trunk/test/CodeGen/X86/memcpy.ll Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=122952&r1=122951&r2=122952&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Thu Jan 6 00:52:41 2011 @@ -642,21 +642,30 @@ /// This function returns the maximum number of store operations permitted /// to replace a call to llvm.memset. The value is set by the target at the - /// performance threshold for such a replacement. + /// performance threshold for such a replacement. If OptSize is true, + /// return the limit for functions that have OptSize attribute. /// @brief Get maximum # of store operations permitted for llvm.memset - unsigned getMaxStoresPerMemset() const { return maxStoresPerMemset; } + unsigned getMaxStoresPerMemset(bool OptSize) const { + return OptSize ? maxStoresPerMemsetOptSize : maxStoresPerMemset; + } /// This function returns the maximum number of store operations permitted /// to replace a call to llvm.memcpy. The value is set by the target at the - /// performance threshold for such a replacement. + /// performance threshold for such a replacement. If OptSize is true, + /// return the limit for functions that have OptSize attribute. /// @brief Get maximum # of store operations permitted for llvm.memcpy - unsigned getMaxStoresPerMemcpy() const { return maxStoresPerMemcpy; } + unsigned getMaxStoresPerMemcpy(bool OptSize) const { + return OptSize ? maxStoresPerMemcpyOptSize : maxStoresPerMemcpy; + } /// This function returns the maximum number of store operations permitted /// to replace a call to llvm.memmove. The value is set by the target at the - /// performance threshold for such a replacement. + /// performance threshold for such a replacement. If OptSize is true, + /// return the limit for functions that have OptSize attribute. /// @brief Get maximum # of store operations permitted for llvm.memmove - unsigned getMaxStoresPerMemmove() const { return maxStoresPerMemmove; } + unsigned getMaxStoresPerMemmove(bool OptSize) const { + return OptSize ? maxStoresPerMemmoveOptSize : maxStoresPerMemmove; + } /// This function returns true if the target allows unaligned memory accesses. /// of the specified type. This is used, for example, in situations where an @@ -1776,6 +1785,10 @@ /// @brief Specify maximum number of store instructions per memset call. unsigned maxStoresPerMemset; + /// Maximum number of stores operations that may be substituted for the call + /// to memset, used for functions with OptSize attribute. + unsigned maxStoresPerMemsetOptSize; + /// When lowering \@llvm.memcpy this field specifies the maximum number of /// store operations that may be substituted for a call to memcpy. Targets /// must set this value based on the cost threshold for that target. Targets @@ -1788,6 +1801,10 @@ /// @brief Specify maximum bytes of store instructions per memcpy call. unsigned maxStoresPerMemcpy; + /// Maximum number of store operations that may be substituted for a call + /// to memcpy, used for functions with OptSize attribute. + unsigned maxStoresPerMemcpyOptSize; + /// When lowering \@llvm.memmove this field specifies the maximum number of /// store instructions that may be substituted for a call to memmove. Targets /// must set this value based on the cost threshold for that target. Targets @@ -1799,6 +1816,10 @@ /// @brief Specify maximum bytes of store instructions per memmove call. unsigned maxStoresPerMemmove; + /// Maximum number of store instructions that may be substituted for a call + /// to memmove, used for functions with OpSize attribute. + unsigned maxStoresPerMemmoveOptSize; + /// This field specifies whether the target can benefit from code placement /// optimization. bool benefitFromCodePlacementOpt; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=122952&r1=122951&r2=122952&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Jan 6 00:52:41 2011 @@ -3281,15 +3281,6 @@ VT = LVT; } - // If we're optimizing for size, and there is a limit, bump the maximum number - // of operations inserted down to 4. This is a wild guess that approximates - // the size of a call to memcpy or memset (3 arguments + call). - if (Limit != ~0U) { - const Function *F = DAG.getMachineFunction().getFunction(); - if (F->hasFnAttr(Attribute::OptimizeForSize)) - Limit = 4; - } - unsigned NumMemOps = 0; while (Size != 0) { unsigned VTSize = VT.getSizeInBits() / 8; @@ -3335,7 +3326,9 @@ const TargetLowering &TLI = DAG.getTargetLoweringInfo(); std::vector MemOps; bool DstAlignCanChange = false; - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + bool OptSize = MF.getFunction()->hasFnAttr(Attribute::OptimizeForSize); FrameIndexSDNode *FI = dyn_cast(Dst); if (FI && !MFI->isFixedObjectIndex(FI->getIndex())) DstAlignCanChange = true; @@ -3345,7 +3338,7 @@ std::string Str; bool CopyFromStr = isMemSrcFromString(Src, Str); bool isZeroStr = CopyFromStr && Str.empty(); - unsigned Limit = AlwaysInline ? ~0U : TLI.getMaxStoresPerMemcpy(); + unsigned Limit = AlwaysInline ? ~0U : TLI.getMaxStoresPerMemcpy(OptSize); if (!FindOptimalMemOpLowering(MemOps, Limit, Size, (DstAlignCanChange ? 0 : Align), @@ -3426,14 +3419,16 @@ const TargetLowering &TLI = DAG.getTargetLoweringInfo(); std::vector MemOps; bool DstAlignCanChange = false; - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + bool OptSize = MF.getFunction()->hasFnAttr(Attribute::OptimizeForSize); FrameIndexSDNode *FI = dyn_cast(Dst); if (FI && !MFI->isFixedObjectIndex(FI->getIndex())) DstAlignCanChange = true; unsigned SrcAlign = DAG.InferPtrAlignment(Src); if (Align > SrcAlign) SrcAlign = Align; - unsigned Limit = AlwaysInline ? ~0U : TLI.getMaxStoresPerMemmove(); + unsigned Limit = AlwaysInline ? ~0U : TLI.getMaxStoresPerMemmove(OptSize); if (!FindOptimalMemOpLowering(MemOps, Limit, Size, (DstAlignCanChange ? 0 : Align), @@ -3502,13 +3497,15 @@ const TargetLowering &TLI = DAG.getTargetLoweringInfo(); std::vector MemOps; bool DstAlignCanChange = false; - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + bool OptSize = MF.getFunction()->hasFnAttr(Attribute::OptimizeForSize); FrameIndexSDNode *FI = dyn_cast(Dst); if (FI && !MFI->isFixedObjectIndex(FI->getIndex())) DstAlignCanChange = true; bool NonScalarIntSafe = isa(Src) && cast(Src)->isNullValue(); - if (!FindOptimalMemOpLowering(MemOps, TLI.getMaxStoresPerMemset(), + if (!FindOptimalMemOpLowering(MemOps, TLI.getMaxStoresPerMemset(OptSize), Size, (DstAlignCanChange ? 0 : Align), 0, NonScalarIntSafe, false, DAG, TLI)) return SDValue(); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=122952&r1=122951&r2=122952&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Thu Jan 6 00:52:41 2011 @@ -567,6 +567,8 @@ memset(RegClassForVT, 0,MVT::LAST_VALUETYPE*sizeof(TargetRegisterClass*)); memset(TargetDAGCombineArray, 0, array_lengthof(TargetDAGCombineArray)); maxStoresPerMemset = maxStoresPerMemcpy = maxStoresPerMemmove = 8; + maxStoresPerMemsetOptSize = maxStoresPerMemcpyOptSize + = maxStoresPerMemmoveOptSize = 4; benefitFromCodePlacementOpt = false; UseUnderscoreSetJmp = false; UseUnderscoreLongJmp = false; Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=122952&r1=122951&r2=122952&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu Jan 6 00:52:41 2011 @@ -687,7 +687,8 @@ else setSchedulingPreference(Sched::Hybrid); - maxStoresPerMemcpy = 1; //// temporary - rewrite interface to use type + //// temporary - rewrite interface to use type + maxStoresPerMemcpy = maxStoresPerMemcpyOptSize = 1; // On ARM arguments smaller than 4 bytes are extended, so all arguments // are at least 4 bytes aligned. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=122952&r1=122951&r2=122952&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Jan 6 00:52:41 2011 @@ -978,11 +978,14 @@ computeRegisterProperties(); - // FIXME: These should be based on subtarget info. Plus, the values should - // be smaller when we are in optimizing for size mode. + // On Darwin, -Os means optimize for size without hurting performance, + // do not reduce the limit. maxStoresPerMemset = 16; // For @llvm.memset -> sequence of stores + maxStoresPerMemsetOptSize = Subtarget->isTargetDarwin() ? 16 : 8; maxStoresPerMemcpy = 8; // For @llvm.memcpy -> sequence of stores - maxStoresPerMemmove = 3; // For @llvm.memmove -> sequence of stores + maxStoresPerMemcpyOptSize = Subtarget->isTargetDarwin() ? 8 : 4; + maxStoresPerMemmove = 8; // For @llvm.memmove -> sequence of stores + maxStoresPerMemmoveOptSize = Subtarget->isTargetDarwin() ? 8 : 4; setPrefLoopAlignment(16); benefitFromCodePlacementOpt = true; } Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=122952&r1=122951&r2=122952&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original) +++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Thu Jan 6 00:52:41 2011 @@ -149,8 +149,9 @@ setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); - maxStoresPerMemset = 4; - maxStoresPerMemmove = maxStoresPerMemcpy = 2; + maxStoresPerMemset = maxStoresPerMemsetOptSize = 4; + maxStoresPerMemmove = maxStoresPerMemmoveOptSize + = maxStoresPerMemcpy = maxStoresPerMemcpyOptSize = 2; // We have target-specific dag combine patterns for the following nodes: setTargetDAGCombine(ISD::STORE); Modified: llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll?rev=122952&r1=122951&r2=122952&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll Thu Jan 6 00:52:41 2011 @@ -1,4 +1,4 @@ -; RUN: llc -O1 -mtriple=x86_64-apple-darwin10 -relocation-model=pic -disable-fp-elim < %s | FileCheck %s +; RUN: llc -O1 -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic -disable-fp-elim < %s | FileCheck %s ; %struct.type = type { %struct.subtype*, i32, i8, i32, i8, i32, i32, i32, i32, i32, i8, i32, i32, i32, i32, i32, [256 x i32], i32, [257 x i32], [257 x i32], i32*, i16*, i8*, i32, i32, i32, i32, i32, [256 x i8], [16 x i8], [256 x i8], [4096 x i8], [16 x i32], [18002 x i8], [18002 x i8], [6 x [258 x i8]], [6 x [258 x i32]], [6 x [258 x i32]], [6 x [258 x i32]], [6 x i32], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32*, i32*, i32* } @@ -21,9 +21,9 @@ ; statement. It can be an ADD or LEA instruction, it's not important which one ; it is. ; -; CHECK: ## %bb -; CHECK-NEXT: addq $64036, %rdi -; CHECK: rep;stosl +; CHECK: # %bb +; CHECK: addq $64036, %rdi +; CHECK: rep;stosl %tmp5 = bitcast i32* %tmp4 to i8* call void @llvm.memset.p0i8.i64(i8* %tmp5, i8 0, i64 84, i32 4, i1 false) Modified: llvm/trunk/test/CodeGen/X86/memcpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memcpy.ll?rev=122952&r1=122951&r2=122952&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memcpy.ll (original) +++ llvm/trunk/test/CodeGen/X86/memcpy.ll Thu Jan 6 00:52:41 2011 @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=x86-64 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s -check-prefix=LINUX +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s -check-prefix=DARWIN declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind @@ -9,8 +10,8 @@ tail call void @llvm.memcpy.p0i8.p0i8.i64( i8* %a, i8* %b, i64 %n, i32 1, i1 0 ) ret i8* %a -; CHECK: test1: -; CHECK: memcpy +; LINUX: test1: +; LINUX: memcpy } ; Variable memcpy's should lower to calls. @@ -21,18 +22,41 @@ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp14, i8* %tmp25, i64 %n, i32 8, i1 0 ) ret i8* %tmp14 -; CHECK: test2: -; CHECK: memcpy +; LINUX: test2: +; LINUX: memcpy } ; Large constant memcpy's should lower to a call when optimizing for size. ; PR6623 + +; On the other hand, Darwin's definition of -Os is optimizing for size without +; hurting performance so it should just ignore optsize when expanding memcpy. +; rdar://8821501 define void @test3(i8* nocapture %A, i8* nocapture %B) nounwind optsize noredzone { entry: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i32 1, i1 false) ret void -; CHECK: test3: -; CHECK: memcpy +; LINUX: test3: +; LINUX: memcpy + +; DARWIN: test3: +; DARWIN-NOT: memcpy +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq } ; Large constant memcpy's should be inlined when not optimizing for size. @@ -40,18 +64,18 @@ entry: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i32 1, i1 false) ret void -; CHECK: test4: -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq -; CHECK: movq +; LINUX: test4: +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq +; LINUX movq } From sabre at nondot.org Thu Jan 6 01:09:23 2011 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Jan 2011 07:09:23 -0000 Subject: [llvm-commits] [llvm] r122953 - /llvm/trunk/lib/Target/README.txt Message-ID: <20110106070923.939402A6C12C@llvm.org> Author: lattner Date: Thu Jan 6 01:09:23 2011 New Revision: 122953 URL: http://llvm.org/viewvc/llvm-project?rev=122953&view=rev Log: add a trivial instcombine missed in Dhrystone 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=122953&r1=122952&r2=122953&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Thu Jan 6 01:09:23 2011 @@ -1964,4 +1964,41 @@ //===---------------------------------------------------------------------===// +This code (from Benchmarks/Dhrystone/dry.c): + +define i32 @Func1(i32, i32) nounwind readnone optsize ssp { +entry: + %sext = shl i32 %0, 24 + %conv = ashr i32 %sext, 24 + %sext6 = shl i32 %1, 24 + %conv4 = ashr i32 %sext6, 24 + %cmp = icmp eq i32 %conv, %conv4 + %. = select i1 %cmp, i32 10000, i32 0 + ret i32 %. +} + +Should be simplified into something like: + +define i32 @Func1(i32, i32) nounwind readnone optsize ssp { +entry: + %sext = shl i32 %0, 24 + %conv = and i32 %sext, 0xFF000000 + %sext6 = shl i32 %1, 24 + %conv4 = and i32 %sext6, 0xFF000000 + %cmp = icmp eq i32 %conv, %conv4 + %. = select i1 %cmp, i32 10000, i32 0 + ret i32 %. +} + +and then to: + +define i32 @Func1(i32, i32) nounwind readnone optsize ssp { +entry: + %conv = and i32 %0, 0xFF + %conv4 = and i32 %1, 0xFF + %cmp = icmp eq i32 %conv, %conv4 + %. = select i1 %cmp, i32 10000, i32 0 + ret i32 %. +} +//===---------------------------------------------------------------------===// From zwarich at apple.com Thu Jan 6 01:17:05 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 5 Jan 2011 23:17:05 -0800 Subject: [llvm-commits] [llvm] r122801 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: References: <20110104044331.3BD3E2A6C12C@llvm.org> <26A75B47-71D0-4125-B7FB-8FF965D0EB70@2pi.dk> <1CC24B63-4E25-4134-B9D4-D213A19001B6@2pi.dk> <35B5659B-6502-49B8-8799-3ADA45CA8781@apple.com> Message-ID: <1613B3BB-8D9B-4DD2-9B65-C86317990707@apple.com> On Jan 5, 2011, at 3:44 PM, Jakob Stoklund Olesen wrote: > On Jan 5, 2011, at 2:53 PM, Cameron Zwarich wrote: >> I tried implementing this, only reiterating over each basic block after optimizing a memory instruction instead of rechecking the whole function. I got the following results on test-suite + SPEC2000 & SPEC2006. This seems to disagree with my previous printf-based approach to counting the extra improvements. > > [... almost, but not quite identical results ..] > >> I guess I'll still have to work at getting it closer in code quality. Maybe I'll need to make all of the optimizations feed into a worklist, which could be tricky. > > I think an instruction-based work list should give you even better performance than anything basic on basic blocks. > > Whenever an instruction is sunk, add all its operands to the work list. You should probably use a SetVector for stable results. This doesn't catch all of the cases. In fact, nothing I try, either on a BB or Instruction level, seems to catch all of the cases with less compile time. I can't think of anything else to do, but maybe something will come to me. Cameron From sabre at nondot.org Thu Jan 6 01:41:22 2011 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Jan 2011 07:41:22 -0000 Subject: [llvm-commits] [llvm] r122954 - /llvm/trunk/lib/Target/README.txt Message-ID: <20110106074122.EBFE92A6C12C@llvm.org> Author: lattner Date: Thu Jan 6 01:41:22 2011 New Revision: 122954 URL: http://llvm.org/viewvc/llvm-project?rev=122954&view=rev Log: add a note about object size from drystone, add a poorly optimized loop from 179.art. 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=122954&r1=122953&r2=122954&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Thu Jan 6 01:41:22 2011 @@ -1075,6 +1075,77 @@ It would be better to do the mul once to reduce codesize above the if. This is GCC PR38204. + +//===---------------------------------------------------------------------===// +This simple function from 179.art: + +int winner, numf2s; +struct { double y; int reset; } *Y; + +void find_match() { + int i; + winner = 0; + for (i=0;i Y[winner].y) + winner =i; +} + +Compiles into (with clang TBAA): + +for.body: ; preds = %for.inc, %bb.nph + %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.inc ] + %i.01718 = phi i32 [ 0, %bb.nph ], [ %i.01719, %for.inc ] + %tmp4 = getelementptr inbounds %struct.anon* %tmp3, i64 %indvar, i32 0 + %tmp5 = load double* %tmp4, align 8, !tbaa !4 + %idxprom7 = sext i32 %i.01718 to i64 + %tmp10 = getelementptr inbounds %struct.anon* %tmp3, i64 %idxprom7, i32 0 + %tmp11 = load double* %tmp10, align 8, !tbaa !4 + %cmp12 = fcmp ogt double %tmp5, %tmp11 + br i1 %cmp12, label %if.then, label %for.inc + +if.then: ; preds = %for.body + %i.017 = trunc i64 %indvar to i32 + br label %for.inc + +for.inc: ; preds = %for.body, %if.then + %i.01719 = phi i32 [ %i.01718, %for.body ], [ %i.017, %if.then ] + %indvar.next = add i64 %indvar, 1 + %exitcond = icmp eq i64 %indvar.next, %tmp22 + br i1 %exitcond, label %for.cond.for.end_crit_edge, label %for.body + + +It is good that we hoisted the reloads of numf2's, and Y out of the loop and +sunk the store to winner out. + +However, this is awful on several levels: the conditional truncate in the loop +(-indvars at fault? why can't we completely promote the IV to i64?). + +Beyond that, we have a partially redundant load in the loop: if "winner" (aka +%i.01718) isn't updated, we reload Y[winner].y the next time through the loop. +Similarly, the addressing that feeds it (including the sext) is redundant. In +the end we get this generated assembly: + +LBB0_2: ## %for.body + ## =>This Inner Loop Header: Depth=1 + movsd (%rdi), %xmm0 + movslq %edx, %r8 + shlq $4, %r8 + ucomisd (%rcx,%r8), %xmm0 + jbe LBB0_4 + movl %esi, %edx +LBB0_4: ## %for.inc + addq $16, %rdi + incq %rsi + cmpq %rsi, %rax + jne LBB0_2 + +All things considered this isn't too bad, but we shouldn't need the movslq or +the shlq instruction, or the load folded into ucomisd every time through the +loop. + +On an x86-specific topic, if the loop can't be restructure, the movl should be a +cmov. + //===---------------------------------------------------------------------===// [STORE SINKING] @@ -1962,6 +2033,14 @@ This occurs several times in viterbi. +Stuff like this occurs in drystone: + + %call5 = call i8* @malloc(i32 48) optsize + %5 = getelementptr inbounds i8* %call5, i32 16 + %6 = call i32 @llvm.objectsize.i32(i8* %5, i1 false) + +We should be able to constant fold that. + //===---------------------------------------------------------------------===// This code (from Benchmarks/Dhrystone/dry.c): From evan.cheng at apple.com Thu Jan 6 01:58:36 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 06 Jan 2011 07:58:36 -0000 Subject: [llvm-commits] [llvm] r122955 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/2010-04-08-CoalescerBug.ll test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll test/CodeGen/X86/memcpy-2.ll test/CodeGen/X86/memcpy.ll test/CodeGen/X86/memset-2.ll test/CodeGen/X86/memset64-on-x86-32.ll test/CodeGen/X86/small-byval-memcpy.ll test/CodeGen/X86/tlv-1.ll test/CodeGen/X86/unaligned-load.ll Message-ID: <20110106075837.0AC762A6C12C@llvm.org> Author: evancheng Date: Thu Jan 6 01:58:36 2011 New Revision: 122955 URL: http://llvm.org/viewvc/llvm-project?rev=122955&view=rev Log: Use movups to lower memcpy and memset even if it's not fast (like corei7). The theory is it's still faster than a pair of movq / a quad of movl. This will probably hurt older chips like P4 but should run faster on current and future Intel processors. rdar://8817010 Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/test/CodeGen/X86/2010-04-08-CoalescerBug.ll llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll llvm/trunk/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll llvm/trunk/test/CodeGen/X86/memcpy-2.ll llvm/trunk/test/CodeGen/X86/memcpy.ll llvm/trunk/test/CodeGen/X86/memset-2.ll llvm/trunk/test/CodeGen/X86/memset64-on-x86-32.ll llvm/trunk/test/CodeGen/X86/small-byval-memcpy.ll llvm/trunk/test/CodeGen/X86/tlv-1.ll llvm/trunk/test/CodeGen/X86/unaligned-load.ll Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=122955&r1=122954&r2=122955&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Jan 6 01:58:36 2011 @@ -1063,12 +1063,8 @@ // linux. This is because the stack realignment code can't handle certain // cases like PR2962. This should be removed when PR2962 is fixed. const Function *F = MF.getFunction(); - if (NonScalarIntSafe && - !F->hasFnAttr(Attribute::NoImplicitFloat)) { + if (NonScalarIntSafe && !F->hasFnAttr(Attribute::NoImplicitFloat)) { if (Size >= 16 && - (Subtarget->isUnalignedMemAccessFast() || - ((DstAlign == 0 || DstAlign >= 16) && - (SrcAlign == 0 || SrcAlign >= 16))) && Subtarget->getStackAlignment() >= 16) { if (Subtarget->hasSSE2()) return MVT::v4i32; Modified: llvm/trunk/test/CodeGen/X86/2010-04-08-CoalescerBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-04-08-CoalescerBug.ll?rev=122955&r1=122954&r2=122955&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-04-08-CoalescerBug.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-04-08-CoalescerBug.ll Thu Jan 6 01:58:36 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s ; rdar://7842028 ; Do not delete partially dead copy instructions. @@ -9,7 +9,7 @@ %struct.F = type { %struct.FC*, i32, i32, i8, i32, i32, i32 } %struct.FC = type { [10 x i8], [32 x i32], %struct.FC*, i32 } -define void @t(%struct.F* %this) nounwind { +define void @t(%struct.F* %this) nounwind optsize { entry: ; CHECK: t: ; CHECK: addq $12, %rsi Modified: llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll?rev=122955&r1=122954&r2=122955&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll Thu Jan 6 01:58:36 2011 @@ -26,7 +26,7 @@ ; CHECK: rep;stosl %tmp5 = bitcast i32* %tmp4 to i8* - call void @llvm.memset.p0i8.i64(i8* %tmp5, i8 0, i64 84, i32 4, i1 false) + call void @llvm.memset.p0i8.i64(i8* %tmp5, i8 0, i64 124, i32 4, i1 false) %tmp6 = getelementptr inbounds %struct.type* %s, i32 0, i32 62 store i32* null, i32** %tmp6, align 8 br label %bb1 Modified: llvm/trunk/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll?rev=122955&r1=122954&r2=122955&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll Thu Jan 6 01:58:36 2011 @@ -19,8 +19,8 @@ } ; CHECK: movq ___stack_chk_guard at GOTPCREL(%rip), %rax -; CHECK: movb 30(%rsp), %dl -; CHECK: movb (%rsp), %sil -; CHECK: movb %sil, (%rsp) -; CHECK: movb %dl, 30(%rsp) +; CHECK: movb 30(%rsp), %cl +; CHECK: movb (%rsp), %dl +; CHECK: movb %dl, (%rsp) +; CHECK: movb %cl, 30(%rsp) ; CHECK: callq ___stack_chk_fail Modified: llvm/trunk/test/CodeGen/X86/memcpy-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memcpy-2.ll?rev=122955&r1=122954&r2=122955&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memcpy-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/memcpy-2.ll Thu Jan 6 01:58:36 2011 @@ -1,5 +1,4 @@ ; RUN: llc < %s -mattr=+sse2 -mtriple=i686-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=SSE2 -; RUN: llc < %s -mattr=+sse,-sse2 -mtriple=i686-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=SSE1 ; RUN: llc < %s -mattr=-sse -mtriple=i686-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=NOSSE ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=X86-64 @@ -15,13 +14,6 @@ ; SSE2: movl $0 ; SSE2: movl $0 -; SSE1: t1: -; SSE1: movaps _.str, %xmm0 -; SSE1: movaps %xmm0 -; SSE1: movb $0 -; SSE1: movl $0 -; SSE1: movl $0 - ; NOSSE: t1: ; NOSSE: movb $0 ; NOSSE: movl $0 @@ -51,10 +43,6 @@ ; SSE2: movaps (%eax), %xmm0 ; SSE2: movaps %xmm0, (%eax) -; SSE1: t2: -; SSE1: movaps (%eax), %xmm0 -; SSE1: movaps %xmm0, (%eax) - ; NOSSE: t2: ; NOSSE: movl ; NOSSE: movl @@ -79,22 +67,8 @@ define void @t3(%struct.s0* nocapture %a, %struct.s0* nocapture %b) nounwind ssp { entry: ; SSE2: t3: -; SSE2: movsd (%eax), %xmm0 -; SSE2: movsd 8(%eax), %xmm1 -; SSE2: movsd %xmm1, 8(%eax) -; SSE2: movsd %xmm0, (%eax) - -; SSE1: t3: -; SSE1: movl -; SSE1: movl -; SSE1: movl -; SSE1: movl -; SSE1: movl -; SSE1: movl -; SSE1: movl -; SSE1: movl -; SSE1: movl -; SSE1: movl +; SSE2: movups (%eax), %xmm0 +; SSE2: movups %xmm0, (%eax) ; NOSSE: t3: ; NOSSE: movl @@ -109,10 +83,8 @@ ; NOSSE: movl ; X86-64: t3: -; X86-64: movq (%rsi), %rax -; X86-64: movq 8(%rsi), %rcx -; X86-64: movq %rcx, 8(%rdi) -; X86-64: movq %rax, (%rdi) +; X86-64: movups (%rsi), %xmm0 +; X86-64: movups %xmm0, (%rdi) %tmp2 = bitcast %struct.s0* %a to i8* ; [#uses=1] %tmp3 = bitcast %struct.s0* %b to i8* ; [#uses=1] tail call void @llvm.memcpy.i32(i8* %tmp2, i8* %tmp3, i32 16, i32 8) @@ -122,24 +94,12 @@ define void @t4() nounwind { entry: ; SSE2: t4: -; SSE2: movw $120 -; SSE2: movl $2021161080 -; SSE2: movl $2021161080 -; SSE2: movl $2021161080 +; SSE2: movups _.str2, %xmm0 +; SSE2: movaps %xmm0, (%esp) +; SSE2: movw $120, 28(%esp) ; SSE2: movl $2021161080 ; SSE2: movl $2021161080 ; SSE2: movl $2021161080 -; SSE2: movl $2021161080 - -; SSE1: t4: -; SSE1: movw $120 -; SSE1: movl $2021161080 -; SSE1: movl $2021161080 -; SSE1: movl $2021161080 -; SSE1: movl $2021161080 -; SSE1: movl $2021161080 -; SSE1: movl $2021161080 -; SSE1: movl $2021161080 ; NOSSE: t4: ; NOSSE: movw $120 @@ -154,8 +114,8 @@ ; X86-64: t4: ; X86-64: movabsq $8680820740569200760, %rax ; X86-64: movq %rax -; X86-64: movq %rax -; X86-64: movq %rax +; X86-64: movups _.str2(%rip), %xmm0 +; X86-64: movaps %xmm0, -40(%rsp) ; X86-64: movw $120 ; X86-64: movl $2021161080 %tmp1 = alloca [30 x i8] Modified: llvm/trunk/test/CodeGen/X86/memcpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memcpy.ll?rev=122955&r1=122954&r2=122955&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memcpy.ll (original) +++ llvm/trunk/test/CodeGen/X86/memcpy.ll Thu Jan 6 01:58:36 2011 @@ -37,26 +37,34 @@ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i32 1, i1 false) ret void ; LINUX: test3: -; LINUX: memcpy +; LINUX-NOT: memcpy +; LINUX: movups +; LINUX: movups +; LINUX: movups +; LINUX: movups +; LINUX: movups +; LINUX: movups +; LINUX: movups +; LINUX: movups ; DARWIN: test3: ; DARWIN-NOT: memcpy -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq -; DARWIN: movq +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups +; DARWIN: movups } ; Large constant memcpy's should be inlined when not optimizing for size. Modified: llvm/trunk/test/CodeGen/X86/memset-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memset-2.ll?rev=122955&r1=122954&r2=122955&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memset-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/memset-2.ll Thu Jan 6 01:58:36 2011 @@ -5,7 +5,21 @@ define fastcc void @t1() nounwind { entry: ; CHECK: t1: -; CHECK: calll _memset +; CHECK: pxor %xmm0, %xmm0 +; CHECK: movups %xmm0, 160 +; CHECK: movups %xmm0, 144 +; CHECK: movups %xmm0, 128 +; CHECK: movups %xmm0, 112 +; CHECK: movups %xmm0, 96 +; CHECK: movups %xmm0, 80 +; CHECK: movups %xmm0, 64 +; CHECK: movups %xmm0, 48 +; CHECK: movups %xmm0, 32 +; CHECK: movups %xmm0, 16 +; CHECK: movups %xmm0, 0 +; CHECK: movl $0, 184 +; CHECK: movl $0, 180 +; CHECK: movl $0, 176 call void @llvm.memset.i32( i8* null, i8 0, i32 188, i32 1 ) nounwind unreachable } Modified: llvm/trunk/test/CodeGen/X86/memset64-on-x86-32.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memset64-on-x86-32.ll?rev=122955&r1=122954&r2=122955&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memset64-on-x86-32.ll (original) +++ llvm/trunk/test/CodeGen/X86/memset64-on-x86-32.ll Thu Jan 6 01:58:36 2011 @@ -1,6 +1,5 @@ ; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=nehalem | grep movups | count 5 -; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=core2 | grep movl | count 20 -; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core2 | grep movq | count 10 +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core2 | grep movups | count 5 define void @bork() nounwind { entry: Modified: llvm/trunk/test/CodeGen/X86/small-byval-memcpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/small-byval-memcpy.ll?rev=122955&r1=122954&r2=122955&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/small-byval-memcpy.ll (original) +++ llvm/trunk/test/CodeGen/X86/small-byval-memcpy.ll Thu Jan 6 01:58:36 2011 @@ -1,8 +1,12 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=core2 | grep movsd | count 8 -; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=nehalem | grep movups | count 2 +; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=nehalem | FileCheck %s define void @ccosl({ x86_fp80, x86_fp80 }* noalias sret %agg.result, { x86_fp80, x86_fp80 }* byval align 4 %z) nounwind { entry: +; CHECK: ccosl: +; CHECK: movaps +; CHECK: movaps +; CHECK: movups +; CHECK: movups %iz = alloca { x86_fp80, x86_fp80 } ; <{ x86_fp80, x86_fp80 }*> [#uses=3] %tmp1 = getelementptr { x86_fp80, x86_fp80 }* %z, i32 0, i32 1 ; [#uses=1] %tmp2 = load x86_fp80* %tmp1, align 16 ; [#uses=1] Modified: llvm/trunk/test/CodeGen/X86/tlv-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tlv-1.ll?rev=122955&r1=122954&r2=122955&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tlv-1.ll (original) +++ llvm/trunk/test/CodeGen/X86/tlv-1.ll Thu Jan 6 01:58:36 2011 @@ -10,8 +10,12 @@ unreachable ; CHECK: movq _c at TLVP(%rip), %rdi ; CHECK-NEXT: callq *(%rdi) - ; CHECK-NEXT: movl $0, 56(%rax) - ; CHECK-NEXT: movq $0, 48(%rax) + ; CHECK-NEXT: pxor %xmm0, %xmm0 + ; CHECK-NEXT: movups %xmm0, 32(%rax) + ; CHECK-NEXT: movups %xmm0, 16(%rax) + ; CHECK-NEXT: movups %xmm0, (%rax) + ; CHECK-NEXT: movl $0, 56(%rax) + ; CHECK-NEXT: movq $0, 48(%rax) } declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind Modified: llvm/trunk/test/CodeGen/X86/unaligned-load.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/unaligned-load.ll?rev=122955&r1=122954&r2=122955&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/unaligned-load.ll (original) +++ llvm/trunk/test/CodeGen/X86/unaligned-load.ll Thu Jan 6 01:58:36 2011 @@ -1,6 +1,4 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin10.0 -mcpu=core2 -relocation-model=dynamic-no-pic --asm-verbose=0 | FileCheck -check-prefix=I386 %s -; RUN: llc < %s -mtriple=x86_64-apple-darwin10.0 -mcpu=core2 -relocation-model=dynamic-no-pic --asm-verbose=0 | FileCheck -check-prefix=CORE2 %s -; RUN: llc < %s -mtriple=x86_64-apple-darwin10.0 -mcpu=corei7 -relocation-model=dynamic-no-pic --asm-verbose=0 | FileCheck -check-prefix=COREI7 %s +; RUN: llc < %s -mtriple=x86_64-apple-darwin10.0 -mcpu=core2 -relocation-model=dynamic-no-pic --asm-verbose=0 | FileCheck %s @.str1 = internal constant [31 x i8] c"DHRYSTONE PROGRAM, SOME STRING\00", align 8 @.str3 = internal constant [31 x i8] c"DHRYSTONE PROGRAM, 2'ND STRING\00", align 8 @@ -13,13 +11,8 @@ bb: %String2Loc9 = getelementptr inbounds [31 x i8]* %String2Loc, i64 0, i64 0 call void @llvm.memcpy.i64(i8* %String2Loc9, i8* getelementptr inbounds ([31 x i8]* @.str3, i64 0, i64 0), i64 31, i32 1) -; I386: calll {{_?}}memcpy - -; CORE2: movabsq -; CORE2: movabsq -; CORE2: movabsq - -; COREI7: movups _.str3 +; CHECK: movabsq $2325069237881678925, %rax +; CHECK: movups _.str3(%rip), %xmm0 br label %bb return: @@ -28,9 +21,9 @@ declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind -; CORE2: .section -; CORE2: .align 4 -; CORE2-NEXT: _.str1: -; CORE2-NEXT: .asciz "DHRYSTONE PROGRAM, SOME STRING" -; CORE2: .align 4 -; CORE2-NEXT: _.str3: +; CHECK: .section +; CHECK: .align 4 +; CHECK-NEXT: _.str1: +; CHECK-NEXT: .asciz "DHRYSTONE PROGRAM, SOME STRING" +; CHECK: .align 4 +; CHECK-NEXT: _.str3: From geek4civic at gmail.com Thu Jan 6 02:16:44 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Thu, 6 Jan 2011 17:16:44 +0900 Subject: [llvm-commits] [llvm] r122934 - /llvm/trunk/lib/Target/X86/X86FrameInfo.cpp In-Reply-To: <20110106005034.DE5522A6C12C@llvm.org> References: <20110106005034.DE5522A6C12C@llvm.org> Message-ID: Hello Sreeram, > PR8919 - LLVM incorrectly generates "_alloca" as the stack probing call. That > works only on MinGW32. On 64-bit, the function to call is "__chkstk". > Patch by KS Sreeram! I am using libraries in mingw-w64-1.0-bin_i686-mingw_20101129.zip. It has not __chkstk but ___chkstk. It seems ToT gcc provides ___chkstk. Seek gcc/config/i386/cygwin.asm on gcc.gnu.org. What are you using? Or what would I miss? Please let me know, thank you. ...Takumi From geek4civic at gmail.com Thu Jan 6 03:24:48 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Thu, 6 Jan 2011 18:24:48 +0900 Subject: [llvm-commits] [llvm] r122934 - /llvm/trunk/lib/Target/X86/X86FrameInfo.cpp In-Reply-To: References: <20110106005034.DE5522A6C12C@llvm.org> Message-ID: Hello Sreeram, 2011/1/6 KS Sreeram : > I'm using MinGW GCC 4.5.1 from this distro:?http://tdm-gcc.tdragon.net/. > Any ideas on how to handle the differences between 4.5.1 and ToT? I have to look into TDM, thank you! If mingw and tdm were diverged, we might consider individual triplets; eg. x86_64-{mingw|tdm} :p ...Takumi From geek4civic at gmail.com Thu Jan 6 03:37:25 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Thu, 6 Jan 2011 18:37:25 +0900 Subject: [llvm-commits] [llvm] r122934 - /llvm/trunk/lib/Target/X86/X86FrameInfo.cpp In-Reply-To: References: <20110106005034.DE5522A6C12C@llvm.org> Message-ID: I found in; http://tdm-gcc.tdragon.net/development > TDM64 edition only: Includes a patch to remove a leading underscore from the 64-bit cygwin.asm symbols "__chkstk" and "_alloca", allowing them to be exported with the same rule as the 32-bit versions after underscoring rules are applied. divergence...Takumi From pichet2000 at gmail.com Thu Jan 6 03:57:14 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Thu, 6 Jan 2011 04:57:14 -0500 Subject: [llvm-commits] Fwd: [llvm] r122808 - /llvm/trunk/utils/lit/lit/TestRunner.py In-Reply-To: References: <20110104102342.95C5F2A6C12C@llvm.org> Message-ID: forgot to cc the list ---------- Forwarded message ---------- From: Francois Pichet Date: Thu, Jan 6, 2011 at 4:13 AM Subject: Re: [llvm-commits] [llvm] r122808 - /llvm/trunk/utils/lit/lit/TestRunner.py To: "David A. Greene" On Tue, Jan 4, 2011 at 10:20 AM, David A. Greene wrote: > Francois Pichet writes: > > > Author: fpichet > > Date: Tue Jan 4 04:23:42 2011 > > New Revision: 122808 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=122808&view=rev > > Log: > > Disable r122754 on Windows: was causing all lit tests to fail. > > > > Modified: > > llvm/trunk/utils/lit/lit/TestRunner.py > > > > Modified: llvm/trunk/utils/lit/lit/TestRunner.py > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/TestRunner.py?rev=122808&r1=122807&r2=122808&view=diff > > > ============================================================================== > > --- llvm/trunk/utils/lit/lit/TestRunner.py (original) > > +++ llvm/trunk/utils/lit/lit/TestRunner.py Tue Jan 4 04:23:42 2011 > > @@ -451,8 +451,12 @@ > > # expression pattern a with substitution b in line ln. > > def processLine(ln): > > # Apply substitutions > > + # FIXME: Investigate why re.sub doesn't work on Windows > > for a,b in substitutions: > > - ln = re.sub(a, b, ln) > > + if kIsWindows: > > + ln = ln.replace(a,b) > > + else: > > + ln = re.sub(a, b, ln) > > > > # Strip the trailing newline and any extra whitespace. > > return ln.strip() > > This can't possibly work. "a" is a regular expression. A replace isn't > going to match it. > > The problem on Windows is that re.sub will replace \t with a tab character. I still don't understand why you need to do a re.sub here instead of a replace. Doing a replace work for me. Give me an example of "a" as a regular expression? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110106/858a7a36/attachment.html From anton at korobeynikov.info Thu Jan 6 04:16:20 2011 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Thu, 6 Jan 2011 13:16:20 +0300 Subject: [llvm-commits] [llvm] r122934 - /llvm/trunk/lib/Target/X86/X86FrameInfo.cpp In-Reply-To: References: <20110106005034.DE5522A6C12C@llvm.org> Message-ID: >> TDM64 edition only: Includes a patch to remove a leading underscore from the 64-bit cygwin.asm symbols "__chkstk" and "_alloca", allowing them to be exported with the same rule as the 32-bit versions after underscoring rules are applied. Please check the comments I left in PR, we need to be extremely careful here, since there is a huge mess wrt __chkstk / __alloca in win64 world. Bill, next time please don't apply such patches blindly, thanks! -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From fvbommel at gmail.com Thu Jan 6 04:49:59 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Thu, 6 Jan 2011 11:49:59 +0100 Subject: [llvm-commits] [PATCH] Fix: instcombine does not get max if hidden by sext In-Reply-To: <48360275-C1A1-4AB1-A1A2-F5609C52094B@apple.com> References: <4D22A780.6060209@fim.uni-passau.de> <48360275-C1A1-4AB1-A1A2-F5609C52094B@apple.com> Message-ID: On Thu, Jan 6, 2011 at 7:49 AM, Chris Lattner wrote: > On Jan 3, 2011, at 8:52 PM, Tobias Grosser wrote: >> I fixed a recent bug report, that blocked me on a large FORTRAN test case: >> >> ? ?InstCombine: >> ? ?X = sext x ; x < c ? X : C-1 >> ? ?--> >> ? ?X = sext x; X > C-1 ? C-1 : X >> >> ? ?Instead of calculating this with mixed types promote all to the >> ? ?larger type. This enables scalar evolution to analyze this >> ? ?expression. PR8866 Why only for sext and not zext? Does scalar evolution understand those well enough that it's not needed there or was it just not useful for your particular test case? Or maybe the zext case is too different from the sext case to add easily? > Generally, the logic involved is complex enough that it is probably best to pull it out into a static helper function. ?This should make it easier to read. And since the "less than" and "greater than" cases seem to be quite similar, you could try to use a single helper function for both. Is the fallthrough at the end of the "less than" case intentional? If so, a big '// FALLTHROUGH' would probably be helpful. If not, add a 'break', obviously. Either way, adding one at the end of the "greater than" case would future-proof it in case anyone adds extra cases. > It's probably also good to get Frits to review this, he has a keen eye :) Thanks :). From benny.kra at googlemail.com Thu Jan 6 07:01:03 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 06 Jan 2011 13:01:03 -0000 Subject: [llvm-commits] [llvm] r122957 - in /llvm/trunk/lib/Target: MBlaze/MBlazeRegisterInfo.cpp X86/X86FastISel.cpp Message-ID: <20110106130103.233CF2A6C12C@llvm.org> Author: d0k Date: Thu Jan 6 07:01:02 2011 New Revision: 122957 URL: http://llvm.org/viewvc/llvm-project?rev=122957&view=rev Log: Remove dead code and silence warnings. Modified: llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp llvm/trunk/lib/Target/X86/X86FastISel.cpp Modified: llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp?rev=122957&r1=122956&r2=122957&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp Thu Jan 6 07:01:02 2011 @@ -266,7 +266,6 @@ MachineInstr &MI = *II; MachineFunction &MF = *MI.getParent()->getParent(); MachineFrameInfo *MFI = MF.getFrameInfo(); - MBlazeFunctionInfo *MBlazeFI = MF.getInfo(); unsigned i = 0; while (!MI.getOperand(i).isFI()) { @@ -281,10 +280,11 @@ dbgs() << "<--------->\n" << MI); int FrameIndex = MI.getOperand(i).getIndex(); - int stackSize = MF.getFrameInfo()->getStackSize(); - int spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex); + int stackSize = MFI->getStackSize(); + int spOffset = MFI->getObjectOffset(FrameIndex); - DEBUG(dbgs() << "FrameIndex : " << FrameIndex << "\n" + DEBUG(MBlazeFunctionInfo *MBlazeFI = MF.getInfo(); + dbgs() << "FrameIndex : " << FrameIndex << "\n" << "spOffset : " << spOffset << "\n" << "stackSize : " << stackSize << "\n" << "isFixed : " << MFI->isFixedObjectIndex(FrameIndex) << "\n" Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=122957&r1=122956&r2=122957&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Thu Jan 6 07:01:02 2011 @@ -1548,7 +1548,6 @@ bool Emitted = X86FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(), Arg, ArgVT, Arg); assert(Emitted && "Failed to emit a sext!"); (void)Emitted; - Emitted = true; ArgVT = VA.getLocVT(); break; } @@ -1556,7 +1555,6 @@ bool Emitted = X86FastEmitExtend(ISD::ZERO_EXTEND, VA.getLocVT(), Arg, ArgVT, Arg); assert(Emitted && "Failed to emit a zext!"); (void)Emitted; - Emitted = true; ArgVT = VA.getLocVT(); break; } From benny.kra at googlemail.com Thu Jan 6 07:07:49 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 06 Jan 2011 13:07:49 -0000 Subject: [llvm-commits] [llvm] r122958 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/objsize.ll Message-ID: <20110106130750.061212A6C12C@llvm.org> Author: d0k Date: Thu Jan 6 07:07:49 2011 New Revision: 122958 URL: http://llvm.org/viewvc/llvm-project?rev=122958&view=rev Log: InstCombine: Teach llvm.objectsize folding to look through GEPs. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/trunk/test/Transforms/InstCombine/objsize.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=122958&r1=122957&r2=122958&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Thu Jan 6 07:07:49 2011 @@ -250,82 +250,73 @@ if (!TD) break; const Type *ReturnTy = CI.getType(); - bool Min = (cast(II->getArgOperand(1))->getZExtValue() == 1); + uint64_t DontKnow = II->getArgOperand(1) == Builder->getTrue() ? 0 : -1ULL; // Get to the real allocated thing and offset as fast as possible. Value *Op1 = II->getArgOperand(0)->stripPointerCasts(); - + + uint64_t Offset = 0; + uint64_t Size = -1ULL; + + // Try to look through constant GEPs. + if (GEPOperator *GEP = dyn_cast(Op1)) { + if (!GEP->hasAllConstantIndices()) break; + + // Get the current byte offset into the thing. Use the original + // operand in case we're looking through a bitcast. + SmallVector Ops(GEP->idx_begin(), GEP->idx_end()); + Offset = TD->getIndexedOffset(GEP->getPointerOperandType(), + Ops.data(), Ops.size()); + + Op1 = GEP->getPointerOperand()->stripPointerCasts(); + + // Make sure we're not a constant offset from an external + // global. + if (GlobalVariable *GV = dyn_cast(Op1)) + if (!GV->hasDefinitiveInitializer()) break; + } + // If we've stripped down to a single global variable that we // can know the size of then just return that. if (GlobalVariable *GV = dyn_cast(Op1)) { if (GV->hasDefinitiveInitializer()) { Constant *C = GV->getInitializer(); - uint64_t GlobalSize = TD->getTypeAllocSize(C->getType()); - return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, GlobalSize)); + Size = TD->getTypeAllocSize(C->getType()); } else { // Can't determine size of the GV. - Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL); + Constant *RetVal = ConstantInt::get(ReturnTy, DontKnow); return ReplaceInstUsesWith(CI, RetVal); } } else if (AllocaInst *AI = dyn_cast(Op1)) { // Get alloca size. if (AI->getAllocatedType()->isSized()) { - uint64_t AllocaSize = TD->getTypeAllocSize(AI->getAllocatedType()); + Size = TD->getTypeAllocSize(AI->getAllocatedType()); if (AI->isArrayAllocation()) { const ConstantInt *C = dyn_cast(AI->getArraySize()); if (!C) break; - AllocaSize *= C->getZExtValue(); + Size *= C->getZExtValue(); } - return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, AllocaSize)); } } else if (CallInst *MI = extractMallocCall(Op1)) { - const Type* MallocType = getMallocAllocatedType(MI); // Get alloca size. - if (MallocType && MallocType->isSized()) { - if (Value *NElems = getMallocArraySize(MI, TD, true)) { + const Type* MallocType = getMallocAllocatedType(MI); + if (MallocType && MallocType->isSized()) + if (Value *NElems = getMallocArraySize(MI, TD, true)) if (ConstantInt *NElements = dyn_cast(NElems)) - return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, - (NElements->getZExtValue() * TD->getTypeAllocSize(MallocType)))); - } - } - } else if (ConstantExpr *CE = dyn_cast(Op1)) { - // Only handle constant GEPs here. - if (CE->getOpcode() != Instruction::GetElementPtr) break; - GEPOperator *GEP = cast(CE); - - // Make sure we're not a constant offset from an external - // global. - Value *Operand = GEP->getPointerOperand(); - Operand = Operand->stripPointerCasts(); - if (GlobalVariable *GV = dyn_cast(Operand)) - if (!GV->hasDefinitiveInitializer()) break; - - // Get what we're pointing to and its size. - const PointerType *BaseType = - cast(Operand->getType()); - uint64_t Size = TD->getTypeAllocSize(BaseType->getElementType()); - - // Get the current byte offset into the thing. Use the original - // operand in case we're looking through a bitcast. - SmallVector Ops(CE->op_begin()+1, CE->op_end()); - const PointerType *OffsetType = - cast(GEP->getPointerOperand()->getType()); - uint64_t Offset = TD->getIndexedOffset(OffsetType, &Ops[0], Ops.size()); - - if (Size < Offset) { - // Out of bound reference? Negative index normalized to large - // index? Just return "I don't know". - Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL); - return ReplaceInstUsesWith(CI, RetVal); - } - - Constant *RetVal = ConstantInt::get(ReturnTy, Size-Offset); - return ReplaceInstUsesWith(CI, RetVal); - } + Size = NElements->getZExtValue() * TD->getTypeAllocSize(MallocType); + } // Do not return "I don't know" here. Later optimization passes could // make it possible to evaluate objectsize to a constant. - break; + if (Size == -1ULL) + break; + + if (Size < Offset) { + // Out of bound reference? Negative index normalized to large + // index? Just return "I don't know". + return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, DontKnow)); + } + return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, Size-Offset)); } case Intrinsic::bswap: // bswap(bswap(x)) -> x Modified: llvm/trunk/test/Transforms/InstCombine/objsize.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/objsize.ll?rev=122958&r1=122957&r2=122958&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/objsize.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/objsize.ll Thu Jan 6 07:07:49 2011 @@ -150,3 +150,13 @@ declare noalias i8* @malloc(i32) nounwind declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly + +define i32 @test7() { +; CHECK: @test7 + %alloc = call noalias i8* @malloc(i32 48) nounwind + %gep = getelementptr inbounds i8* %alloc, i32 16 + %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false) nounwind readonly +; CHECK-NEXT: ret i32 32 + ret i32 %objsize +} + From benny.kra at googlemail.com Thu Jan 6 07:11:05 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 06 Jan 2011 13:11:05 -0000 Subject: [llvm-commits] [llvm] r122959 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/objsize.ll Message-ID: <20110106131105.59E222A6C12C@llvm.org> Author: d0k Date: Thu Jan 6 07:11:05 2011 New Revision: 122959 URL: http://llvm.org/viewvc/llvm-project?rev=122959&view=rev Log: InstCombine: If we call llvm.objectsize on a malloc call we can replace it with the size passed to malloc. Modified: llvm/trunk/lib/Target/README.txt llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/trunk/test/Transforms/InstCombine/objsize.ll Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=122959&r1=122958&r2=122959&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Thu Jan 6 07:11:05 2011 @@ -2020,29 +2020,6 @@ //===---------------------------------------------------------------------===// -This code can be seen in viterbi: - - %64 = call noalias i8* @malloc(i64 %62) nounwind -... - %67 = call i64 @llvm.objectsize.i64(i8* %64, i1 false) nounwind - %68 = call i8* @__memset_chk(i8* %64, i32 0, i64 %62, i64 %67) nounwind - -llvm.objectsize.i64 should be taught about malloc/calloc, allowing it to -fold to %62. This is a security win (overflows of malloc will get caught) -and also a performance win by exposing more memsets to the optimizer. - -This occurs several times in viterbi. - -Stuff like this occurs in drystone: - - %call5 = call i8* @malloc(i32 48) optsize - %5 = getelementptr inbounds i8* %call5, i32 16 - %6 = call i32 @llvm.objectsize.i32(i8* %5, i1 false) - -We should be able to constant fold that. - -//===---------------------------------------------------------------------===// - This code (from Benchmarks/Dhrystone/dry.c): define i32 @Func1(i32, i32) nounwind readnone optsize ssp { Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=122959&r1=122958&r2=122959&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Thu Jan 6 07:11:05 2011 @@ -298,12 +298,16 @@ } } } else if (CallInst *MI = extractMallocCall(Op1)) { - // Get alloca size. + // Get allocation size. const Type* MallocType = getMallocAllocatedType(MI); if (MallocType && MallocType->isSized()) if (Value *NElems = getMallocArraySize(MI, TD, true)) if (ConstantInt *NElements = dyn_cast(NElems)) Size = NElements->getZExtValue() * TD->getTypeAllocSize(MallocType); + + // If there is no offset we can just return the size passed to malloc. + if (Offset == 0) + return ReplaceInstUsesWith(CI, MI->getArgOperand(0)); } // Do not return "I don't know" here. Later optimization passes could Modified: llvm/trunk/test/Transforms/InstCombine/objsize.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/objsize.ll?rev=122959&r1=122958&r2=122959&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/objsize.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/objsize.ll Thu Jan 6 07:11:05 2011 @@ -160,3 +160,19 @@ ret i32 %objsize } +define i32 @test8(i32 %x) { +; CHECK: @test8 + %alloc = call noalias i8* @malloc(i32 %x) nounwind + %objsize = call i32 @llvm.objectsize.i32(i8* %alloc, i1 false) nounwind readonly +; CHECK-NEXT: ret i32 %x + ret i32 %objsize +} + +define i32 @test9(i32 %x) { +; CHECK: @test9 + %alloc = call noalias i8* @malloc(i32 %x) nounwind + %gep = getelementptr inbounds i8* %alloc, i32 16 + %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false) nounwind readonly +; CHECK-NOT: ret i32 %x + ret i32 %objsize +} From benny.kra at googlemail.com Thu Jan 6 07:19:46 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 06 Jan 2011 13:19:46 -0000 Subject: [llvm-commits] [llvm] r122960 - /llvm/trunk/lib/Target/README.txt Message-ID: <20110106131946.30E5A2A6C12C@llvm.org> Author: d0k Date: Thu Jan 6 07:19:46 2011 New Revision: 122960 URL: http://llvm.org/viewvc/llvm-project?rev=122960&view=rev Log: EarlyCSE does this now (and GVN always did it). 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=122960&r1=122959&r2=122960&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Thu Jan 6 07:19:46 2011 @@ -2009,17 +2009,6 @@ //===---------------------------------------------------------------------===// -This compare could fold to false: - -define i1 @g(i32 a) nounwind readnone { - %add = shl i32 %a, 1 - %mul = shl i32 %a, 1 - %cmp = icmp ugt i32 %add, %mul - ret i1 %cmp -} - -//===---------------------------------------------------------------------===// - This code (from Benchmarks/Dhrystone/dry.c): define i32 @Func1(i32, i32) nounwind readnone optsize ssp { From isanbard at gmail.com Thu Jan 6 07:26:20 2011 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 6 Jan 2011 05:26:20 -0800 Subject: [llvm-commits] [llvm] r122934 - /llvm/trunk/lib/Target/X86/X86FrameInfo.cpp In-Reply-To: References: <20110106005034.DE5522A6C12C@llvm.org> Message-ID: <4D9C7E8D-93C4-49DB-A8CF-55A31F271477@gmail.com> On Jan 6, 2011, at 2:16 AM, Anton Korobeynikov wrote: >>> TDM64 edition only: Includes a patch to remove a leading underscore from the 64-bit cygwin.asm symbols "__chkstk" and "_alloca", allowing them to be exported with the same rule as the 32-bit versions after underscoring rules are applied. > Please check the comments I left in PR, we need to be extremely > careful here, since there is a huge mess wrt __chkstk / __alloca in > win64 world. > > Bill, next time please don't apply such patches blindly, thanks! > Please revert the patches. -bw From benny.kra at googlemail.com Thu Jan 6 08:22:52 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 06 Jan 2011 14:22:52 -0000 Subject: [llvm-commits] [llvm] r122961 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/objsize.ll Message-ID: <20110106142252.621E22A6C12C@llvm.org> Author: d0k Date: Thu Jan 6 08:22:52 2011 New Revision: 122961 URL: http://llvm.org/viewvc/llvm-project?rev=122961&view=rev Log: InstCombine: Turn _chk functions into the "unsafe" variant if length and max langth are equal. This happens when we take the (non-constant) length from a malloc. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/trunk/test/Transforms/InstCombine/objsize.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=122961&r1=122960&r2=122961&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Thu Jan 6 08:22:52 2011 @@ -722,6 +722,8 @@ NewInstruction = IC->ReplaceInstUsesWith(*CI, With); } bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, bool isString) const { + if (CI->getArgOperand(SizeCIOp) == CI->getArgOperand(SizeArgOp)) + return true; if (ConstantInt *SizeCI = dyn_cast(CI->getArgOperand(SizeCIOp))) { if (SizeCI->isAllOnesValue()) Modified: llvm/trunk/test/Transforms/InstCombine/objsize.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/objsize.ll?rev=122961&r1=122960&r2=122961&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/objsize.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/objsize.ll Thu Jan 6 08:22:52 2011 @@ -176,3 +176,14 @@ ; CHECK-NOT: ret i32 %x ret i32 %objsize } + +define i8* @test10(i32 %x) { +; CHECK: @test10 + %alloc = call noalias i8* @malloc(i32 %x) nounwind + %objsize = call i32 @llvm.objectsize.i32(i8* %alloc, i1 false) nounwind readonly + tail call i8* @__memset_chk(i8* %alloc, i32 0, i32 %x, i32 %objsize) nounwind +; CHECK-NOT: @llvm.objectsize +; CHECK: @llvm.memset + ret i8* %alloc +; CHECK: ret i8* +} From rafael.espindola at gmail.com Thu Jan 6 10:48:42 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Thu, 06 Jan 2011 16:48:42 -0000 Subject: [llvm-commits] [llvm] r122962 - in /llvm/trunk: lib/Target/X86/Disassembler/X86DisassemblerDecoder.c test/MC/Disassembler/X86/truncated-input.txt tools/llvm-mc/Disassembler.cpp Message-ID: <20110106164842.4CF4C2A6C12C@llvm.org> Author: rafael Date: Thu Jan 6 10:48:42 2011 New Revision: 122962 URL: http://llvm.org/viewvc/llvm-project?rev=122962&view=rev Log: Correctly disassemble truncated asm. Patch by Richard Simth. Added: llvm/trunk/test/MC/Disassembler/X86/truncated-input.txt Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c llvm/trunk/tools/llvm-mc/Disassembler.cpp Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c?rev=122962&r1=122961&r2=122962&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c (original) +++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c Thu Jan 6 10:48:42 2011 @@ -511,7 +511,8 @@ insn->opcode); if (hasModRMExtension) { - readModRM(insn); + if (readModRM(insn)) + return -1; *instructionID = decode(insn->opcodeType, instructionClass, @@ -860,7 +861,8 @@ if (insn->consumedModRM) return 0; - consumeByte(insn, &insn->modRM); + if (consumeByte(insn, &insn->modRM)) + return -1; insn->consumedModRM = TRUE; mod = modFromModRM(insn->modRM); Added: llvm/trunk/test/MC/Disassembler/X86/truncated-input.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/X86/truncated-input.txt?rev=122962&view=auto ============================================================================== --- llvm/trunk/test/MC/Disassembler/X86/truncated-input.txt (added) +++ llvm/trunk/test/MC/Disassembler/X86/truncated-input.txt Thu Jan 6 10:48:42 2011 @@ -0,0 +1,4 @@ +# RUN: llvm-mc --disassemble %s -triple=x86_64-apple-darwin9 |& FileCheck %s + +# CHECK: warning +0x00 Modified: llvm/trunk/tools/llvm-mc/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/Disassembler.cpp?rev=122962&r1=122961&r2=122962&view=diff ============================================================================== --- llvm/trunk/tools/llvm-mc/Disassembler.cpp (original) +++ llvm/trunk/tools/llvm-mc/Disassembler.cpp Thu Jan 6 10:48:42 2011 @@ -44,7 +44,7 @@ uint64_t getExtent() const { return Bytes.size(); } int readByte(uint64_t Addr, uint8_t *Byte) const { - if (Addr > getExtent()) + if (Addr >= getExtent()) return -1; *Byte = Bytes[Addr].first; return 0; From rafael.espindola at gmail.com Thu Jan 6 10:53:44 2011 From: rafael.espindola at gmail.com (=?ISO-8859-1?Q?Rafael_=C1vila_de_Esp=EDndola?=) Date: Thu, 06 Jan 2011 11:53:44 -0500 Subject: [llvm-commits] [PATCH] [MC] Reading off end of buffer when disassembling truncated x86 asm (PR7710) In-Reply-To: <45726.10.0.16.53.1294173022.squirrel@webmail.cantab.net> References: <57603.10.0.16.53.1294058683.squirrel@webmail.cantab.net> <45726.10.0.16.53.1294173022.squirrel@webmail.cantab.net> Message-ID: <4D25F398.9000309@gmail.com> > The updated, attached patch also contains a test for these issues. Committed. Thanks! > Thanks, > Richard Cheers, Rafael From baldrick at free.fr Thu Jan 6 10:58:05 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 06 Jan 2011 17:58:05 +0100 Subject: [llvm-commits] [llvm] r122960 - /llvm/trunk/lib/Target/README.txt In-Reply-To: <20110106131946.30E5A2A6C12C@llvm.org> References: <20110106131946.30E5A2A6C12C@llvm.org> Message-ID: <4D25F49D.1070906@free.fr> Hi Benjamin, > EarlyCSE does this now (and GVN always did it). yes, but the issue with the original example (posted on the mailing list) was that this CSE opportunity was created by an optimization pass that ran *after* GVN, so wasn't caught by GVN. Since EarlyCSE runs before GVN, it won't catch it either. Unfortunately the README item didn't note this or the original C code, and I don't seem to have kept a copy of the original email - maybe someone else did. Ciao, Duncan. > > 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=122960&r1=122959&r2=122960&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/README.txt (original) > +++ llvm/trunk/lib/Target/README.txt Thu Jan 6 07:19:46 2011 > @@ -2009,17 +2009,6 @@ > > //===---------------------------------------------------------------------===// > > -This compare could fold to false: > - > -define i1 @g(i32 a) nounwind readnone { > - %add = shl i32 %a, 1 > - %mul = shl i32 %a, 1 > - %cmp = icmp ugt i32 %add, %mul > - ret i1 %cmp > -} > - > -//===---------------------------------------------------------------------===// > - > This code (from Benchmarks/Dhrystone/dry.c): > > define i32 @Func1(i32, i32) nounwind readnone optsize ssp { > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Thu Jan 6 11:16:31 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 06 Jan 2011 18:16:31 +0100 Subject: [llvm-commits] [llvm] r122950 - in /llvm/trunk: lib/Analysis/ConstantFolding.cpp test/Transforms/InstCombine/constant-fold-gep.ll In-Reply-To: <20110106061946.A48182A6C12C@llvm.org> References: <20110106061946.A48182A6C12C@llvm.org> Message-ID: <4D25F8EF.1030400@free.fr> Hi Chris, > ============================================================================== > --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) > +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Thu Jan 6 00:19:46 2011 > @@ -575,8 +575,26 @@ > // If this is a constant expr gep that is effectively computing an > // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12' > for (unsigned i = 1; i != NumOps; ++i) > - if (!isa(Ops[i])) > + if (!isa(Ops[i])) { > + > + // If this is "gep i8* Ptr, (sub 0, V)", fold this as: > + // "inttoptr (sub (ptrtoint Ptr), V)" > + if (NumOps == 2&& > + cast(ResultTy)->getElementType()->isIntegerTy(8)) { you could do this for other pointer types by introducing a multiplication. But perhaps it isn't interesting? > + ConstantExpr *CE = dyn_cast(Ops[1]); > + if (CE&& CE->getOpcode() == Instruction::Sub&& > + isa(CE->getOperand(0))&& > + cast(CE->getOperand(0))->isZero()) { The above two lines could be turned into: CE->getOperand(0)->isNullValue() > + Constant *Res = ConstantExpr::getPtrToInt(Ptr, CE->getType()); Here you convert the pointer to an integer of the type of the sub. I don't think that makes sense, since can't the GEP index have any type? For example, suppose the type of the sub was i8, then here you convert the pointer to an i8 which is wrong. > + Res = ConstantExpr::getSub(Res, CE->getOperand(1)); > + Res = ConstantExpr::getIntToPtr(Res, ResultTy); > + if (ConstantExpr *ResCE = dyn_cast(Res)) > + Res = ConstantFoldConstantExpression(ResCE, TD); > + return Res; > + } > + } Ciao, Duncan. From echristo at apple.com Thu Jan 6 11:17:24 2011 From: echristo at apple.com (Eric Christopher) Date: Thu, 6 Jan 2011 09:17:24 -0800 Subject: [llvm-commits] [llvm] r122958 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/objsize.ll In-Reply-To: <20110106130750.061212A6C12C@llvm.org> References: <20110106130750.061212A6C12C@llvm.org> Message-ID: On Jan 6, 2011, at 5:07 AM, Benjamin Kramer wrote: > InstCombine: Teach llvm.objectsize folding to look through GEPs. Looks good, thanks! -eric From sreeram at tachyontech.net Thu Jan 6 02:29:55 2011 From: sreeram at tachyontech.net (KS Sreeram) Date: Thu, 6 Jan 2011 13:59:55 +0530 Subject: [llvm-commits] [llvm] r122934 - /llvm/trunk/lib/Target/X86/X86FrameInfo.cpp In-Reply-To: References: <20110106005034.DE5522A6C12C@llvm.org> Message-ID: Hi On Thu, Jan 6, 2011 at 1:46 PM, NAKAMURA Takumi wrote: > > PR8919 - LLVM incorrectly generates "_alloca" as the stack probing call. > That > > works only on MinGW32. On 64-bit, the function to call is "__chkstk". > > Patch by KS Sreeram! > > I am using libraries in mingw-w64-1.0-bin_i686-mingw_20101129.zip. > It has not __chkstk but ___chkstk. > > It seems ToT gcc provides ___chkstk. Seek gcc/config/i386/cygwin.asm > on gcc.gnu.org. > > What are you using? Or what would I miss? Please let me know, thank you. > I'm using MinGW GCC 4.5.1 from this distro: http://tdm-gcc.tdragon.net/. Any ideas on how to handle the differences between 4.5.1 and ToT? - KS Sreeram > > ...Takumi > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110106/8243614f/attachment.html From tim.northover at arm.com Thu Jan 6 08:52:34 2011 From: tim.northover at arm.com (Tim Northover) Date: Thu, 6 Jan 2011 14:52:34 +0000 Subject: [llvm-commits] shufflevector on ARM (clumsy x-post from llvmdev) Message-ID: Hi, I've been taking a look at http://llvm.org/bugs/show_bug.cgi?id=8411, which is essentially improving how shufflevector instructions are handled for ARM. It looks like the main complexity comes from the fact that the DAG which emerges from SelectionDAGBuilder::visitShuffleVector is often rather low-level. A case could probably be made for keeping more information around in the DAG, but that would require cooperation among all the backends. For now, both EXTRACT_SUBVECTORs and BUILD_VECTORs seem to be handled on ARM mainly by resorting to the stack, which often leads to rather bad code. EXTRACT_SUBVECTOR in particular should just involve ignoring one of the registers. I've put together a couple of patches to improve matters: http://www.maths.ed.ac.uk/~s0677366/build_vector.patch http://www.maths.ed.ac.uk/~s0677366/extract_subvector.patch (both were originally created a couple of weeks ago so the offsets have changed slightly, they're still valid on today's trunk). extract_subvector.patch adds "Pat"s to the relevant .td file so that EXTRACT_SUBVECTOR works naturally. This changed the code generated in a couple of tests and exposed slight bug in visitShuffleVector itself, so they needed modifying. build_vector.patch is a more complex C++ modification, which attempts to reconstruct shuffles from the BUILD_VECTOR nodes where possible. Its primary effect is on <8 x *> -> <4 x *> shuffles, where on average it saves 4.6 instructions, with a degradation (of 1 instruction) in only 5/83827 shuffles. Runtime benchmarks were more difficult, however a random sample suggests it improves about 75% of shuffles. I suspect "natural" shuffles will fare better. On <16 x *> -> <8 x *> shuffles, it rarely performs any optimization. Probably only 0.03 instructions shorter on average. The problem is that not many random shuffles actually have known good encodings, so the existing SHUFFLE_VECTOR handling refuses to deal with them usually. Again I'd expect natural shuffles to do better. The code is disabled on shorter vectors because my tests suggested the transformations weren't improving matters. (The extract_subvector code still applies -- it will always be better). I would welcome any comments or suggestions. Tim From abramo.bagnara at gmail.com Thu Jan 6 10:55:14 2011 From: abramo.bagnara at gmail.com (Abramo Bagnara) Date: Thu, 06 Jan 2011 16:55:14 -0000 Subject: [llvm-commits] [llvm] r122963 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <20110106165514.E1AF52A6C12C@llvm.org> Author: abramo Date: Thu Jan 6 10:55:14 2011 New Revision: 122963 URL: http://llvm.org/viewvc/llvm-project?rev=122963&view=rev Log: Fixed parsing of hex floats. Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=122963&r1=122962&r2=122963&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Thu Jan 6 10:55:14 2011 @@ -194,11 +194,11 @@ assert(value < 10U && "Invalid character in exponent"); unsignedExponent = unsignedExponent * 10 + value; - if (unsignedExponent > 65535) + if (unsignedExponent > 32767) overflow = true; } - if (exponentAdjustment > 65535 || exponentAdjustment < -65536) + if (exponentAdjustment > 32767 || exponentAdjustment < -32768) overflow = true; if (!overflow) { @@ -206,12 +206,12 @@ if (negative) exponent = -exponent; exponent += exponentAdjustment; - if (exponent > 65535 || exponent < -65536) + if (exponent > 32767 || exponent < -32768) overflow = true; } if (overflow) - exponent = negative ? -65536: 65535; + exponent = negative ? -32768: 32767; return exponent; } From 6yearold at gmail.com Thu Jan 6 11:00:23 2011 From: 6yearold at gmail.com (arrowdodger) Date: Thu, 6 Jan 2011 20:00:23 +0300 Subject: [llvm-commits] [PATCH][CMake] include/Config/config.h fixes. Message-ID: Posting first patch here as ?scar suggested in this thread http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-January/037209.html I've decided to start with simple stuff. Short summary: - Add ENABLE_CBE_PRINTF_A. - Fix ENABLE_PIC. The problem was that ENABLE_PIC was set to 1 *after* generating config.h. I've moved if(ENABLE_PIC) from CMakeLists.txt into cmake/config-ix.cmake. - Add check. - Add fmodf() call check. This call located in math.h on Linux, FreeBSD, MacOS and Windows, so i decided, that it's safe to check it using just check_symbol_exists() command. - Add HAVE_INT64_T. - Fix HAVE_INT64_T, HAVE_UINT64_T and HAVE_U_INT64_T defines in config.h.cmake. - Remove CAN_DLOPEN_SELF. This was only in config.h.cmake and not in config.h.in. Additionaly, there was none check for it. I want to mention, that all CMake code is slightly messed up: declarations are messed with logic, there is no convention on naming variables (LLVM_ENABLE_<> and simply ENABLE_<>) and other things. What do you think about cleaning this up? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110106/e96f2e4f/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: cmake.patch Type: text/x-patch Size: 5536 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110106/e96f2e4f/attachment.bin From benny.kra at googlemail.com Thu Jan 6 11:35:50 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 06 Jan 2011 17:35:50 -0000 Subject: [llvm-commits] [llvm] r122966 - /llvm/trunk/lib/Target/README.txt Message-ID: <20110106173550.C70DC2A6C12C@llvm.org> Author: d0k Date: Thu Jan 6 11:35:50 2011 New Revision: 122966 URL: http://llvm.org/viewvc/llvm-project?rev=122966&view=rev Log: Add a note from llvmdev, this time with more info. 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=122966&r1=122965&r2=122966&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Thu Jan 6 11:35:50 2011 @@ -2047,3 +2047,29 @@ } //===---------------------------------------------------------------------===// +clang -O3 currently compiles this code + +int g(unsigned int a) { + unsigned int c[100]; + c[10] = a; + c[11] = a; + unsigned int b = c[10] + c[11]; + if(b > a*2) a = 4; + else a = 8; + return a + 7; +} + +into + +define i32 @g(i32 a) nounwind readnone { + %add = shl i32 %a, 1 + %mul = shl i32 %a, 1 + %cmp = icmp ugt i32 %add, %mul + %a.addr.0 = select i1 %cmp, i32 11, i32 15 + ret i32 %a.addr.0 +} + +The icmp should fold to false. This CSE opportunity is only available +after GVN and InstCombine have run. + +//===---------------------------------------------------------------------===// From benny.kra at googlemail.com Thu Jan 6 11:39:28 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 6 Jan 2011 18:39:28 +0100 Subject: [llvm-commits] [llvm] r122960 - /llvm/trunk/lib/Target/README.txt In-Reply-To: <4D25F49D.1070906@free.fr> References: <20110106131946.30E5A2A6C12C@llvm.org> <4D25F49D.1070906@free.fr> Message-ID: On 06.01.2011, at 17:58, Duncan Sands wrote: > Hi Benjamin, > >> EarlyCSE does this now (and GVN always did it). > > yes, but the issue with the original example (posted on the mailing list) was > that this CSE opportunity was created by an optimization pass that ran *after* > GVN, so wasn't caught by GVN. Since EarlyCSE runs before GVN, it won't catch > it either. Unfortunately the README item didn't note this or the original C > code, and I don't seem to have kept a copy of the original email - maybe someone > else did. It's still in the ml archive: http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-December/037135.html I've added a new note with the original C code. From clattner at apple.com Thu Jan 6 12:34:06 2011 From: clattner at apple.com (Chris Lattner) Date: Thu, 6 Jan 2011 10:34:06 -0800 Subject: [llvm-commits] [llvm] r122950 - in /llvm/trunk: lib/Analysis/ConstantFolding.cpp test/Transforms/InstCombine/constant-fold-gep.ll In-Reply-To: <4D25F8EF.1030400@free.fr> References: <20110106061946.A48182A6C12C@llvm.org> <4D25F8EF.1030400@free.fr> Message-ID: <78355351-BB50-4FA6-87F1-A1C85E1ED8B7@apple.com> On Jan 6, 2011, at 9:16 AM, Duncan Sands wrote: > Hi Chris, > >> ============================================================================== >> --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) >> +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Thu Jan 6 00:19:46 2011 >> @@ -575,8 +575,26 @@ >> // If this is a constant expr gep that is effectively computing an >> // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12' >> for (unsigned i = 1; i != NumOps; ++i) >> - if (!isa(Ops[i])) >> + if (!isa(Ops[i])) { >> + >> + // If this is "gep i8* Ptr, (sub 0, V)", fold this as: >> + // "inttoptr (sub (ptrtoint Ptr), V)" >> + if (NumOps == 2&& >> + cast(ResultTy)->getElementType()->isIntegerTy(8)) { > > you could do this for other pointer types by introducing a multiplication. > But perhaps it isn't interesting? The idiom I was looking at (std::fill on arrays) was able to compute a trip count for all cases other than when the array was of bytes... so I assume that there is another canonicalization kicking in. > >> + ConstantExpr *CE = dyn_cast(Ops[1]); >> + if (CE&& CE->getOpcode() == Instruction::Sub&& >> + isa(CE->getOperand(0))&& >> + cast(CE->getOperand(0))->isZero()) { > > The above two lines could be turned into: CE->getOperand(0)->isNullValue() Nice cleanup, done. >> + Constant *Res = ConstantExpr::getPtrToInt(Ptr, CE->getType()); > > Here you convert the pointer to an integer of the type of the sub. I don't > think that makes sense, since can't the GEP index have any type? For example, > suppose the type of the sub was i8, then here you convert the pointer to an i8 > which is wrong. This code is in SymbolicallyEvaluateGEP, which only is run if TD is available. SymbolicallyEvaluateGEP is run only after CastGEPIndices, which canonicalizes the indexes to intptr_t. I agree that this is subtle so I added an assert to make it clear. Thanks for the review! llvm.org seems to be missing, but i'll commit the patch when it's back. -Chris From anton at korobeynikov.info Thu Jan 6 12:36:59 2011 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Thu, 6 Jan 2011 21:36:59 +0300 Subject: [llvm-commits] [llvm] r122934 - /llvm/trunk/lib/Target/X86/X86FrameInfo.cpp In-Reply-To: References: <20110106005034.DE5522A6C12C@llvm.org> Message-ID: > I'm using MinGW GCC 4.5.1 from this distro:?http://tdm-gcc.tdragon.net/. > Any ideas on how to handle the differences between 4.5.1 and ToT? The main question is the semantics of the function. Do you know what precisely does the function in TDM? -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From bob.wilson at apple.com Thu Jan 6 13:24:32 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 06 Jan 2011 19:24:32 -0000 Subject: [llvm-commits] [llvm] r122968 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <20110106192432.47BA72A6C12C@llvm.org> Author: bwilson Date: Thu Jan 6 13:24:32 2011 New Revision: 122968 URL: http://llvm.org/viewvc/llvm-project?rev=122968&view=rev Log: Fix comment typo. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=122968&r1=122967&r2=122968&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Jan 6 13:24:32 2011 @@ -1836,7 +1836,7 @@ } // neverHasSideEffects -// Load / Store Multiple Mnemnoic Aliases +// Load / Store Multiple Mnemonic Aliases def : MnemonicAlias<"ldm", "ldmia">; def : MnemonicAlias<"stm", "stmia">; From bob.wilson at apple.com Thu Jan 6 13:24:36 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 06 Jan 2011 19:24:36 -0000 Subject: [llvm-commits] [llvm] r122969 - /llvm/trunk/lib/Target/ARM/ARMFrameInfo.cpp Message-ID: <20110106192436.A11522A6C12D@llvm.org> Author: bwilson Date: Thu Jan 6 13:24:36 2011 New Revision: 122969 URL: http://llvm.org/viewvc/llvm-project?rev=122969&view=rev Log: Remove extra whitespace. Modified: llvm/trunk/lib/Target/ARM/ARMFrameInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMFrameInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFrameInfo.cpp?rev=122969&r1=122968&r2=122969&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFrameInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMFrameInfo.cpp Thu Jan 6 13:24:36 2011 @@ -658,7 +658,7 @@ unsigned FltOpc = ARM::VSTMDDB_UPD; emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea1Register); emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea2Register); - emitPushInst(MBB, MI, CSI, FltOpc, 0, true, &isARMArea3Register); + emitPushInst(MBB, MI, CSI, FltOpc, 0, true, &isARMArea3Register); return true; } @@ -678,7 +678,7 @@ unsigned PopOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD; unsigned LdrOpc = AFI->isThumbFunction() ? ARM::t2LDR_POST : ARM::LDR_POST; unsigned FltOpc = ARM::VLDMDIA_UPD; - emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, &isARMArea3Register); + emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, &isARMArea3Register); emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, &isARMArea2Register); emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, From bob.wilson at apple.com Thu Jan 6 13:24:41 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 06 Jan 2011 19:24:41 -0000 Subject: [llvm-commits] [llvm] r122970 - in /llvm/trunk: lib/Target/ARM/ARMFrameInfo.cpp lib/Target/ARM/ARMLoadStoreOptimizer.cpp test/CodeGen/ARM/2010-03-18-ldm-rtrn.ll test/CodeGen/ARM/bx_fold.ll test/CodeGen/ARM/ifcvt6.ll test/CodeGen/ARM/ifcvt7.ll test/CodeGen/ARM/ifcvt8.ll test/CodeGen/ARM/ldm.ll test/CodeGen/ARM/lsr-code-insertion.ll Message-ID: <20110106192441.5339D2A6C12C@llvm.org> Author: bwilson Date: Thu Jan 6 13:24:41 2011 New Revision: 122970 URL: http://llvm.org/viewvc/llvm-project?rev=122970&view=rev Log: PR8921: LDM/POP do not support interworking prior to v5t. Modified: llvm/trunk/lib/Target/ARM/ARMFrameInfo.cpp llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp llvm/trunk/test/CodeGen/ARM/2010-03-18-ldm-rtrn.ll llvm/trunk/test/CodeGen/ARM/bx_fold.ll llvm/trunk/test/CodeGen/ARM/ifcvt6.ll llvm/trunk/test/CodeGen/ARM/ifcvt7.ll llvm/trunk/test/CodeGen/ARM/ifcvt8.ll llvm/trunk/test/CodeGen/ARM/ldm.ll llvm/trunk/test/CodeGen/ARM/lsr-code-insertion.ll Modified: llvm/trunk/lib/Target/ARM/ARMFrameInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFrameInfo.cpp?rev=122970&r1=122969&r2=122970&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFrameInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMFrameInfo.cpp Thu Jan 6 13:24:41 2011 @@ -592,7 +592,7 @@ unsigned Reg = CSI[i-1].getReg(); if (!(Func)(Reg, STI.isTargetDarwin())) continue; - if (Reg == ARM::LR && !isVarArg) { + if (Reg == ARM::LR && !isVarArg && STI.hasV5TOps()) { Reg = ARM::PC; LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET; // Fold the return instruction into the LDM. Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=122970&r1=122969&r2=122970&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Thu Jan 6 13:24:41 2011 @@ -1390,7 +1390,8 @@ ++MFI) { MachineBasicBlock &MBB = *MFI; Modified |= LoadStoreMultipleOpti(MBB); - Modified |= MergeReturnIntoLDM(MBB); + if (TM.getSubtarget().hasV5TOps()) + Modified |= MergeReturnIntoLDM(MBB); } delete RS; Modified: llvm/trunk/test/CodeGen/ARM/2010-03-18-ldm-rtrn.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2010-03-18-ldm-rtrn.ll?rev=122970&r1=122969&r2=122970&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2010-03-18-ldm-rtrn.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2010-03-18-ldm-rtrn.ll Thu Jan 6 13:24:41 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=armv4-unknown-eabi | FileCheck %s +; RUN: llc < %s -mtriple=armv4-unknown-eabi | FileCheck %s -check-prefix=V4 ; RUN: llc < %s -mtriple=armv5-unknown-eabi | FileCheck %s ; RUN: llc < %s -mtriple=armv6-unknown-eabi | FileCheck %s @@ -7,6 +7,8 @@ %0 = tail call i32 @foo(i32 %a) nounwind ; [#uses=1] %1 = add nsw i32 %0, 3 ; [#uses=1] ; CHECK: ldmia sp!, {r11, pc} +; V4: pop +; V4-NEXT: mov pc, lr ret i32 %1 } Modified: llvm/trunk/test/CodeGen/ARM/bx_fold.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/bx_fold.ll?rev=122970&r1=122969&r2=122970&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/bx_fold.ll (original) +++ llvm/trunk/test/CodeGen/ARM/bx_fold.ll Thu Jan 6 13:24:41 2011 @@ -1,5 +1,4 @@ -; RUN: llc < %s -march=arm -; RUN: llc < %s -march=arm | not grep bx +; RUN: llc < %s -mtriple=armv5t-apple-darwin | FileCheck %s define void @test(i32 %Ptr, i8* %L) { entry: @@ -24,6 +23,8 @@ br i1 %bothcond, label %bb, label %bb18 bb18: ; preds = %bb1 +; CHECK-NOT: bx +; CHECK: ldmia sp! ret void } Modified: llvm/trunk/test/CodeGen/ARM/ifcvt6.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ifcvt6.ll?rev=122970&r1=122969&r2=122970&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/ifcvt6.ll (original) +++ llvm/trunk/test/CodeGen/ARM/ifcvt6.ll Thu Jan 6 13:24:41 2011 @@ -1,10 +1,9 @@ -; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \ -; RUN: grep cmpne | count 1 -; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \ -; RUN: grep ldmiahi | count 1 +; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s define void @foo(i32 %X, i32 %Y) { entry: +; CHECK: cmpne +; CHECK: ldmiahi sp! %tmp1 = icmp ult i32 %X, 4 ; [#uses=1] %tmp4 = icmp eq i32 %Y, 0 ; [#uses=1] %tmp7 = or i1 %tmp4, %tmp1 ; [#uses=1] Modified: llvm/trunk/test/CodeGen/ARM/ifcvt7.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ifcvt7.ll?rev=122970&r1=122969&r2=122970&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/ifcvt7.ll (original) +++ llvm/trunk/test/CodeGen/ARM/ifcvt7.ll Thu Jan 6 13:24:41 2011 @@ -1,14 +1,12 @@ -; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \ -; RUN: grep cmpeq | count 1 -; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \ -; RUN: grep moveq | count 1 -; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \ -; RUN: grep ldmiaeq | count 1 +; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s ; FIXME: Need post-ifcvt branch folding to get rid of the extra br at end of BB1. %struct.quad_struct = type { i32, i32, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct* } define fastcc i32 @CountTree(%struct.quad_struct* %tree) { +; CHECK: cmpeq +; CHECK: moveq +; CHECK: ldmiaeq sp! entry: br label %tailrecurse Modified: llvm/trunk/test/CodeGen/ARM/ifcvt8.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ifcvt8.ll?rev=122970&r1=122969&r2=122970&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/ifcvt8.ll (original) +++ llvm/trunk/test/CodeGen/ARM/ifcvt8.ll Thu Jan 6 13:24:41 2011 @@ -1,11 +1,11 @@ -; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \ -; RUN: grep ldmiane | count 1 +; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s %struct.SString = type { i8*, i32, i32 } declare void @abort() define fastcc void @t(%struct.SString* %word, i8 signext %c) { +; CHECK: ldmiane sp! entry: %tmp1 = icmp eq %struct.SString* %word, null ; [#uses=1] br i1 %tmp1, label %cond_true, label %cond_false Modified: llvm/trunk/test/CodeGen/ARM/ldm.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ldm.ll?rev=122970&r1=122969&r2=122970&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/ldm.ll (original) +++ llvm/trunk/test/CodeGen/ARM/ldm.ll Thu Jan 6 13:24:41 2011 @@ -1,10 +1,13 @@ -; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s +; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s +; RUN: llc < %s -mtriple=armv4t-apple-darwin | FileCheck %s -check-prefix=V4T @X = external global [0 x i32] ; <[0 x i32]*> [#uses=5] define i32 @t1() { ; CHECK: t1: ; CHECK: ldmia +; V4T: t1: +; V4T: ldmia %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 0) ; [#uses=1] %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 1) ; [#uses=1] %tmp4 = tail call i32 @f1( i32 %tmp, i32 %tmp3 ) ; [#uses=1] @@ -14,6 +17,8 @@ define i32 @t2() { ; CHECK: t2: ; CHECK: ldmia +; V4T: t2: +; V4T: ldmia %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 2) ; [#uses=1] %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 3) ; [#uses=1] %tmp5 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 4) ; [#uses=1] @@ -25,6 +30,10 @@ ; CHECK: t3: ; CHECK: ldmib ; CHECK: ldmia sp! +; V4T: t3: +; V4T: ldmib +; V4T: pop +; V4T-NEXT: bx lr %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 1) ; [#uses=1] %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 2) ; [#uses=1] %tmp5 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 3) ; [#uses=1] Modified: llvm/trunk/test/CodeGen/ARM/lsr-code-insertion.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/lsr-code-insertion.ll?rev=122970&r1=122969&r2=122970&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/lsr-code-insertion.ll (original) +++ llvm/trunk/test/CodeGen/ARM/lsr-code-insertion.ll Thu Jan 6 13:24:41 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -stats |& grep {38.*Number of machine instrs printed} +; RUN: llc < %s -stats |& grep {39.*Number of machine instrs printed} ; RUN: llc < %s -stats |& not grep {.*Number of re-materialization} ; This test really wants to check that the resultant "cond_true" block only ; has a single store in it, and that cond_true55 only has code to materialize From sreeram at tachyontech.net Thu Jan 6 15:11:06 2011 From: sreeram at tachyontech.net (KS Sreeram) Date: Fri, 7 Jan 2011 02:41:06 +0530 Subject: [llvm-commits] [llvm] r122934 - /llvm/trunk/lib/Target/X86/X86FrameInfo.cpp In-Reply-To: References: <20110106005034.DE5522A6C12C@llvm.org> Message-ID: Hi Anton On Fri, Jan 7, 2011 at 12:06 AM, Anton Korobeynikov wrote: > > I'm using MinGW GCC 4.5.1 from this distro: http://tdm-gcc.tdragon.net/. > > Any ideas on how to handle the differences between 4.5.1 and ToT? > The main question is the semantics of the function. Do you know what > precisely does the function in TDM? > I've added some information in a comment: http://llvm.org/bugs/show_bug.cgi?id=8919#c8 Regards KS Sreeram -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110107/a822b0b7/attachment.html From dpatel at apple.com Thu Jan 6 15:39:25 2011 From: dpatel at apple.com (Devang Patel) Date: Thu, 06 Jan 2011 21:39:25 -0000 Subject: [llvm-commits] [llvm] r122971 - in /llvm/trunk/lib/CodeGen/AsmPrinter: DwarfDebug.cpp DwarfDebug.h Message-ID: <20110106213925.5B2F52A6C12C@llvm.org> Author: dpatel Date: Thu Jan 6 15:39:25 2011 New Revision: 122971 URL: http://llvm.org/viewvc/llvm-project?rev=122971&view=rev Log: Emit 128 bit constant. This fixes PR 8913 crash. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=122971&r1=122970&r2=122971&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu Jan 6 15:39:25 2011 @@ -894,6 +894,39 @@ return true; } +/// addConstantValue - Add constant value entry in variable DIE. +bool DwarfDebug::addConstantValue(DIE *Die, ConstantInt *CI, + bool Unsigned) { + if (CI->getBitWidth() <= 64) { + if (Unsigned) + addUInt(Die, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata, + CI->getZExtValue()); + else + addSInt(Die, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, + CI->getSExtValue()); + return true; + } + + DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); + + // Get the raw data form of the large APInt. + const APInt Val = CI->getValue(); + const char *Ptr = (const char*)Val.getRawData(); + + int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte. + bool LittleEndian = Asm->getTargetData().isLittleEndian(); + int Incr = (LittleEndian ? 1 : -1); + int Start = (LittleEndian ? 0 : NumBytes - 1); + int Stop = (LittleEndian ? NumBytes : -1); + + // Output the constant to DWARF one byte at a time. + for (; Start != Stop; Start += Incr) + addUInt(Block, 0, dwarf::DW_FORM_data1, + (unsigned char)0xFF & Ptr[Start]); + + addBlock(Die, dwarf::DW_AT_const_value, 0, Block); + return true; +} /// addToContextOwner - Add Die into the list of its context owner's children. void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) { @@ -1957,16 +1990,10 @@ } else { addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block); } - } else if (Constant *C = GV.getConstant()) { - if (ConstantInt *CI = dyn_cast(C)) { - if (isUnsignedDIType(GTy)) - addUInt(VariableDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata, - CI->getZExtValue()); - else - addSInt(VariableDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, - CI->getSExtValue()); - } - } + } else if (ConstantInt *CI = + dyn_cast_or_null(GV.getConstant())) + addConstantValue(VariableDIE, CI, isUnsignedDIType(GTy)); + return; } Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=122971&r1=122970&r2=122971&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Thu Jan 6 15:39:25 2011 @@ -301,6 +301,7 @@ /// addConstantValue - Add constant value entry in variable DIE. bool addConstantValue(DIE *Die, const MachineOperand &MO); + bool addConstantValue(DIE *Die, ConstantInt *CI, bool Unsigned); /// addConstantFPValue - Add constant value entry in variable DIE. bool addConstantFPValue(DIE *Die, const MachineOperand &MO); From sabre at nondot.org Thu Jan 6 16:24:29 2011 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Jan 2011 22:24:29 -0000 Subject: [llvm-commits] [llvm] r122977 - /llvm/trunk/lib/Analysis/ConstantFolding.cpp Message-ID: <20110106222429.6C1352A6C12C@llvm.org> Author: lattner Date: Thu Jan 6 16:24:29 2011 New Revision: 122977 URL: http://llvm.org/viewvc/llvm-project?rev=122977&view=rev Log: use isNullValue() to simplify code, add an assert. 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=122977&r1=122976&r2=122977&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Thu Jan 6 16:24:29 2011 @@ -568,9 +568,8 @@ Constant *Ptr = Ops[0]; if (!TD || !cast(Ptr->getType())->getElementType()->isSized()) return 0; - - unsigned BitWidth = - TD->getTypeSizeInBits(TD->getIntPtrType(Ptr->getContext())); + + const Type *IntPtrTy = TD->getIntPtrType(Ptr->getContext()); // If this is a constant expr gep that is effectively computing an // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12' @@ -582,9 +581,10 @@ if (NumOps == 2 && cast(ResultTy)->getElementType()->isIntegerTy(8)) { ConstantExpr *CE = dyn_cast(Ops[1]); + assert(CE->getType() == IntPtrTy && + "CastGEPIndices didn't canonicalize index types!"); if (CE && CE->getOpcode() == Instruction::Sub && - isa(CE->getOperand(0)) && - cast(CE->getOperand(0))->isZero()) { + CE->getOperand(0)->isNullValue()) { Constant *Res = ConstantExpr::getPtrToInt(Ptr, CE->getType()); Res = ConstantExpr::getSub(Res, CE->getOperand(1)); Res = ConstantExpr::getIntToPtr(Res, ResultTy); @@ -596,6 +596,7 @@ return 0; } + unsigned BitWidth = TD->getTypeSizeInBits(IntPtrTy); APInt Offset = APInt(BitWidth, TD->getIndexedOffset(Ptr->getType(), (Value**)Ops+1, NumOps-1)); From sabre at nondot.org Thu Jan 6 16:25:00 2011 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Jan 2011 22:25:00 -0000 Subject: [llvm-commits] [llvm] r122978 - /llvm/trunk/lib/Target/README.txt Message-ID: <20110106222500.7A3D02A6C12C@llvm.org> Author: lattner Date: Thu Jan 6 16:25:00 2011 New Revision: 122978 URL: http://llvm.org/viewvc/llvm-project?rev=122978&view=rev Log: With Benjamin's recent amazing patches, we should be able to do even better things :) 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=122978&r1=122977&r2=122978&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Thu Jan 6 16:25:00 2011 @@ -2073,3 +2073,16 @@ after GVN and InstCombine have run. //===---------------------------------------------------------------------===// + +memcpyopt should turn this: + +define i8* @test10(i32 %x) { + %alloc = call noalias i8* @malloc(i32 %x) nounwind + call void @llvm.memset.p0i8.i32(i8* %alloc, i8 0, i32 %x, i32 1, i1 false) + ret i8* %alloc +} + +into a call to calloc. We should make sure that we analyze calloc as +aggressively as malloc though. + +//===---------------------------------------------------------------------===// From echristo at apple.com Thu Jan 6 16:28:56 2011 From: echristo at apple.com (Eric Christopher) Date: Thu, 06 Jan 2011 22:28:56 -0000 Subject: [llvm-commits] [llvm] r122979 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeIntegerTypes.cpp LegalizeTypes.cpp LegalizeTypes.h Message-ID: <20110106222856.3C5A92A6C12C@llvm.org> Author: echristo Date: Thu Jan 6 16:28:56 2011 New Revision: 122979 URL: http://llvm.org/viewvc/llvm-project?rev=122979&view=rev Log: Add some fairly duplicated code to let type legalization split illegal typed atomics. This will lower exclusively to libcalls at the moment. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=122979&r1=122978&r2=122979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Thu Jan 6 16:28:56 2011 @@ -1019,6 +1019,24 @@ case ISD::UREM: ExpandIntRes_UREM(N, Lo, Hi); break; case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break; + case ISD::ATOMIC_LOAD_ADD: + case ISD::ATOMIC_LOAD_SUB: + case ISD::ATOMIC_LOAD_AND: + case ISD::ATOMIC_LOAD_OR: + case ISD::ATOMIC_LOAD_XOR: + case ISD::ATOMIC_LOAD_NAND: + case ISD::ATOMIC_LOAD_MIN: + case ISD::ATOMIC_LOAD_MAX: + case ISD::ATOMIC_LOAD_UMIN: + case ISD::ATOMIC_LOAD_UMAX: + case ISD::ATOMIC_SWAP: { + SDValue Ch = N->getOperand(0); + std::pair Tmp = ExpandAtomic(N); + SplitInteger(Tmp.first, Lo, Hi); + ReplaceValueWith(SDValue(N, 1), Tmp.second); + break; + } + case ISD::AND: case ISD::OR: case ISD::XOR: ExpandIntRes_Logical(N, Lo, Hi); break; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=122979&r1=122978&r2=122979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Thu Jan 6 16:28:56 2011 @@ -1050,6 +1050,125 @@ return CallInfo.first; } +// ExpandChainLibCall - Expand a node into a call to a libcall. Similar to +// ExpandLibCall except that the first operand is the in-chain. +std::pair +DAGTypeLegalizer::ExpandChainLibCall(RTLIB::Libcall LC, + SDNode *Node, + bool isSigned) { + SDValue InChain = Node->getOperand(0); + + TargetLowering::ArgListTy Args; + TargetLowering::ArgListEntry Entry; + for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) { + EVT ArgVT = Node->getOperand(i).getValueType(); + const Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); + Entry.Node = Node->getOperand(i); + Entry.Ty = ArgTy; + Entry.isSExt = isSigned; + Entry.isZExt = !isSigned; + Args.push_back(Entry); + } + SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), + TLI.getPointerTy()); + + // Splice the libcall in wherever FindInputOutputChains tells us to. + const Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); + std::pair CallInfo = + TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, + 0, TLI.getLibcallCallingConv(LC), /*isTailCall=*/false, + /*isReturnValueUsed=*/true, + Callee, Args, DAG, Node->getDebugLoc()); + + return CallInfo; +} + +std::pair DAGTypeLegalizer::ExpandAtomic(SDNode *Node) { + unsigned Opc = Node->getOpcode(); + MVT VT = cast(Node)->getMemoryVT().getSimpleVT(); + RTLIB::Libcall LC; + + switch (Opc) { + default: + llvm_unreachable("Unhandled atomic intrinsic Expand!"); + break; + case ISD::ATOMIC_SWAP: + switch (VT.SimpleTy) { + default: llvm_unreachable("Unexpected value type for atomic!"); + case MVT::i8: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_1; break; + case MVT::i16: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_2; break; + case MVT::i32: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_4; break; + case MVT::i64: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_8; break; + } + break; + case ISD::ATOMIC_CMP_SWAP: + switch (VT.SimpleTy) { + default: llvm_unreachable("Unexpected value type for atomic!"); + case MVT::i8: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_1; break; + case MVT::i16: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_2; break; + case MVT::i32: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_4; break; + case MVT::i64: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_8; break; + } + break; + case ISD::ATOMIC_LOAD_ADD: + switch (VT.SimpleTy) { + default: llvm_unreachable("Unexpected value type for atomic!"); + case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_ADD_1; break; + case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_ADD_2; break; + case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_ADD_4; break; + case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_ADD_8; break; + } + break; + case ISD::ATOMIC_LOAD_SUB: + switch (VT.SimpleTy) { + default: llvm_unreachable("Unexpected value type for atomic!"); + case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_SUB_1; break; + case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_SUB_2; break; + case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_SUB_4; break; + case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_SUB_8; break; + } + break; + case ISD::ATOMIC_LOAD_AND: + switch (VT.SimpleTy) { + default: llvm_unreachable("Unexpected value type for atomic!"); + case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_AND_1; break; + case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_AND_2; break; + case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_AND_4; break; + case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_AND_8; break; + } + break; + case ISD::ATOMIC_LOAD_OR: + switch (VT.SimpleTy) { + default: llvm_unreachable("Unexpected value type for atomic!"); + case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_OR_1; break; + case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_OR_2; break; + case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_OR_4; break; + case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_OR_8; break; + } + break; + case ISD::ATOMIC_LOAD_XOR: + switch (VT.SimpleTy) { + default: llvm_unreachable("Unexpected value type for atomic!"); + case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_XOR_1; break; + case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_XOR_2; break; + case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_XOR_4; break; + case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_XOR_8; break; + } + break; + case ISD::ATOMIC_LOAD_NAND: + switch (VT.SimpleTy) { + default: llvm_unreachable("Unexpected value type for atomic!"); + case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_NAND_1; break; + case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_NAND_2; break; + case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_NAND_4; break; + case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_NAND_8; break; + } + break; + } + + return ExpandChainLibCall(LC, Node, false); +} + /// PromoteTargetBoolean - Promote the given target boolean to a target boolean /// of the given type. A target boolean is an integer value, not necessarily of /// type i1, the bits of which conform to getBooleanContents. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=122979&r1=122978&r2=122979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Thu Jan 6 16:28:56 2011 @@ -192,6 +192,10 @@ SDValue MakeLibCall(RTLIB::Libcall LC, EVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned, DebugLoc dl); + std::pair ExpandChainLibCall(RTLIB::Libcall LC, + SDNode *Node, bool isSigned); + std::pair ExpandAtomic(SDNode *Node); + SDValue PromoteTargetBoolean(SDValue Bool, EVT VT); void ReplaceValueWith(SDValue From, SDValue To); void SplitInteger(SDValue Op, SDValue &Lo, SDValue &Hi); From baldrick at free.fr Thu Jan 6 16:45:10 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 06 Jan 2011 23:45:10 +0100 Subject: [llvm-commits] [llvm] r122979 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeIntegerTypes.cpp LegalizeTypes.cpp LegalizeTypes.h In-Reply-To: <20110106222856.3C5A92A6C12C@llvm.org> References: <20110106222856.3C5A92A6C12C@llvm.org> Message-ID: <4D2645F6.1020301@free.fr> Hi Eric, > +std::pair DAGTypeLegalizer::ExpandAtomic(SDNode *Node) { why not put this function in LegalizeIntegerTypes? It doesn't seem to be of general utility. Are you planning to use it from some other LegalizeXYZTypes file? > + std::pair ExpandAtomic(SDNode *Node); > + Then you wouldn't need this declaration either. Ciao, Duncan. From echristo at apple.com Thu Jan 6 16:47:13 2011 From: echristo at apple.com (Eric Christopher) Date: Thu, 6 Jan 2011 14:47:13 -0800 Subject: [llvm-commits] [llvm] r122979 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeIntegerTypes.cpp LegalizeTypes.cpp LegalizeTypes.h In-Reply-To: <4D2645F6.1020301@free.fr> References: <20110106222856.3C5A92A6C12C@llvm.org> <4D2645F6.1020301@free.fr> Message-ID: <908B8B1D-B71C-4013-AF8C-1475ABEDC619@apple.com> On Jan 6, 2011, at 2:45 PM, Duncan Sands wrote: > Hi Eric, > >> +std::pair DAGTypeLegalizer::ExpandAtomic(SDNode *Node) { > > why not put this function in LegalizeIntegerTypes? It doesn't seem to be of > general utility. Are you planning to use it from some other LegalizeXYZTypes > file? > >> + std::pair ExpandAtomic(SDNode *Node); >> + > > Then you wouldn't need this declaration either. That's fair, I'll do that :) -eric -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110106/1688722e/attachment.html From baldrick at free.fr Thu Jan 6 17:04:29 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 06 Jan 2011 23:04:29 -0000 Subject: [llvm-commits] [llvm] r122982 - /llvm/trunk/test/CodeGen/Generic/2011-01-06-BigNumberCrash.ll Message-ID: <20110106230429.C05152A6C12C@llvm.org> Author: baldrick Date: Thu Jan 6 17:04:29 2011 New Revision: 122982 URL: http://llvm.org/viewvc/llvm-project?rev=122982&view=rev Log: Add a testcase for PR8582, which mysteriously fixed itself, in case the problem comes back some day. Added: llvm/trunk/test/CodeGen/Generic/2011-01-06-BigNumberCrash.ll Added: llvm/trunk/test/CodeGen/Generic/2011-01-06-BigNumberCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/2011-01-06-BigNumberCrash.ll?rev=122982&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/Generic/2011-01-06-BigNumberCrash.ll (added) +++ llvm/trunk/test/CodeGen/Generic/2011-01-06-BigNumberCrash.ll Thu Jan 6 17:04:29 2011 @@ -0,0 +1,15 @@ +; RUN: llc < %s +; PR8582 + +define void @uint82() nounwind { +entry: + %tmp3 = select i1 undef, i960 4872657003430991806293355221650511486142000513558154090491761976385142772940676648094983476628187266917101386048750715027104076737938178423519545241493072038894065019132638919037781494702597609951702322267198307200588774905587225212622510286498675097141625012190497682454879271766334636032, i960 0 + br i1 undef, label %for.body25.for.body25_crit_edge, label %if.end + +for.body25.for.body25_crit_edge: ; preds = %entry + %ins = or i960 %tmp3, undef + ret void + +if.end: ; preds = %entry + ret void +} From baldrick at free.fr Thu Jan 6 17:45:23 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 06 Jan 2011 23:45:23 -0000 Subject: [llvm-commits] [llvm] r122983 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeTypes.cpp test/CodeGen/X86/2011-01-07-LegalizeTypesCrash.ll Message-ID: <20110106234523.2A8202A6C12C@llvm.org> Author: baldrick Date: Thu Jan 6 17:45:22 2011 New Revision: 122983 URL: http://llvm.org/viewvc/llvm-project?rev=122983&view=rev Log: Fix the other problem reported in PR8582. Testcase and patch by Nadav Rotem. Added: llvm/trunk/test/CodeGen/X86/2011-01-07-LegalizeTypesCrash.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=122983&r1=122982&r2=122983&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Thu Jan 6 17:45:22 2011 @@ -714,6 +714,11 @@ if (M->getNodeId() == Processed) RemapValue(NewVal); DAG.ReplaceAllUsesOfValueWith(OldVal, NewVal, &NUL); + // OldVal may be a target of the ReplacedValues map which was marked + // NewNode to force reanalysis because it was updated. Ensure that + // anything that ReplacedValues mapped to OldVal will now be mapped + // all the way to NewVal. + ReplacedValues[OldVal] = NewVal; } // The original node continues to exist in the DAG, marked NewNode. } Added: llvm/trunk/test/CodeGen/X86/2011-01-07-LegalizeTypesCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2011-01-07-LegalizeTypesCrash.ll?rev=122983&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2011-01-07-LegalizeTypesCrash.ll (added) +++ llvm/trunk/test/CodeGen/X86/2011-01-07-LegalizeTypesCrash.ll Thu Jan 6 17:45:22 2011 @@ -0,0 +1,19 @@ +; RUN: llc < %s -enable-legalize-types-checking +; PR8582 +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" +target triple = "i686-pc-win32" + +define void @test() nounwind { + %i17 = icmp eq <4 x i8> undef, zeroinitializer + %cond = extractelement <4 x i1> %i17, i32 0 + %_comp = select i1 %cond, i8 0, i8 undef + %merge = insertelement <4 x i8> undef, i8 %_comp, i32 0 + %cond3 = extractelement <4 x i1> %i17, i32 1 + %_comp4 = select i1 %cond3, i8 0, i8 undef + %merge5 = insertelement <4 x i8> %merge, i8 %_comp4, i32 1 + %cond8 = extractelement <4 x i1> %i17, i32 2 + %_comp9 = select i1 %cond8, i8 0, i8 undef + %m387 = insertelement <4 x i8> %merge5, i8 %_comp9, i32 2 + store <4 x i8> %m387, <4 x i8>* undef + ret void +} From bob.wilson at apple.com Thu Jan 6 17:52:04 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 6 Jan 2011 15:52:04 -0800 Subject: [llvm-commits] shufflevector on ARM (clumsy x-post from llvmdev) In-Reply-To: References: Message-ID: On Jan 6, 2011, at 6:52 AM, Tim Northover wrote: > I've put together a couple of patches to improve matters: > > http://www.maths.ed.ac.uk/~s0677366/build_vector.patch > http://www.maths.ed.ac.uk/~s0677366/extract_subvector.patch The extract_subvector patch looks good, except for the testsuite changes. Those tests are supposed to test spill code, and your patch causes them to stop spilling. I'll commit the patch after I fix the tests to continue spilling in spite of your change. I'll look at the build_vector patch soon. From jyasskin at gmail.com Thu Jan 6 18:31:40 2011 From: jyasskin at gmail.com (jyasskin at gmail.com) Date: Fri, 07 Jan 2011 00:31:40 +0000 Subject: [llvm-commits] [PATCH] Remove unused variables found by gcc-4.6's -Wunused-but-set-variable (issue3827044) Message-ID: <20cf30549f43ed8e62049936bde4@google.com> Reviewers: , Description: Some of these removals may actually indicate bugs, so someone who knows this code better than I do should take a look. There are a couple other gcc-4.6 warnings in googletest, but we should get a fix for them when they release version 1.6. Please review this at http://codereview.appspot.com/3827044/ Affected files: M lib/Target/ARM/ARMFastISel.cpp M lib/Target/ARM/ARMFrameInfo.cpp M lib/Target/CellSPU/SPUISelLowering.cpp M lib/Target/PowerPC/PPCISelLowering.cpp M lib/Target/X86/X86ISelDAGToDAG.cpp Index: lib/Target/X86/X86ISelDAGToDAG.cpp =================================================================== --- lib/Target/X86/X86ISelDAGToDAG.cpp (revision 122455) +++ lib/Target/X86/X86ISelDAGToDAG.cpp (working copy) @@ -1604,13 +1604,13 @@ SDNode *X86DAGToDAGISel::Select(SDNode *Node) { SDValue N0 = Node->getOperand(0); SDValue N1 = Node->getOperand(1); - unsigned LoReg, HiReg; + unsigned LoReg; switch (NVT.getSimpleVT().SimpleTy) { default: llvm_unreachable("Unsupported VT!"); - case MVT::i8: LoReg = X86::AL; HiReg = X86::AH; Opc = X86::MUL8r; break; - case MVT::i16: LoReg = X86::AX; HiReg = X86::DX; Opc = X86::MUL16r; break; - case MVT::i32: LoReg = X86::EAX; HiReg = X86::EDX; Opc = X86::MUL32r; break; - case MVT::i64: LoReg = X86::RAX; HiReg = X86::RDX; Opc = X86::MUL64r; break; + case MVT::i8: LoReg = X86::AL; Opc = X86::MUL8r; break; + case MVT::i16: LoReg = X86::AX; Opc = X86::MUL16r; break; + case MVT::i32: LoReg = X86::EAX; Opc = X86::MUL32r; break; + case MVT::i64: LoReg = X86::RAX; Opc = X86::MUL64r; break; } SDValue InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg, Index: lib/Target/CellSPU/SPUISelLowering.cpp =================================================================== --- lib/Target/CellSPU/SPUISelLowering.cpp (revision 122455) +++ lib/Target/CellSPU/SPUISelLowering.cpp (working copy) @@ -683,10 +683,6 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPU // storage position offset from lower 16 byte aligned memory chunk SDValue offset = DAG.getNode(ISD::AND, dl, MVT::i32, basePtr, DAG.getConstant( 0xf, MVT::i32 ) ); - // 16 - offset - SDValue offset_compl = DAG.getNode(ISD::SUB, dl, MVT::i32, - DAG.getConstant( 16, MVT::i32), - offset ); // get a registerfull of ones. (this implementation is a workaround: LLVM // cannot handle 128 bit signed int constants) SDValue ones = DAG.getConstant(-1, MVT::v4i32 ); @@ -911,10 +907,6 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG, const SP SDValue offset_compl = DAG.getNode(ISD::SUB, dl, MVT::i32, DAG.getConstant( 16, MVT::i32), offset); - SDValue hi_shift = DAG.getNode(ISD::SUB, dl, MVT::i32, - DAG.getConstant( VT.getSizeInBits()/8, - MVT::i32), - offset_compl); // 16 - sizeof(Value) SDValue surplus = DAG.getNode(ISD::SUB, dl, MVT::i32, DAG.getConstant( 16, MVT::i32), @@ -3260,4 +3252,3 @@ SPUTargetLowering::isLegalAddressingMode(const Add return false; } - Index: lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- lib/Target/PowerPC/PPCISelLowering.cpp (revision 122458) +++ lib/Target/PowerPC/PPCISelLowering.cpp (working copy) @@ -1176,7 +1176,6 @@ SDValue PPCTargetLowering::LowerJumpTable(SDValue SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const { EVT PtrVT = Op.getValueType(); - DebugLoc DL = Op.getDebugLoc(); const BlockAddress *BA = cast(Op)->getBlockAddress(); Index: lib/Target/ARM/ARMFrameInfo.cpp =================================================================== --- lib/Target/ARM/ARMFrameInfo.cpp (revision 122455) +++ lib/Target/ARM/ARMFrameInfo.cpp (working copy) @@ -651,7 +651,6 @@ bool ARMFrameInfo::spillCalleeSavedRegisters(Machi MachineFunction &MF = *MBB.getParent(); ARMFunctionInfo *AFI = MF.getInfo(); - DebugLoc DL = MI->getDebugLoc(); unsigned PushOpc = AFI->isThumbFunction() ? ARM::t2STMDB_UPD : ARM::STMDB_UPD; unsigned PushOneOpc = AFI->isThumbFunction() ? ARM::t2STR_PRE : ARM::STR_PRE; @@ -673,7 +672,6 @@ bool ARMFrameInfo::restoreCalleeSavedRegisters(Mac MachineFunction &MF = *MBB.getParent(); ARMFunctionInfo *AFI = MF.getInfo(); bool isVarArg = AFI->getVarArgsRegSaveSize() > 0; - DebugLoc DL = MI->getDebugLoc(); unsigned PopOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD; unsigned LdrOpc = AFI->isThumbFunction() ? ARM::t2LDR_POST : ARM::LDR_POST; Index: lib/Target/ARM/ARMFastISel.cpp =================================================================== --- lib/Target/ARM/ARMFastISel.cpp (revision 122455) +++ lib/Target/ARM/ARMFastISel.cpp (working copy) @@ -1017,21 +1017,17 @@ bool ARMFastISel::SelectBranch(const Instruction * return false; unsigned CmpOpc; - unsigned CondReg; switch (VT.SimpleTy) { default: return false; // TODO: Verify compares. case MVT::f32: CmpOpc = ARM::VCMPES; - CondReg = ARM::FPSCR; break; case MVT::f64: CmpOpc = ARM::VCMPED; - CondReg = ARM::FPSCR; break; case MVT::i32: CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr; - CondReg = ARM::CPSR; break; } From echristo at apple.com Thu Jan 6 18:37:27 2011 From: echristo at apple.com (Eric Christopher) Date: Thu, 6 Jan 2011 16:37:27 -0800 Subject: [llvm-commits] [PATCH] Remove unused variables found by gcc-4.6's -Wunused-but-set-variable (issue3827044) In-Reply-To: <20cf30549f43ed8e62049936bde4@google.com> References: <20cf30549f43ed8e62049936bde4@google.com> Message-ID: <4A3969AF-E7F8-404A-95D5-BF832A330CDC@apple.com> > > Affected files: > M lib/Target/ARM/ARMFastISel.cpp > M lib/Target/ARM/ARMFrameInfo.cpp These changes are fine. Thanks! -eric -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110106/1d062c92/attachment.html From isanbard at gmail.com Thu Jan 6 20:54:45 2011 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 07 Jan 2011 02:54:45 -0000 Subject: [llvm-commits] [llvm] r122990 - /llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp Message-ID: <20110107025445.4071B2A6C12C@llvm.org> Author: void Date: Thu Jan 6 20:54:45 2011 New Revision: 122990 URL: http://llvm.org/viewvc/llvm-project?rev=122990&view=rev Log: Early exit if we don't have invokes. The 'Unwinds' vector isn't modified unless we have invokes, so there is no functionality change here. Modified: llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp Modified: llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp?rev=122990&r1=122989&r2=122990&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp (original) +++ llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp Thu Jan 6 20:54:45 2011 @@ -319,8 +319,12 @@ Unwinds.push_back(UI); } } - // If we don't have any invokes or unwinds, there's nothing to do. - if (Unwinds.empty() && Invokes.empty()) return false; + + NumInvokes += Invokes.size(); + NumUnwinds += Unwinds.size(); + + // If we don't have any invokes, there's nothing to do. + if (Invokes.empty()) return false; // Find the eh.selector.*, eh.exception and alloca calls. // @@ -334,6 +338,7 @@ SmallVector EH_Selectors; SmallVector EH_Exceptions; SmallVector JmpbufUpdatePoints; + // Note: Skip the entry block since there's nothing there that interests // us. eh.selector and eh.exception shouldn't ever be there, and we // want to disregard any allocas that are there. @@ -353,236 +358,231 @@ } } } + // If we don't have any eh.selector calls, we can't determine the personality // function. Without a personality function, we can't process exceptions. if (!PersonalityFn) return false; - NumInvokes += Invokes.size(); - NumUnwinds += Unwinds.size(); + // We have invokes, so we need to add register/unregister calls to get this + // function onto the global unwind stack. + // + // First thing we need to do is scan the whole function for values that are + // live across unwind edges. Each value that is live across an unwind edge we + // spill into a stack location, guaranteeing that there is nothing live across + // the unwind edge. This process also splits all critical edges coming out of + // invoke's. + splitLiveRangesAcrossInvokes(Invokes); + + BasicBlock *EntryBB = F.begin(); + // Create an alloca for the incoming jump buffer ptr and the new jump buffer + // that needs to be restored on all exits from the function. This is an + // alloca because the value needs to be added to the global context list. + unsigned Align = 4; // FIXME: Should be a TLI check? + AllocaInst *FunctionContext = + new AllocaInst(FunctionContextTy, 0, Align, + "fcn_context", F.begin()->begin()); + + Value *Idxs[2]; + const Type *Int32Ty = Type::getInt32Ty(F.getContext()); + Value *Zero = ConstantInt::get(Int32Ty, 0); + // We need to also keep around a reference to the call_site field + Idxs[0] = Zero; + Idxs[1] = ConstantInt::get(Int32Ty, 1); + CallSite = GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, + "call_site", + EntryBB->getTerminator()); + + // The exception selector comes back in context->data[1] + Idxs[1] = ConstantInt::get(Int32Ty, 2); + Value *FCData = GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, + "fc_data", + EntryBB->getTerminator()); + Idxs[1] = ConstantInt::get(Int32Ty, 1); + Value *SelectorAddr = GetElementPtrInst::Create(FCData, Idxs, Idxs+2, + "exc_selector_gep", + EntryBB->getTerminator()); + // The exception value comes back in context->data[0] + Idxs[1] = Zero; + Value *ExceptionAddr = GetElementPtrInst::Create(FCData, Idxs, Idxs+2, + "exception_gep", + EntryBB->getTerminator()); + + // The result of the eh.selector call will be replaced with a a reference to + // the selector value returned in the function context. We leave the selector + // itself so the EH analysis later can use it. + for (int i = 0, e = EH_Selectors.size(); i < e; ++i) { + CallInst *I = EH_Selectors[i]; + Value *SelectorVal = new LoadInst(SelectorAddr, "select_val", true, I); + I->replaceAllUsesWith(SelectorVal); + } - if (!Invokes.empty()) { - // We have invokes, so we need to add register/unregister calls to get - // this function onto the global unwind stack. - // - // First thing we need to do is scan the whole function for values that are - // live across unwind edges. Each value that is live across an unwind edge - // we spill into a stack location, guaranteeing that there is nothing live - // across the unwind edge. This process also splits all critical edges - // coming out of invoke's. - splitLiveRangesAcrossInvokes(Invokes); - - BasicBlock *EntryBB = F.begin(); - // Create an alloca for the incoming jump buffer ptr and the new jump buffer - // that needs to be restored on all exits from the function. This is an - // alloca because the value needs to be added to the global context list. - unsigned Align = 4; // FIXME: Should be a TLI check? - AllocaInst *FunctionContext = - new AllocaInst(FunctionContextTy, 0, Align, - "fcn_context", F.begin()->begin()); - - Value *Idxs[2]; - const Type *Int32Ty = Type::getInt32Ty(F.getContext()); - Value *Zero = ConstantInt::get(Int32Ty, 0); - // We need to also keep around a reference to the call_site field - Idxs[0] = Zero; - Idxs[1] = ConstantInt::get(Int32Ty, 1); - CallSite = GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, - "call_site", - EntryBB->getTerminator()); - - // The exception selector comes back in context->data[1] - Idxs[1] = ConstantInt::get(Int32Ty, 2); - Value *FCData = GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, - "fc_data", - EntryBB->getTerminator()); - Idxs[1] = ConstantInt::get(Int32Ty, 1); - Value *SelectorAddr = GetElementPtrInst::Create(FCData, Idxs, Idxs+2, - "exc_selector_gep", - EntryBB->getTerminator()); - // The exception value comes back in context->data[0] - Idxs[1] = Zero; - Value *ExceptionAddr = GetElementPtrInst::Create(FCData, Idxs, Idxs+2, - "exception_gep", - EntryBB->getTerminator()); - - // The result of the eh.selector call will be replaced with a - // a reference to the selector value returned in the function - // context. We leave the selector itself so the EH analysis later - // can use it. - for (int i = 0, e = EH_Selectors.size(); i < e; ++i) { - CallInst *I = EH_Selectors[i]; - Value *SelectorVal = new LoadInst(SelectorAddr, "select_val", true, I); - I->replaceAllUsesWith(SelectorVal); - } - // eh.exception calls are replaced with references to the proper - // location in the context. Unlike eh.selector, the eh.exception - // calls are removed entirely. - for (int i = 0, e = EH_Exceptions.size(); i < e; ++i) { - CallInst *I = EH_Exceptions[i]; - // Possible for there to be duplicates, so check to make sure - // the instruction hasn't already been removed. - if (!I->getParent()) continue; - Value *Val = new LoadInst(ExceptionAddr, "exception", true, I); - const Type *Ty = Type::getInt8PtrTy(F.getContext()); - Val = CastInst::Create(Instruction::IntToPtr, Val, Ty, "", I); + // eh.exception calls are replaced with references to the proper location in + // the context. Unlike eh.selector, the eh.exception calls are removed + // entirely. + for (int i = 0, e = EH_Exceptions.size(); i < e; ++i) { + CallInst *I = EH_Exceptions[i]; + // Possible for there to be duplicates, so check to make sure the + // instruction hasn't already been removed. + if (!I->getParent()) continue; + Value *Val = new LoadInst(ExceptionAddr, "exception", true, I); + const Type *Ty = Type::getInt8PtrTy(F.getContext()); + Val = CastInst::Create(Instruction::IntToPtr, Val, Ty, "", I); - I->replaceAllUsesWith(Val); - I->eraseFromParent(); - } + I->replaceAllUsesWith(Val); + I->eraseFromParent(); + } - // The entry block changes to have the eh.sjlj.setjmp, with a conditional - // branch to a dispatch block for non-zero returns. If we return normally, - // we're not handling an exception and just register the function context - // and continue. - - // Create the dispatch block. The dispatch block is basically a big switch - // statement that goes to all of the invoke landing pads. - BasicBlock *DispatchBlock = - BasicBlock::Create(F.getContext(), "eh.sjlj.setjmp.catch", &F); - - // Add a call to dispatch_setup at the start of the dispatch block. This - // is expanded to any target-specific setup that needs to be done. - Value *SetupArg = - CastInst::Create(Instruction::BitCast, FunctionContext, - Type::getInt8PtrTy(F.getContext()), "", + // The entry block changes to have the eh.sjlj.setjmp, with a conditional + // branch to a dispatch block for non-zero returns. If we return normally, + // we're not handling an exception and just register the function context and + // continue. + + // Create the dispatch block. The dispatch block is basically a big switch + // statement that goes to all of the invoke landing pads. + BasicBlock *DispatchBlock = + BasicBlock::Create(F.getContext(), "eh.sjlj.setjmp.catch", &F); + + // Add a call to dispatch_setup at the start of the dispatch block. This is + // expanded to any target-specific setup that needs to be done. + Value *SetupArg = + CastInst::Create(Instruction::BitCast, FunctionContext, + Type::getInt8PtrTy(F.getContext()), "", + DispatchBlock); + CallInst::Create(DispatchSetupFn, SetupArg, "", DispatchBlock); + + // Insert a load of the callsite in the dispatch block, and a switch on its + // value. By default, we go to a block that just does an unwind (which is the + // correct action for a standard call). + BasicBlock *UnwindBlock = + BasicBlock::Create(F.getContext(), "unwindbb", &F); + Unwinds.push_back(new UnwindInst(F.getContext(), UnwindBlock)); + + Value *DispatchLoad = new LoadInst(CallSite, "invoke.num", true, + DispatchBlock); + SwitchInst *DispatchSwitch = + SwitchInst::Create(DispatchLoad, UnwindBlock, Invokes.size(), DispatchBlock); - CallInst::Create(DispatchSetupFn, SetupArg, "", DispatchBlock); - - // Insert a load of the callsite in the dispatch block, and a switch on - // its value. By default, we go to a block that just does an unwind - // (which is the correct action for a standard call). - BasicBlock *UnwindBlock = - BasicBlock::Create(F.getContext(), "unwindbb", &F); - Unwinds.push_back(new UnwindInst(F.getContext(), UnwindBlock)); - - Value *DispatchLoad = new LoadInst(CallSite, "invoke.num", true, - DispatchBlock); - SwitchInst *DispatchSwitch = - SwitchInst::Create(DispatchLoad, UnwindBlock, Invokes.size(), - DispatchBlock); - // Split the entry block to insert the conditional branch for the setjmp. - BasicBlock *ContBlock = EntryBB->splitBasicBlock(EntryBB->getTerminator(), - "eh.sjlj.setjmp.cont"); - - // Populate the Function Context - // 1. LSDA address - // 2. Personality function address - // 3. jmpbuf (save SP, FP and call eh.sjlj.setjmp) - - // LSDA address - Idxs[0] = Zero; - Idxs[1] = ConstantInt::get(Int32Ty, 4); - Value *LSDAFieldPtr = - GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, - "lsda_gep", - EntryBB->getTerminator()); - Value *LSDA = CallInst::Create(LSDAAddrFn, "lsda_addr", - EntryBB->getTerminator()); - new StoreInst(LSDA, LSDAFieldPtr, true, EntryBB->getTerminator()); - - Idxs[1] = ConstantInt::get(Int32Ty, 3); - Value *PersonalityFieldPtr = - GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, - "lsda_gep", + // Split the entry block to insert the conditional branch for the setjmp. + BasicBlock *ContBlock = EntryBB->splitBasicBlock(EntryBB->getTerminator(), + "eh.sjlj.setjmp.cont"); + + // Populate the Function Context + // 1. LSDA address + // 2. Personality function address + // 3. jmpbuf (save SP, FP and call eh.sjlj.setjmp) + + // LSDA address + Idxs[0] = Zero; + Idxs[1] = ConstantInt::get(Int32Ty, 4); + Value *LSDAFieldPtr = + GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, + "lsda_gep", + EntryBB->getTerminator()); + Value *LSDA = CallInst::Create(LSDAAddrFn, "lsda_addr", + EntryBB->getTerminator()); + new StoreInst(LSDA, LSDAFieldPtr, true, EntryBB->getTerminator()); + + Idxs[1] = ConstantInt::get(Int32Ty, 3); + Value *PersonalityFieldPtr = + GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, + "lsda_gep", + EntryBB->getTerminator()); + new StoreInst(PersonalityFn, PersonalityFieldPtr, true, + EntryBB->getTerminator()); + + // Save the frame pointer. + Idxs[1] = ConstantInt::get(Int32Ty, 5); + Value *JBufPtr + = GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, + "jbuf_gep", EntryBB->getTerminator()); - new StoreInst(PersonalityFn, PersonalityFieldPtr, true, - EntryBB->getTerminator()); - - // Save the frame pointer. - Idxs[1] = ConstantInt::get(Int32Ty, 5); - Value *JBufPtr - = GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, - "jbuf_gep", - EntryBB->getTerminator()); - Idxs[1] = ConstantInt::get(Int32Ty, 0); - Value *FramePtr = - GetElementPtrInst::Create(JBufPtr, Idxs, Idxs+2, "jbuf_fp_gep", - EntryBB->getTerminator()); - - Value *Val = CallInst::Create(FrameAddrFn, - ConstantInt::get(Int32Ty, 0), - "fp", - EntryBB->getTerminator()); - new StoreInst(Val, FramePtr, true, EntryBB->getTerminator()); - - // Save the stack pointer. - Idxs[1] = ConstantInt::get(Int32Ty, 2); - Value *StackPtr = - GetElementPtrInst::Create(JBufPtr, Idxs, Idxs+2, "jbuf_sp_gep", + Idxs[1] = ConstantInt::get(Int32Ty, 0); + Value *FramePtr = + GetElementPtrInst::Create(JBufPtr, Idxs, Idxs+2, "jbuf_fp_gep", + EntryBB->getTerminator()); + + Value *Val = CallInst::Create(FrameAddrFn, + ConstantInt::get(Int32Ty, 0), + "fp", EntryBB->getTerminator()); + new StoreInst(Val, FramePtr, true, EntryBB->getTerminator()); - Val = CallInst::Create(StackAddrFn, "sp", EntryBB->getTerminator()); - new StoreInst(Val, StackPtr, true, EntryBB->getTerminator()); - - // Call the setjmp instrinsic. It fills in the rest of the jmpbuf. - Value *SetjmpArg = - CastInst::Create(Instruction::BitCast, JBufPtr, - Type::getInt8PtrTy(F.getContext()), "", - EntryBB->getTerminator()); - Value *DispatchVal = CallInst::Create(BuiltinSetjmpFn, SetjmpArg, - "dispatch", - EntryBB->getTerminator()); - // check the return value of the setjmp. non-zero goes to dispatcher. - Value *IsNormal = new ICmpInst(EntryBB->getTerminator(), - ICmpInst::ICMP_EQ, DispatchVal, Zero, - "notunwind"); - // Nuke the uncond branch. - EntryBB->getTerminator()->eraseFromParent(); - - // Put in a new condbranch in its place. - BranchInst::Create(ContBlock, DispatchBlock, IsNormal, EntryBB); - - // Register the function context and make sure it's known to not throw - CallInst *Register = - CallInst::Create(RegisterFn, FunctionContext, "", - ContBlock->getTerminator()); - Register->setDoesNotThrow(); - - // At this point, we are all set up, update the invoke instructions - // to mark their call_site values, and fill in the dispatch switch - // accordingly. - for (unsigned i = 0, e = Invokes.size(); i != e; ++i) - markInvokeCallSite(Invokes[i], i+1, CallSite, DispatchSwitch); - - // Mark call instructions that aren't nounwind as no-action - // (call_site == -1). Skip the entry block, as prior to then, no function - // context has been created for this function and any unexpected exceptions - // thrown will go directly to the caller's context, which is what we want - // anyway, so no need to do anything here. - for (Function::iterator BB = F.begin(), E = F.end(); ++BB != E;) { - for (BasicBlock::iterator I = BB->begin(), end = BB->end(); I != end; ++I) - if (CallInst *CI = dyn_cast(I)) { - // Ignore calls to the EH builtins (eh.selector, eh.exception) - Constant *Callee = CI->getCalledFunction(); - if (Callee != SelectorFn && Callee != ExceptionFn - && !CI->doesNotThrow()) - insertCallSiteStore(CI, -1, CallSite); - } - } - - // Replace all unwinds with a branch to the unwind handler. - // ??? Should this ever happen with sjlj exceptions? - for (unsigned i = 0, e = Unwinds.size(); i != e; ++i) { - BranchInst::Create(UnwindBlock, Unwinds[i]); - Unwinds[i]->eraseFromParent(); - } + // Save the stack pointer. + Idxs[1] = ConstantInt::get(Int32Ty, 2); + Value *StackPtr = + GetElementPtrInst::Create(JBufPtr, Idxs, Idxs+2, "jbuf_sp_gep", + EntryBB->getTerminator()); + + Val = CallInst::Create(StackAddrFn, "sp", EntryBB->getTerminator()); + new StoreInst(Val, StackPtr, true, EntryBB->getTerminator()); + + // Call the setjmp instrinsic. It fills in the rest of the jmpbuf. + Value *SetjmpArg = + CastInst::Create(Instruction::BitCast, JBufPtr, + Type::getInt8PtrTy(F.getContext()), "", + EntryBB->getTerminator()); + Value *DispatchVal = CallInst::Create(BuiltinSetjmpFn, SetjmpArg, + "dispatch", + EntryBB->getTerminator()); + // check the return value of the setjmp. non-zero goes to dispatcher. + Value *IsNormal = new ICmpInst(EntryBB->getTerminator(), + ICmpInst::ICMP_EQ, DispatchVal, Zero, + "notunwind"); + // Nuke the uncond branch. + EntryBB->getTerminator()->eraseFromParent(); + + // Put in a new condbranch in its place. + BranchInst::Create(ContBlock, DispatchBlock, IsNormal, EntryBB); + + // Register the function context and make sure it's known to not throw + CallInst *Register = + CallInst::Create(RegisterFn, FunctionContext, "", + ContBlock->getTerminator()); + Register->setDoesNotThrow(); + + // At this point, we are all set up, update the invoke instructions to mark + // their call_site values, and fill in the dispatch switch accordingly. + for (unsigned i = 0, e = Invokes.size(); i != e; ++i) + markInvokeCallSite(Invokes[i], i+1, CallSite, DispatchSwitch); + + // Mark call instructions that aren't nounwind as no-action (call_site == + // -1). Skip the entry block, as prior to then, no function context has been + // created for this function and any unexpected exceptions thrown will go + // directly to the caller's context, which is what we want anyway, so no need + // to do anything here. + for (Function::iterator BB = F.begin(), E = F.end(); ++BB != E;) { + for (BasicBlock::iterator I = BB->begin(), end = BB->end(); I != end; ++I) + if (CallInst *CI = dyn_cast(I)) { + // Ignore calls to the EH builtins (eh.selector, eh.exception) + Constant *Callee = CI->getCalledFunction(); + if (Callee != SelectorFn && Callee != ExceptionFn + && !CI->doesNotThrow()) + insertCallSiteStore(CI, -1, CallSite); + } + } - // Following any allocas not in the entry block, update the saved SP - // in the jmpbuf to the new value. - for (unsigned i = 0, e = JmpbufUpdatePoints.size(); i != e; ++i) { - Instruction *AI = JmpbufUpdatePoints[i]; - Instruction *StackAddr = CallInst::Create(StackAddrFn, "sp"); - StackAddr->insertAfter(AI); - Instruction *StoreStackAddr = new StoreInst(StackAddr, StackPtr, true); - StoreStackAddr->insertAfter(StackAddr); - } + // Replace all unwinds with a branch to the unwind handler. + // ??? Should this ever happen with sjlj exceptions? + for (unsigned i = 0, e = Unwinds.size(); i != e; ++i) { + BranchInst::Create(UnwindBlock, Unwinds[i]); + Unwinds[i]->eraseFromParent(); + } - // Finally, for any returns from this function, if this function contains an - // invoke, add a call to unregister the function context. - for (unsigned i = 0, e = Returns.size(); i != e; ++i) - CallInst::Create(UnregisterFn, FunctionContext, "", Returns[i]); + // Following any allocas not in the entry block, update the saved SP in the + // jmpbuf to the new value. + for (unsigned i = 0, e = JmpbufUpdatePoints.size(); i != e; ++i) { + Instruction *AI = JmpbufUpdatePoints[i]; + Instruction *StackAddr = CallInst::Create(StackAddrFn, "sp"); + StackAddr->insertAfter(AI); + Instruction *StoreStackAddr = new StoreInst(StackAddr, StackPtr, true); + StoreStackAddr->insertAfter(StackAddr); } + // Finally, for any returns from this function, if this function contains an + // invoke, add a call to unregister the function context. + for (unsigned i = 0, e = Returns.size(); i != e; ++i) + CallInst::Create(UnregisterFn, FunctionContext, "", Returns[i]); + return true; } From bob.wilson at apple.com Thu Jan 6 22:58:56 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 07 Jan 2011 04:58:56 -0000 Subject: [llvm-commits] [llvm] r122993 - in /llvm/trunk: include/llvm/CodeGen/ISDOpcodes.h lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp Message-ID: <20110107045856.34AB22A6C12C@llvm.org> Author: bwilson Date: Thu Jan 6 22:58:56 2011 New Revision: 122993 URL: http://llvm.org/viewvc/llvm-project?rev=122993&view=rev Log: Change EXTRACT_SUBVECTOR to require a constant index. We were never generating any of these nodes with variable indices, and there was one legalizer function asserting on a non-constant index. If we ever have a need to support variable indices, we can add this back again. Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=122993&r1=122992&r2=122993&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Thu Jan 6 22:58:56 2011 @@ -270,8 +270,8 @@ CONCAT_VECTORS, /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an - /// vector value) starting with the (potentially variable) element number - /// IDX, which must be a multiple of the result vector length. + /// vector value) starting with the element number IDX, which must be a + /// constant multiple of the result vector length. EXTRACT_SUBVECTOR, /// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp?rev=122993&r1=122992&r2=122993&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp Thu Jan 6 22:58:56 2011 @@ -645,16 +645,15 @@ SDValue &Hi) { SDValue Vec = N->getOperand(0); SDValue Idx = N->getOperand(1); - EVT IdxVT = Idx.getValueType(); DebugLoc dl = N->getDebugLoc(); EVT LoVT, HiVT; GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, LoVT, Vec, Idx); - Idx = DAG.getNode(ISD::ADD, dl, IdxVT, Idx, - DAG.getConstant(LoVT.getVectorNumElements(), IdxVT)); - Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HiVT, Vec, Idx); + uint64_t IdxVal = cast(Idx)->getZExtValue(); + Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HiVT, Vec, + DAG.getIntPtrConstant(IdxVal + LoVT.getVectorNumElements())); } void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDValue &Lo, @@ -1051,8 +1050,7 @@ } SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) { - // We know that the extracted result type is legal. For now, assume the index - // is a constant. + // We know that the extracted result type is legal. EVT SubVT = N->getValueType(0); SDValue Idx = N->getOperand(1); DebugLoc dl = N->getDebugLoc(); @@ -1791,39 +1789,25 @@ EVT InVT = InOp.getValueType(); - ConstantSDNode *CIdx = dyn_cast(Idx); - if (CIdx) { - unsigned IdxVal = CIdx->getZExtValue(); - // Check if we can just return the input vector after widening. - if (IdxVal == 0 && InVT == WidenVT) - return InOp; - - // Check if we can extract from the vector. - unsigned InNumElts = InVT.getVectorNumElements(); - if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts) - return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, WidenVT, InOp, Idx); - } + // Check if we can just return the input vector after widening. + uint64_t IdxVal = cast(Idx)->getZExtValue(); + if (IdxVal == 0 && InVT == WidenVT) + return InOp; + + // Check if we can extract from the vector. + unsigned InNumElts = InVT.getVectorNumElements(); + if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts) + return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, WidenVT, InOp, Idx); // We could try widening the input to the right length but for now, extract // the original elements, fill the rest with undefs and build a vector. SmallVector Ops(WidenNumElts); EVT EltVT = VT.getVectorElementType(); - EVT IdxVT = Idx.getValueType(); unsigned NumElts = VT.getVectorNumElements(); unsigned i; - if (CIdx) { - unsigned IdxVal = CIdx->getZExtValue(); - for (i=0; i < NumElts; ++i) - Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, - DAG.getConstant(IdxVal+i, IdxVT)); - } else { - Ops[0] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, Idx); - for (i=1; i < NumElts; ++i) { - SDValue NewIdx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, - DAG.getConstant(i, IdxVT)); - Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, NewIdx); - } - } + for (i=0; i < NumElts; ++i) + Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, + DAG.getIntPtrConstant(IdxVal+i)); SDValue UndefVal = DAG.getUNDEF(EltVT); for (; i < WidenNumElts; ++i) From bob.wilson at apple.com Thu Jan 6 22:58:58 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 07 Jan 2011 04:58:58 -0000 Subject: [llvm-commits] [llvm] r122994 - /llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp Message-ID: <20110107045858.CFDB02A6C12D@llvm.org> Author: bwilson Date: Thu Jan 6 22:58:58 2011 New Revision: 122994 URL: http://llvm.org/viewvc/llvm-project?rev=122994&view=rev Log: Fix a comment typo. Modified: llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp Modified: llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp?rev=122994&r1=122993&r2=122994&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp (original) +++ llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp Thu Jan 6 22:58:58 2011 @@ -9,7 +9,7 @@ // // This pass assigns local frame indices to stack slots relative to one another // and allocates additional base registers to access them when the target -// estimates the are likely to be out of range of stack pointer and frame +// estimates they are likely to be out of range of stack pointer and frame // pointer relative addressing. // //===----------------------------------------------------------------------===// From bob.wilson at apple.com Thu Jan 6 22:59:04 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 07 Jan 2011 04:59:04 -0000 Subject: [llvm-commits] [llvm] r122995 - in /llvm/trunk: include/llvm/Target/TargetSelectionDAG.td lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMInstrNEON.td test/CodeGen/ARM/spill-q.ll test/CodeGen/Thumb2/thumb2-spill-q.ll Message-ID: <20110107045904.BF43E2A6C12C@llvm.org> Author: bwilson Date: Thu Jan 6 22:59:04 2011 New Revision: 122995 URL: http://llvm.org/viewvc/llvm-project?rev=122995&view=rev Log: Add ARM patterns to match EXTRACT_SUBVECTOR nodes. Also fix an off-by-one in SelectionDAGBuilder that was preventing shuffle vectors from being translated to EXTRACT_SUBVECTOR. Patch by Tim Northover. The test changes are needed to keep those spill-q tests from testing aligned spills and restores. If the only aligned stack objects are spill slots, we no longer realign the stack frame. Prior to this patch, an EXTRACT_SUBVECTOR was legalized by loading from the stack, which created an aligned frame index. Now, however, there is nothing except the spill slot in the stack frame, so I added an aligned alloca. Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMInstrNEON.td llvm/trunk/test/CodeGen/ARM/spill-q.ll llvm/trunk/test/CodeGen/Thumb2/thumb2-spill-q.ll Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=122995&r1=122994&r2=122995&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td (original) +++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Thu Jan 6 22:59:04 2011 @@ -421,6 +421,9 @@ []>; def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>; +def vector_extract_subvec : SDNode<"ISD::EXTRACT_SUBVECTOR", + SDTypeProfile<1, 2, [SDTCisInt<2>, SDTCisVec<1>, SDTCisVec<0>]>, + []>; def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT", SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=122995&r1=122994&r2=122995&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu Jan 6 22:59:04 2011 @@ -2745,7 +2745,7 @@ } else { StartIdx[Input] = (MinRange[Input]/MaskNumElts)*MaskNumElts; if (MaxRange[Input] - StartIdx[Input] < (int)MaskNumElts && - StartIdx[Input] + MaskNumElts < SrcNumElts) + StartIdx[Input] + MaskNumElts <= SrcNumElts) RangeUse[Input] = 1; // Extract from a multiple of the mask length. } } Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=122995&r1=122994&r2=122995&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu Jan 6 22:59:04 2011 @@ -94,7 +94,7 @@ setOperationAction(ISD::BUILD_VECTOR, VT.getSimpleVT(), Custom); setOperationAction(ISD::VECTOR_SHUFFLE, VT.getSimpleVT(), Custom); setOperationAction(ISD::CONCAT_VECTORS, VT.getSimpleVT(), Legal); - setOperationAction(ISD::EXTRACT_SUBVECTOR, VT.getSimpleVT(), Expand); + setOperationAction(ISD::EXTRACT_SUBVECTOR, VT.getSimpleVT(), Legal); setOperationAction(ISD::SELECT, VT.getSimpleVT(), Expand); setOperationAction(ISD::SELECT_CC, VT.getSimpleVT(), Expand); if (VT.isInteger()) { Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=122995&r1=122994&r2=122995&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Thu Jan 6 22:59:04 2011 @@ -4530,6 +4530,23 @@ // Other Vector Shuffles. +// Aligned extractions: really just dropping registers + +class AlignedVEXTq + : Pat<(DestTy (vector_extract_subvec (SrcTy QPR:$src), (i32 imm:$start))), + (EXTRACT_SUBREG (SrcTy QPR:$src), (LaneCVT imm:$start))>; + +def : AlignedVEXTq; + +def : AlignedVEXTq; + +def : AlignedVEXTq; + +def : AlignedVEXTq; + +def : AlignedVEXTq; + + // VEXT : Vector Extract class VEXTd Modified: llvm/trunk/test/CodeGen/ARM/spill-q.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/spill-q.ll?rev=122995&r1=122994&r2=122995&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/spill-q.ll (original) +++ llvm/trunk/test/CodeGen/ARM/spill-q.ll Thu Jan 6 22:59:04 2011 @@ -15,7 +15,10 @@ ; CHECK: vst1.64 {{.*}}sp, :128 ; CHECK: vld1.64 {{.*}}sp, :128 entry: - %0 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind ; <<4 x float>> [#uses=1] + %aligned_vec = alloca <4 x float>, align 16 + %"alloca point" = bitcast i32 0 to i32 + %vecptr = bitcast <4 x float>* %aligned_vec to i8* + %0 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* %vecptr, i32 1) nounwind ; <<4 x float>> [#uses=1] store float 6.300000e+01, float* undef, align 4 %1 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind ; <<4 x float>> [#uses=1] store float 0.000000e+00, float* undef, align 4 Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-spill-q.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-spill-q.ll?rev=122995&r1=122994&r2=122995&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/thumb2-spill-q.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/thumb2-spill-q.ll Thu Jan 6 22:59:04 2011 @@ -15,7 +15,10 @@ ; CHECK: vst1.64 {{.*}}[{{.*}}, :128] ; CHECK: vld1.64 {{.*}}[{{.*}}, :128] entry: - %0 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind ; <<4 x float>> [#uses=1] + %aligned_vec = alloca <4 x float>, align 16 + %"alloca point" = bitcast i32 0 to i32 + %vecptr = bitcast <4 x float>* %aligned_vec to i8* + %0 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* %vecptr, i32 1) nounwind store float 6.300000e+01, float* undef, align 4 %1 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind ; <<4 x float>> [#uses=1] store float 0.000000e+00, float* undef, align 4 From bob.wilson at apple.com Fri Jan 7 00:44:15 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 07 Jan 2011 06:44:15 -0000 Subject: [llvm-commits] [llvm] r122997 - /llvm/trunk/test/CodeGen/ARM/vcombine.ll Message-ID: <20110107064415.20A4D2A6C12C@llvm.org> Author: bwilson Date: Fri Jan 7 00:44:14 2011 New Revision: 122997 URL: http://llvm.org/viewvc/llvm-project?rev=122997&view=rev Log: Add testcases for PR8411 (vget_low and vget_high implemented as shuffles). Modified: llvm/trunk/test/CodeGen/ARM/vcombine.ll Modified: llvm/trunk/test/CodeGen/ARM/vcombine.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vcombine.ll?rev=122997&r1=122996&r2=122997&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vcombine.ll (original) +++ llvm/trunk/test/CodeGen/ARM/vcombine.ll Fri Jan 7 00:44:14 2011 @@ -1,6 +1,9 @@ -; RUN: llc < %s -march=arm -mattr=+neon +; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s define <16 x i8> @vcombine8(<8 x i8>* %A, <8 x i8>* %B) nounwind { +; CHECK: vcombine8 +; CHECK: vmov r0, r1, d16 +; CHECK: vmov r2, r3, d17 %tmp1 = load <8 x i8>* %A %tmp2 = load <8 x i8>* %B %tmp3 = shufflevector <8 x i8> %tmp1, <8 x i8> %tmp2, <16 x i32> @@ -8,6 +11,9 @@ } define <8 x i16> @vcombine16(<4 x i16>* %A, <4 x i16>* %B) nounwind { +; CHECK: vcombine16 +; CHECK: vmov r0, r1, d16 +; CHECK: vmov r2, r3, d17 %tmp1 = load <4 x i16>* %A %tmp2 = load <4 x i16>* %B %tmp3 = shufflevector <4 x i16> %tmp1, <4 x i16> %tmp2, <8 x i32> @@ -15,6 +21,9 @@ } define <4 x i32> @vcombine32(<2 x i32>* %A, <2 x i32>* %B) nounwind { +; CHECK: vcombine32 +; CHECK: vmov r0, r1, d16 +; CHECK: vmov r2, r3, d17 %tmp1 = load <2 x i32>* %A %tmp2 = load <2 x i32>* %B %tmp3 = shufflevector <2 x i32> %tmp1, <2 x i32> %tmp2, <4 x i32> @@ -22,6 +31,9 @@ } define <4 x float> @vcombinefloat(<2 x float>* %A, <2 x float>* %B) nounwind { +; CHECK: vcombinefloat +; CHECK: vmov r0, r1, d16 +; CHECK: vmov r2, r3, d17 %tmp1 = load <2 x float>* %A %tmp2 = load <2 x float>* %B %tmp3 = shufflevector <2 x float> %tmp1, <2 x float> %tmp2, <4 x i32> @@ -29,8 +41,32 @@ } define <2 x i64> @vcombine64(<1 x i64>* %A, <1 x i64>* %B) nounwind { +; CHECK: vcombine64 +; CHECK: vmov r0, r1, d16 +; CHECK: vmov r2, r3, d17 %tmp1 = load <1 x i64>* %A %tmp2 = load <1 x i64>* %B %tmp3 = shufflevector <1 x i64> %tmp1, <1 x i64> %tmp2, <2 x i32> ret <2 x i64> %tmp3 } + +; Check for vget_low and vget_high implemented with shufflevector. PR8411. +; They should not require storing to the stack. + +define <4 x i16> @vget_low16(<8 x i16>* %A) nounwind { +; CHECK: vget_low16 +; CHECK-NOT: vst +; CHECK: vmov r0, r1, d16 + %tmp1 = load <8 x i16>* %A + %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <4 x i32> + ret <4 x i16> %tmp2 +} + +define <8 x i8> @vget_high8(<16 x i8>* %A) nounwind { +; CHECK: vget_high8 +; CHECK-NOT: vst +; CHECK: vmov r0, r1, d17 + %tmp1 = load <16 x i8>* %A + %tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <8 x i32> + ret <8 x i8> %tmp2 +} From baldrick at free.fr Fri Jan 7 01:52:59 2011 From: baldrick at free.fr (Duncan Sands) Date: Fri, 07 Jan 2011 08:52:59 +0100 Subject: [llvm-commits] [llvm] r122993 - in /llvm/trunk: include/llvm/CodeGen/ISDOpcodes.h lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp In-Reply-To: <20110107045856.34AB22A6C12C@llvm.org> References: <20110107045856.34AB22A6C12C@llvm.org> Message-ID: <4D26C65B.40104@free.fr> Hi Bob, > Change EXTRACT_SUBVECTOR to require a constant index. how about storing the index as an "int" in the node, rather than using a constant node? Ciao, Duncan. From geek4civic at gmail.com Fri Jan 7 03:10:15 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Fri, 7 Jan 2011 18:10:15 +0900 Subject: [llvm-commits] [llvm] r122945 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: <20110106025642.47BA92A6C12C@llvm.org> References: <20110106025642.47BA92A6C12C@llvm.org> Message-ID: > Author: zwarich > Date: Wed Jan ?5 20:56:42 2011 > New Revision: 122945 FYI, it causes assertion failure (probably) due to miscompilation of gcc-4.4.0 on mingw. > g++.exe (TDM-1 mingw32) 4.4.0 $ llc < test/CodeGen/X86/pr3495.ll > Assertion failed: NumEntries == 0 && "Node count imbalance!", file include/llvm/ADT/DenseMap.h, line 123 Workaround: - Use clang++! (recommended :D ) - Use -O2. (-O3 by default with CMake and -O2 by default with autoconf) - Suppress invoking "OptimizeInlineAsmInst(I, &(*CI), SunkAddrs);" ...Takumi From baldrick at free.fr Fri Jan 7 03:36:25 2011 From: baldrick at free.fr (Duncan Sands) Date: Fri, 07 Jan 2011 09:36:25 -0000 Subject: [llvm-commits] [dragonegg] r122998 - /dragonegg/trunk/www/index.html Message-ID: <20110107093625.155E92A6C12C@llvm.org> Author: baldrick Date: Fri Jan 7 03:36:24 2011 New Revision: 122998 URL: http://llvm.org/viewvc/llvm-project?rev=122998&view=rev Log: Add some more information on building gcc and dragonegg. Fix some validation errors while there. Modified: dragonegg/trunk/www/index.html Modified: dragonegg/trunk/www/index.html URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/www/index.html?rev=122998&r1=122997&r2=122998&view=diff ============================================================================== --- dragonegg/trunk/www/index.html (original) +++ dragonegg/trunk/www/index.html Fri Jan 7 03:36:24 2011 @@ -77,20 +77,19 @@
  8. Fortran programs using common variables now link correctly.
  9. GNU OMP constructs no longer crash the compiler.
  10. -

    Known problems with the DragonEgg-2.8 release:

    • Functions returning complex numbers are not handled in an ABI conformant way. This means for example that if code compiled with dragonegg calls a function in a system library that returns a complex number then you get a bogus result. The fix in - subversion commit 117649 + subversion commit 117649 can be applied to the dragonegg-2.8 source to resolve the problem.
    • Calling floor then converting the result to a long integer type can result in link failures due to an undefined reference to __builtin_lfloor. Likewise for ceil and variants like floorf. The fix in - subversion commit 118499 + subversion commit 118499 can be applied to the dragonegg-2.8 source to resolve the problem.
    • Some OpenMP programs fail to work when compiled without optimization. This has been fixed in the development version of LLVM. Compile at @@ -98,7 +97,7 @@
    • Programs that throw an uncaught exception when there are destructors to be run when unwinding would crash rather than terminating cleanly. The fix in - subversion commit 120096 + subversion commit 120096 can be applied to the dragonegg-2.8 source to resolve the problem.
  11. DragonEgg-2.7 was the first ever DragonEgg release. It works with @@ -220,11 +219,19 @@ source:

    	patch -d gcc-4.5.1 -p1 < dragonegg-2.8/gcc-patches/i386_static.diff

    Build and install gcc-4.5 in the - usual way.

    + usual way, except that you should add the configure options --enable-plugin + and --enable-lto.

    Doing

    -
    	GCC=path_to_just_installed_gcc make
    +
    	GCC=directory_where_gcc_installed/bin/gcc make

    in the dragonegg-2.8 directory should then build dragonegg.so. - See the README file for more details.

    + If you have arranged for the gcc executable to occur in your path with the + name gcc-4.5 (using a symbolic link for example) then there is no + need to set the GCC variable: you can just do "make". + If the LLVM binaries are not in your path then you can use

    +
    	GCC=directory_where_gcc_installed/bin/gcc LLVM_CONFIG=directory_where_llvm_installed/bin/llvm-config make
    +

    If you only built LLVM and did not install it then you can still build + dragonegg by setting LLVM_CONFIG to point to the copy of llvm-config in the + build tree.

    To use dragonegg.so, compile something with your just-installed version of gcc, adding -fplugin=path_to_dragonegg/dragonegg.so to the command line. See the README file for more details and useful From kalle.raiskila at nokia.com Fri Jan 7 03:39:26 2011 From: kalle.raiskila at nokia.com (Kalle Raiskila) Date: Fri, 07 Jan 2011 11:39:26 +0200 Subject: [llvm-commits] [PATCH] Remove unused variables found by gcc-4.6's -Wunused-but-set-variable (issue3827044) In-Reply-To: <20cf30549f43ed8e62049936bde4@google.com> References: <20cf30549f43ed8e62049936bde4@google.com> Message-ID: <4D26DF4E.7080905@nokia.com> ext jyasskin at gmail.com skrev: > Reviewers: , > > Description: > Some of these removals may actually indicate bugs, so someone who knows > this code better than I do should take a look. > > There are a couple other gcc-4.6 warnings in googletest, but we should > get a fix for them when they release version 1.6. > > Please review this at http://codereview.appspot.com/3827044/ > > Affected files: > M lib/Target/ARM/ARMFastISel.cpp > M lib/Target/ARM/ARMFrameInfo.cpp > M lib/Target/CellSPU/SPUISelLowering.cpp Those unused in the CellSPU target are OK to remove. (sorry, don't have an account to appspot) thanks, kalle From anton at korobeynikov.info Fri Jan 7 03:51:45 2011 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Fri, 7 Jan 2011 12:51:45 +0300 Subject: [llvm-commits] [llvm] r122945 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: References: <20110106025642.47BA92A6C12C@llvm.org> Message-ID: > ?- Use clang++! (recommended :D ) > ?- Use -O2. (-O3 by default with CMake and -O2 by default with autoconf) Yes, numerous miscompilations was the reason why O2 was forced on mingw32. CMake should do the same. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From benny.kra at googlemail.com Fri Jan 7 05:35:21 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 07 Jan 2011 11:35:21 -0000 Subject: [llvm-commits] [llvm] r122999 - /llvm/trunk/test/CodeGen/X86/memset-2.ll Message-ID: <20110107113521.CB2982A6C12C@llvm.org> Author: d0k Date: Fri Jan 7 05:35:21 2011 New Revision: 122999 URL: http://llvm.org/viewvc/llvm-project?rev=122999&view=rev Log: Try to unbreak the arm buildbot. Modified: llvm/trunk/test/CodeGen/X86/memset-2.ll Modified: llvm/trunk/test/CodeGen/X86/memset-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memset-2.ll?rev=122999&r1=122998&r2=122999&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memset-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/memset-2.ll Fri Jan 7 05:35:21 2011 @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=i386-apple-darwin < %s | FileCheck %s +; RUN: llc -mtriple=i386-apple-darwin -mcpu=yonah < %s | FileCheck %s declare void @llvm.memset.i32(i8*, i8, i32, i32) nounwind From jay.foad at gmail.com Fri Jan 7 06:50:43 2011 From: jay.foad at gmail.com (Jay Foad) Date: Fri, 7 Jan 2011 12:50:43 +0000 Subject: [llvm-commits] [PATCH] remove BranchInst::setUnconditionalDest() Message-ID: These patches fix a FIXME in BranchInst::setUnconditionalDest(): // setUnconditionalDest - Change the current branch to an unconditional branch // targeting the specified block. // FIXME: Eliminate this ugly method. This means that BranchInsts are now created with either 1 or 3 operands, and that never changes over the lifetime of the BranchInst. This allows some nice cleanups in the allocation and freeing of Users' operand lists. (The complexity was originally introduced when Gabor changed BranchInst to allocate its operands along with the instruction, instead of as a separate allocation, here: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20090309/075152.html ) The patches are, in order: remove-uses: change the existing uses of setUnconditionalDest() to create a new unconditional BranchInst instead remove-impl: remove the implementation of setUnconditionalDest() cleanup-operandlist: the cleanups mentioned above I've tested them all with "make all check". Comments? Or, OK to commit? Thanks, Jay. -------------- next part -------------- A non-text attachment was scrubbed... Name: remove-uses Type: application/octet-stream Size: 1903 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110107/c5a22d5d/attachment.obj -------------- next part -------------- A non-text attachment was scrubbed... Name: remove-impl Type: application/octet-stream Size: 1655 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110107/c5a22d5d/attachment-0001.obj -------------- next part -------------- A non-text attachment was scrubbed... Name: cleanup-operandlist Type: application/octet-stream Size: 5995 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110107/c5a22d5d/attachment-0002.obj From grosser at fim.uni-passau.de Fri Jan 7 08:58:11 2011 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Fri, 07 Jan 2011 09:58:11 -0500 Subject: [llvm-commits] [PATCH] Fix: instcombine does not get max if hidden by sext In-Reply-To: References: <4D22A780.6060209@fim.uni-passau.de> <48360275-C1A1-4AB1-A1A2-F5609C52094B@apple.com> Message-ID: <4D272A03.5030008@fim.uni-passau.de> On 01/06/2011 05:49 AM, Frits van Bommel wrote: > On Thu, Jan 6, 2011 at 7:49 AM, Chris Lattner wrote: >> On Jan 3, 2011, at 8:52 PM, Tobias Grosser wrote: >>> I fixed a recent bug report, that blocked me on a large FORTRAN test case: >>> >>> InstCombine: >>> X = sext x ; x< c ? X : C-1 >>> --> >>> X = sext x; X> C-1 ? C-1 : X >>> >>> Instead of calculating this with mixed types promote all to the >>> larger type. This enables scalar evolution to analyze this >>> expression. PR8866 > > Why only for sext and not zext? Does scalar evolution understand those > well enough that it's not needed there or was it just not useful for > your particular test case? > Or maybe the zext case is too different from the sext case to add easily? I wanted to check first if the approach I took was OK. The new version contains also zext support. >> Generally, the logic involved is complex enough that it is probably best to pull it out into a static helper function. This should make it easier to read. > > And since the "less than" and "greater than" cases seem to be quite > similar, you could try to use a single helper function for both. They are exactly the same except of the -1/+1 at the beginning. I moved this difference into an if condition and use the same code for the rest. > Is the fallthrough at the end of the "less than" case intentional? If > so, a big '// FALLTHROUGH' would probably be helpful. If not, add a > 'break', obviously. Either way, adding one at the end of the "greater > than" case would future-proof it in case anyone adds extra cases. No, it was not intentionally. Fixed. Attached is the new version. Thanks for your help Tobi -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-InstCombine-Match-min-max-hidden-by-sext-zext.patch Type: text/x-diff Size: 7630 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110107/2d0fa5ed/attachment.bin From Tim.Northover at arm.com Fri Jan 7 09:16:51 2011 From: Tim.Northover at arm.com (Tim Northover) Date: Fri, 7 Jan 2011 15:16:51 +0000 Subject: [llvm-commits] shufflevector on ARM (clumsy x-post from llvmdev) In-Reply-To: References: Message-ID: <4D272E63.7070605@arm.com> On 07/01/11 07:28, Bob Wilson wrote: > The extract_subvector patch looks good, except for the testsuite > changes. Those tests are supposed to test spill code, and your patch > causes them to stop spilling. I'll commit the patch after I fix the > tests to continue spilling in spite of your change. Ah thanks. I'd convinced myself it was spilling, just slightly differently. Glad you picked that up. > The build_vector patch looks good, too. Can you also provide some tests > that exercise this? (The test/CodeGen/ARM/vext.ll file would be a good > place to put them.) Yep, I've uploaded the replacement to http://www.maths.ed.ac.uk/~s0677366/build_vector_r2.patch It incorporates your comments and some tests that I believe exercise most of the code (some is just there in case weird lowering creates something unexpected and I can't actually produce an example). > The loop below would be a good candidate for splitting into a separate > function, except that it would need quite a few arguments. Maybe this > entire new chunk of new code could be a separate function (if that would > be cleaner)? I would prefer that, if it's not too awkward. The > LowerBUILD_VECTOR function is already getting pretty long and it makes > it hard to follow the logic. Good suggestion, I've moved all the code into a separate function and I think the control flow is rather simpler as a result. > This new code will apply to <4 x i32> vectors. The following code to > implement the BUILD_VECTOR by directly assigning subregisters will also > handle that case.Have you looked at which is better? It might be better > to swap the order of these. I suppose accessing S subregisters can be > slow since the move instructions will run in the VFP pipeline and cause > stalls on some processors I hadn't thought of anything so cunning. If both pieces of code apply then the result is <4 x i32> and both source vectors are <4 x i32> as well (if <2 x i32> I bail). I think this means that the result of my code would be identical to a perfect shuffle with no added overhead (no VEXTs). So assuming that perfect shuffles are indeed handled optimally the order I gave happens to be correct. More by luck than judgement. Let me know if you disagree or have more suggestions. Tim. P.S. Sorry if this gets through twice, I'm still rather uncertain about attachments on these lists and suspect my first attempt was black-holed. -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. From fvbommel at gmail.com Fri Jan 7 10:01:03 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Fri, 7 Jan 2011 17:01:03 +0100 Subject: [llvm-commits] [PATCH] Fix: instcombine does not get max if hidden by sext In-Reply-To: <4D272A03.5030008@fim.uni-passau.de> References: <4D22A780.6060209@fim.uni-passau.de> <48360275-C1A1-4AB1-A1A2-F5609C52094B@apple.com> <4D272A03.5030008@fim.uni-passau.de> Message-ID: On Fri, Jan 7, 2011 at 3:58 PM, Tobias Grosser wrote: > On 01/06/2011 05:49 AM, Frits van Bommel wrote: >> >> On Thu, Jan 6, 2011 at 7:49 AM, Chris Lattner ?wrote: >>> >>> On Jan 3, 2011, at 8:52 PM, Tobias Grosser wrote: >>>> >>>> I fixed a recent bug report, that blocked me on a large FORTRAN test >>>> case: >>>> >>>> ? ?InstCombine: >>>> ? ?X = sext x ; x< ?c ? X : C-1 >>>> ? ?--> >>>> ? ?X = sext x; X> ?C-1 ? C-1 : X >>>> >>>> ? ?Instead of calculating this with mixed types promote all to the >>>> ? ?larger type. This enables scalar evolution to analyze this >>>> ? ?expression. PR8866 >> >> Why only for sext and not zext? Does scalar evolution understand those >> well enough that it's not needed there or was it just not useful for >> your particular test case? >> Or maybe the zext case is too different from the sext case to add easily? > > I wanted to check first if the approach I took was OK. The new version > contains also zext support. > Attached is the new version. switch (Pred) { default: break; - case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_SLT: { // X < MIN ? T : F --> F - if (CI->isMinValue(Pred == ICmpInst::ICMP_SLT)) + if (CI->isMinValue(true /* signed */)) return ReplaceInstUsesWith(SI, FalseVal); ... break; } - case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_SGT: { // X > MAX ? T : F --> F - if (CI->isMaxValue(Pred == ICmpInst::ICMP_SGT)) + if (CI->isMaxValue(true /* signed */)) return ReplaceInstUsesWith(SI, FalseVal); + break; + } Why not do this for the unsigned cases anymore? X u -1. Also, this switch might be cleaner as an if/else if but that's perhaps a matter of taste. + // X = sext x; x >s c ? X : C+1 --> X = sext x; X X = sext x; X >s C-1 ? C-1 : X + if (Pred == ICI->getSignedPredicate()) { You can use ICI->isSigned() or (I)CmpInst::isSigned(Pred) here. I also noticed that you're no longer handling the sext + unsigned compare case. I know it's kind of counter-intuitive, but when I was examining the original patch I tried to find a case where it was wrong but couldn't find one. For instance, for x =s 0, (sext x) and (sext y) are still the same relative values when interpreted as unsigned (just with possibly some 1s prepended) so the result of x =s 0, x =s 0 and y u y. The same doesn't hold for zext + signed compare, by the way. For instance, 0xff s 0x0000. From greened at obbligato.org Fri Jan 7 11:05:38 2011 From: greened at obbligato.org (David Greene) Date: Fri, 07 Jan 2011 17:05:38 -0000 Subject: [llvm-commits] [llvm] r123001 - in /llvm/trunk: docs/TableGenFundamentals.html test/TableGen/ListManip.td test/TableGen/Slice.td test/TableGen/if.td test/TableGen/lisp.td utils/TableGen/Record.cpp utils/TableGen/Record.h utils/TableGen/TGLexer.cpp utils/TableGen/TGLexer.h utils/TableGen/TGParser.cpp Message-ID: <20110107170538.3B8342A6C12C@llvm.org> Author: greened Date: Fri Jan 7 11:05:37 2011 New Revision: 123001 URL: http://llvm.org/viewvc/llvm-project?rev=123001&view=rev Log: Rename lisp-like functions as suggested by Gabor Greif as loooong time ago. This is both easier to learn and easier to read. Modified: llvm/trunk/docs/TableGenFundamentals.html llvm/trunk/test/TableGen/ListManip.td llvm/trunk/test/TableGen/Slice.td llvm/trunk/test/TableGen/if.td llvm/trunk/test/TableGen/lisp.td llvm/trunk/utils/TableGen/Record.cpp llvm/trunk/utils/TableGen/Record.h llvm/trunk/utils/TableGen/TGLexer.cpp llvm/trunk/utils/TableGen/TGLexer.h llvm/trunk/utils/TableGen/TGParser.cpp Modified: llvm/trunk/docs/TableGenFundamentals.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TableGenFundamentals.html?rev=123001&r1=123000&r2=123001&view=diff ============================================================================== --- llvm/trunk/docs/TableGenFundamentals.html (original) +++ llvm/trunk/docs/TableGenFundamentals.html Fri Jan 7 11:05:37 2011 @@ -412,11 +412,11 @@

    For each member 'b' of dag or list 'a' apply operator 'c.' 'b' is a dummy variable that should be declared as a member variable of an instantiated class. This operation is analogous to $(foreach) in GNU make.
    -
    !car(a)
    +
    !head(a)
    The first element of list 'a.'
    -
    !cdr(a)
    +
    !tail(a)
    The 2nd-N elements of list 'a.'
    -
    !null(a)
    +
    !empty(a)
    An integer {0,1} indicating whether list 'a' is empty.
    !if(a,b,c)
    'b' if the result of 'int' or 'bit' operator 'a' is nonzero, Modified: llvm/trunk/test/TableGen/ListManip.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/ListManip.td?rev=123001&r1=123000&r2=123001&view=diff ============================================================================== --- llvm/trunk/test/TableGen/ListManip.td (original) +++ llvm/trunk/test/TableGen/ListManip.td Fri Jan 7 11:05:37 2011 @@ -7,6 +7,6 @@ } class Bla _bli> -: Bli +: Bli { } Modified: llvm/trunk/test/TableGen/Slice.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/Slice.td?rev=123001&r1=123000&r2=123001&view=diff ============================================================================== --- llvm/trunk/test/TableGen/Slice.td (original) +++ llvm/trunk/test/TableGen/Slice.td Fri Jan 7 11:05:37 2011 @@ -66,19 +66,19 @@ multiclass scalar opcode, string asmstr = "", list> patterns = []> { def SSrr : Inst,patterns[0])>; + !if(!empty(patterns),[],patterns[0])>; def SSrm : Inst,!if(!null(!cdr(patterns)),patterns[0],patterns[1]))>; + !if(!empty(patterns),[],!if(!empty(!tail(patterns)),patterns[0],patterns[1]))>; } multiclass vscalar opcode, string asmstr = "", list> patterns = []> { def V#NAME#SSrr : Inst,patterns[0])>; + !if(!empty(patterns),[],patterns[0])>; def V#NAME#SSrm : Inst,!if(!null(!cdr(patterns)),patterns[0],patterns[1]))>; + !if(!empty(patterns),[],!if(!empty(!tail(patterns)),patterns[0],patterns[1]))>; } multiclass myscalar opcode, string asmstr = "", list> patterns = []> : Modified: llvm/trunk/test/TableGen/if.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/if.td?rev=123001&r1=123000&r2=123001&view=diff ============================================================================== --- llvm/trunk/test/TableGen/if.td (original) +++ llvm/trunk/test/TableGen/if.td Fri Jan 7 11:05:37 2011 @@ -28,7 +28,7 @@ class A> vals> { list first = vals[0]; - list rest = !if(!null(!cdr(vals)), vals[0], vals[1]); + list rest = !if(!empty(!tail(vals)), vals[0], vals[1]); } def One : A<[[1,2,3]]>; @@ -38,7 +38,7 @@ list vals = v; } -class BB> vals> : B; +class BB> vals> : B; class BBB> vals> : BB; def OneB : BBB<[[1,2,3]]>; Modified: llvm/trunk/test/TableGen/lisp.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/lisp.td?rev=123001&r1=123000&r2=123001&view=diff ============================================================================== --- llvm/trunk/test/TableGen/lisp.td (original) +++ llvm/trunk/test/TableGen/lisp.td Fri Jan 7 11:05:37 2011 @@ -15,7 +15,7 @@ } class NameList Names> : - List, CAR, CDR; + List, CAR, CDR; def Three : NameList<["Tom", "Dick", "Harry"]>; Modified: llvm/trunk/utils/TableGen/Record.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.cpp?rev=123001&r1=123000&r2=123001&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/Record.cpp (original) +++ llvm/trunk/utils/TableGen/Record.cpp Fri Jan 7 11:05:37 2011 @@ -590,7 +590,7 @@ } break; } - case CAR: { + case HEAD: { ListInit *LHSl = dynamic_cast(LHS); if (LHSl) { if (LHSl->getSize() == 0) { @@ -601,7 +601,7 @@ } break; } - case CDR: { + case TAIL: { ListInit *LHSl = dynamic_cast(LHS); if (LHSl) { if (LHSl->getSize() == 0) { @@ -614,7 +614,7 @@ } break; } - case LNULL: { + case EMPTY: { ListInit *LHSl = dynamic_cast(LHS); if (LHSl) { if (LHSl->getSize() == 0) { @@ -650,9 +650,9 @@ std::string Result; switch (Opc) { case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break; - case CAR: Result = "!car"; break; - case CDR: Result = "!cdr"; break; - case LNULL: Result = "!null"; break; + case HEAD: Result = "!head"; break; + case TAIL: Result = "!tail"; break; + case EMPTY: Result = "!empty"; break; } return Result + "(" + LHS->getAsString() + ")"; } Modified: llvm/trunk/utils/TableGen/Record.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.h?rev=123001&r1=123000&r2=123001&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/Record.h (original) +++ llvm/trunk/utils/TableGen/Record.h Fri Jan 7 11:05:37 2011 @@ -811,7 +811,7 @@ /// class UnOpInit : public OpInit { public: - enum UnaryOp { CAST, CAR, CDR, LNULL }; + enum UnaryOp { CAST, HEAD, TAIL, EMPTY }; private: UnaryOp Opc; Init *LHS; Modified: llvm/trunk/utils/TableGen/TGLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=123001&r1=123000&r2=123001&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGLexer.cpp (original) +++ llvm/trunk/utils/TableGen/TGLexer.cpp Fri Jan 7 11:05:37 2011 @@ -424,14 +424,14 @@ StringSwitch(StringRef(Start, CurPtr - Start)) .Case("eq", tgtok::XEq) .Case("if", tgtok::XIf) - .Case("car", tgtok::XCar) - .Case("cdr", tgtok::XCdr) + .Case("head", tgtok::XHead) + .Case("tail", tgtok::XTail) .Case("con", tgtok::XConcat) .Case("shl", tgtok::XSHL) .Case("sra", tgtok::XSRA) .Case("srl", tgtok::XSRL) .Case("cast", tgtok::XCast) - .Case("null", tgtok::XNull) + .Case("empty", tgtok::XEmpty) .Case("subst", tgtok::XSubst) .Case("foreach", tgtok::XForEach) .Case("strconcat", tgtok::XStrConcat) Modified: llvm/trunk/utils/TableGen/TGLexer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.h?rev=123001&r1=123000&r2=123001&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGLexer.h (original) +++ llvm/trunk/utils/TableGen/TGLexer.h Fri Jan 7 11:05:37 2011 @@ -46,7 +46,7 @@ // !keywords. XConcat, XSRA, XSRL, XSHL, XStrConcat, XCast, XSubst, - XForEach, XCar, XCdr, XNull, XIf, XEq, + XForEach, XHead, XTail, XEmpty, XIf, XEq, // Integer value. IntVal, Modified: llvm/trunk/utils/TableGen/TGParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.cpp?rev=123001&r1=123000&r2=123001&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGParser.cpp (original) +++ llvm/trunk/utils/TableGen/TGParser.cpp Fri Jan 7 11:05:37 2011 @@ -683,9 +683,9 @@ TokError("unknown operation"); return 0; break; - case tgtok::XCar: - case tgtok::XCdr: - case tgtok::XNull: + case tgtok::XHead: + case tgtok::XTail: + case tgtok::XEmpty: case tgtok::XCast: { // Value ::= !unop '(' Value ')' UnOpInit::UnaryOp Code; RecTy *Type = 0; @@ -704,17 +704,17 @@ } break; - case tgtok::XCar: + case tgtok::XHead: Lex.Lex(); // eat the operation - Code = UnOpInit::CAR; + Code = UnOpInit::HEAD; break; - case tgtok::XCdr: + case tgtok::XTail: Lex.Lex(); // eat the operation - Code = UnOpInit::CDR; + Code = UnOpInit::TAIL; break; - case tgtok::XNull: + case tgtok::XEmpty: Lex.Lex(); // eat the operation - Code = UnOpInit::LNULL; + Code = UnOpInit::EMPTY; Type = new IntRecTy; break; } @@ -727,9 +727,9 @@ Init *LHS = ParseValue(CurRec); if (LHS == 0) return 0; - if (Code == UnOpInit::CAR - || Code == UnOpInit::CDR - || Code == UnOpInit::LNULL) { + if (Code == UnOpInit::HEAD + || Code == UnOpInit::TAIL + || Code == UnOpInit::EMPTY) { ListInit *LHSl = dynamic_cast(LHS); StringInit *LHSs = dynamic_cast(LHS); TypedInit *LHSt = dynamic_cast(LHS); @@ -746,8 +746,8 @@ } } - if (Code == UnOpInit::CAR - || Code == UnOpInit::CDR) { + if (Code == UnOpInit::HEAD + || Code == UnOpInit::TAIL) { if (LHSl == 0 && LHSt == 0) { TokError("expected list type argumnet in unary operator"); return 0; @@ -764,7 +764,7 @@ TokError("untyped list element in unary operator"); return 0; } - if (Code == UnOpInit::CAR) { + if (Code == UnOpInit::HEAD) { Type = Itemt->getType(); } else { Type = new ListRecTy(Itemt->getType()); @@ -776,7 +776,7 @@ TokError("expected list type argumnet in unary operator"); return 0; } - if (Code == UnOpInit::CAR) { + if (Code == UnOpInit::HEAD) { Type = LType->getElementType(); } else { Type = LType; @@ -1273,9 +1273,9 @@ return new DagInit(Operator, OperatorName, DagArgs); } - case tgtok::XCar: - case tgtok::XCdr: - case tgtok::XNull: + case tgtok::XHead: + case tgtok::XTail: + case tgtok::XEmpty: case tgtok::XCast: // Value ::= !unop '(' Value ')' case tgtok::XConcat: case tgtok::XSRA: From clattner at apple.com Fri Jan 7 12:46:48 2011 From: clattner at apple.com (Chris Lattner) Date: Fri, 7 Jan 2011 10:46:48 -0800 Subject: [llvm-commits] [llvm] r123001 - in /llvm/trunk: docs/TableGenFundamentals.html test/TableGen/ListManip.td test/TableGen/Slice.td test/TableGen/if.td test/TableGen/lisp.td utils/TableGen/Record.cpp utils/TableGen/Record.h utils/TableGen/TGLexer.cpp utils/TableGen/TGLexer.h utils/TableGen/TGParser.cpp In-Reply-To: <20110107170538.3B8342A6C12C@llvm.org> References: <20110107170538.3B8342A6C12C@llvm.org> Message-ID: <4B5960BE-EA9F-442C-AB0B-0EA2EB676802@apple.com> On Jan 7, 2011, at 9:05 AM, David Greene wrote: > Author: greened > Date: Fri Jan 7 11:05:37 2011 > New Revision: 123001 > > URL: http://llvm.org/viewvc/llvm-project?rev=123001&view=rev > Log: > > Rename lisp-like functions as suggested by Gabor Greif as loooong time > ago. This is both easier to learn and easier to read. Nice, thanks! -Chris From clattner at apple.com Fri Jan 7 12:48:52 2011 From: clattner at apple.com (Chris Lattner) Date: Fri, 7 Jan 2011 10:48:52 -0800 Subject: [llvm-commits] [PATCH] remove BranchInst::setUnconditionalDest() In-Reply-To: References: Message-ID: On Jan 7, 2011, at 4:50 AM, Jay Foad wrote: > > The patches are, in order: > > remove-uses: change the existing uses of setUnconditionalDest() to > create a new unconditional BranchInst instead > remove-impl: remove the implementation of setUnconditionalDest() > cleanup-operandlist: the cleanups mentioned above > > I've tested them all with "make all check". > > Comments? Or, OK to commit? Very very nice, please commit! From kledzik at apple.com Fri Jan 7 13:09:06 2011 From: kledzik at apple.com (Nick Kledzik) Date: Fri, 07 Jan 2011 19:09:06 -0000 Subject: [llvm-commits] [compiler-rt] r123006 - /compiler-rt/trunk/lib/int_lib.h Message-ID: <20110107190906.8CDFE2A6C12D@llvm.org> Author: kledzik Date: Fri Jan 7 13:09:06 2011 New Revision: 123006 URL: http://llvm.org/viewvc/llvm-project?rev=123006&view=rev Log: Add missing to build properly on Solaris. Patch by Joakim Johansson Modified: compiler-rt/trunk/lib/int_lib.h Modified: compiler-rt/trunk/lib/int_lib.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/int_lib.h?rev=123006&r1=123005&r2=123006&view=diff ============================================================================== --- compiler-rt/trunk/lib/int_lib.h (original) +++ compiler-rt/trunk/lib/int_lib.h Fri Jan 7 13:09:06 2011 @@ -20,6 +20,7 @@ /* Assumption: right shift of signed negative is arithmetic shift */ #include +#include #include "endianness.h" #include From evan.cheng at apple.com Fri Jan 7 13:35:30 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 07 Jan 2011 19:35:30 -0000 Subject: [llvm-commits] [llvm] r123015 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/2010-04-08-CoalescerBug.ll test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll test/CodeGen/X86/memcpy-2.ll test/CodeGen/X86/memcpy.ll test/CodeGen/X86/memset-2.ll test/CodeGen/X86/memset64-on-x86-32.ll test/CodeGen/X86/small-byval-memcpy.ll test/CodeGen/X86/tlv-1.ll test/CodeGen/X86/unaligned-load.ll Message-ID: <20110107193531.199272A6C130@llvm.org> Author: evancheng Date: Fri Jan 7 13:35:30 2011 New Revision: 123015 URL: http://llvm.org/viewvc/llvm-project?rev=123015&view=rev Log: Revert r122955. It seems using movups to lower memcpy can cause massive regression (even on Nehalem) in edge cases. I also didn't see any real performance benefit. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/test/CodeGen/X86/2010-04-08-CoalescerBug.ll llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll llvm/trunk/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll llvm/trunk/test/CodeGen/X86/memcpy-2.ll llvm/trunk/test/CodeGen/X86/memcpy.ll llvm/trunk/test/CodeGen/X86/memset-2.ll llvm/trunk/test/CodeGen/X86/memset64-on-x86-32.ll llvm/trunk/test/CodeGen/X86/small-byval-memcpy.ll llvm/trunk/test/CodeGen/X86/tlv-1.ll llvm/trunk/test/CodeGen/X86/unaligned-load.ll Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=123015&r1=123014&r2=123015&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Jan 7 13:35:30 2011 @@ -1063,8 +1063,12 @@ // linux. This is because the stack realignment code can't handle certain // cases like PR2962. This should be removed when PR2962 is fixed. const Function *F = MF.getFunction(); - if (NonScalarIntSafe && !F->hasFnAttr(Attribute::NoImplicitFloat)) { + if (NonScalarIntSafe && + !F->hasFnAttr(Attribute::NoImplicitFloat)) { if (Size >= 16 && + (Subtarget->isUnalignedMemAccessFast() || + ((DstAlign == 0 || DstAlign >= 16) && + (SrcAlign == 0 || SrcAlign >= 16))) && Subtarget->getStackAlignment() >= 16) { if (Subtarget->hasSSE2()) return MVT::v4i32; Modified: llvm/trunk/test/CodeGen/X86/2010-04-08-CoalescerBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-04-08-CoalescerBug.ll?rev=123015&r1=123014&r2=123015&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-04-08-CoalescerBug.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-04-08-CoalescerBug.ll Fri Jan 7 13:35:30 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s ; rdar://7842028 ; Do not delete partially dead copy instructions. @@ -9,7 +9,7 @@ %struct.F = type { %struct.FC*, i32, i32, i8, i32, i32, i32 } %struct.FC = type { [10 x i8], [32 x i32], %struct.FC*, i32 } -define void @t(%struct.F* %this) nounwind optsize { +define void @t(%struct.F* %this) nounwind { entry: ; CHECK: t: ; CHECK: addq $12, %rsi Modified: llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll?rev=123015&r1=123014&r2=123015&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll Fri Jan 7 13:35:30 2011 @@ -26,7 +26,7 @@ ; CHECK: rep;stosl %tmp5 = bitcast i32* %tmp4 to i8* - call void @llvm.memset.p0i8.i64(i8* %tmp5, i8 0, i64 124, i32 4, i1 false) + call void @llvm.memset.p0i8.i64(i8* %tmp5, i8 0, i64 84, i32 4, i1 false) %tmp6 = getelementptr inbounds %struct.type* %s, i32 0, i32 62 store i32* null, i32** %tmp6, align 8 br label %bb1 Modified: llvm/trunk/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll?rev=123015&r1=123014&r2=123015&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll Fri Jan 7 13:35:30 2011 @@ -19,8 +19,8 @@ } ; CHECK: movq ___stack_chk_guard at GOTPCREL(%rip), %rax -; CHECK: movb 30(%rsp), %cl -; CHECK: movb (%rsp), %dl -; CHECK: movb %dl, (%rsp) -; CHECK: movb %cl, 30(%rsp) +; CHECK: movb 30(%rsp), %dl +; CHECK: movb (%rsp), %sil +; CHECK: movb %sil, (%rsp) +; CHECK: movb %dl, 30(%rsp) ; CHECK: callq ___stack_chk_fail Modified: llvm/trunk/test/CodeGen/X86/memcpy-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memcpy-2.ll?rev=123015&r1=123014&r2=123015&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memcpy-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/memcpy-2.ll Fri Jan 7 13:35:30 2011 @@ -1,4 +1,5 @@ ; RUN: llc < %s -mattr=+sse2 -mtriple=i686-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=SSE2 +; RUN: llc < %s -mattr=+sse,-sse2 -mtriple=i686-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=SSE1 ; RUN: llc < %s -mattr=-sse -mtriple=i686-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=NOSSE ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=X86-64 @@ -14,6 +15,13 @@ ; SSE2: movl $0 ; SSE2: movl $0 +; SSE1: t1: +; SSE1: movaps _.str, %xmm0 +; SSE1: movaps %xmm0 +; SSE1: movb $0 +; SSE1: movl $0 +; SSE1: movl $0 + ; NOSSE: t1: ; NOSSE: movb $0 ; NOSSE: movl $0 @@ -43,6 +51,10 @@ ; SSE2: movaps (%eax), %xmm0 ; SSE2: movaps %xmm0, (%eax) +; SSE1: t2: +; SSE1: movaps (%eax), %xmm0 +; SSE1: movaps %xmm0, (%eax) + ; NOSSE: t2: ; NOSSE: movl ; NOSSE: movl @@ -67,8 +79,22 @@ define void @t3(%struct.s0* nocapture %a, %struct.s0* nocapture %b) nounwind ssp { entry: ; SSE2: t3: -; SSE2: movups (%eax), %xmm0 -; SSE2: movups %xmm0, (%eax) +; SSE2: movsd (%eax), %xmm0 +; SSE2: movsd 8(%eax), %xmm1 +; SSE2: movsd %xmm1, 8(%eax) +; SSE2: movsd %xmm0, (%eax) + +; SSE1: t3: +; SSE1: movl +; SSE1: movl +; SSE1: movl +; SSE1: movl +; SSE1: movl +; SSE1: movl +; SSE1: movl +; SSE1: movl +; SSE1: movl +; SSE1: movl ; NOSSE: t3: ; NOSSE: movl @@ -83,8 +109,10 @@ ; NOSSE: movl ; X86-64: t3: -; X86-64: movups (%rsi), %xmm0 -; X86-64: movups %xmm0, (%rdi) +; X86-64: movq (%rsi), %rax +; X86-64: movq 8(%rsi), %rcx +; X86-64: movq %rcx, 8(%rdi) +; X86-64: movq %rax, (%rdi) %tmp2 = bitcast %struct.s0* %a to i8* ; [#uses=1] %tmp3 = bitcast %struct.s0* %b to i8* ; [#uses=1] tail call void @llvm.memcpy.i32(i8* %tmp2, i8* %tmp3, i32 16, i32 8) @@ -94,12 +122,24 @@ define void @t4() nounwind { entry: ; SSE2: t4: -; SSE2: movups _.str2, %xmm0 -; SSE2: movaps %xmm0, (%esp) -; SSE2: movw $120, 28(%esp) +; SSE2: movw $120 +; SSE2: movl $2021161080 +; SSE2: movl $2021161080 +; SSE2: movl $2021161080 ; SSE2: movl $2021161080 ; SSE2: movl $2021161080 ; SSE2: movl $2021161080 +; SSE2: movl $2021161080 + +; SSE1: t4: +; SSE1: movw $120 +; SSE1: movl $2021161080 +; SSE1: movl $2021161080 +; SSE1: movl $2021161080 +; SSE1: movl $2021161080 +; SSE1: movl $2021161080 +; SSE1: movl $2021161080 +; SSE1: movl $2021161080 ; NOSSE: t4: ; NOSSE: movw $120 @@ -114,8 +154,8 @@ ; X86-64: t4: ; X86-64: movabsq $8680820740569200760, %rax ; X86-64: movq %rax -; X86-64: movups _.str2(%rip), %xmm0 -; X86-64: movaps %xmm0, -40(%rsp) +; X86-64: movq %rax +; X86-64: movq %rax ; X86-64: movw $120 ; X86-64: movl $2021161080 %tmp1 = alloca [30 x i8] Modified: llvm/trunk/test/CodeGen/X86/memcpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memcpy.ll?rev=123015&r1=123014&r2=123015&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memcpy.ll (original) +++ llvm/trunk/test/CodeGen/X86/memcpy.ll Fri Jan 7 13:35:30 2011 @@ -37,34 +37,26 @@ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i32 1, i1 false) ret void ; LINUX: test3: -; LINUX-NOT: memcpy -; LINUX: movups -; LINUX: movups -; LINUX: movups -; LINUX: movups -; LINUX: movups -; LINUX: movups -; LINUX: movups -; LINUX: movups +; LINUX: memcpy ; DARWIN: test3: ; DARWIN-NOT: memcpy -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups -; DARWIN: movups +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq +; DARWIN: movq } ; Large constant memcpy's should be inlined when not optimizing for size. Modified: llvm/trunk/test/CodeGen/X86/memset-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memset-2.ll?rev=123015&r1=123014&r2=123015&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memset-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/memset-2.ll Fri Jan 7 13:35:30 2011 @@ -5,21 +5,7 @@ define fastcc void @t1() nounwind { entry: ; CHECK: t1: -; CHECK: pxor %xmm0, %xmm0 -; CHECK: movups %xmm0, 160 -; CHECK: movups %xmm0, 144 -; CHECK: movups %xmm0, 128 -; CHECK: movups %xmm0, 112 -; CHECK: movups %xmm0, 96 -; CHECK: movups %xmm0, 80 -; CHECK: movups %xmm0, 64 -; CHECK: movups %xmm0, 48 -; CHECK: movups %xmm0, 32 -; CHECK: movups %xmm0, 16 -; CHECK: movups %xmm0, 0 -; CHECK: movl $0, 184 -; CHECK: movl $0, 180 -; CHECK: movl $0, 176 +; CHECK: calll _memset call void @llvm.memset.i32( i8* null, i8 0, i32 188, i32 1 ) nounwind unreachable } Modified: llvm/trunk/test/CodeGen/X86/memset64-on-x86-32.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memset64-on-x86-32.ll?rev=123015&r1=123014&r2=123015&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/memset64-on-x86-32.ll (original) +++ llvm/trunk/test/CodeGen/X86/memset64-on-x86-32.ll Fri Jan 7 13:35:30 2011 @@ -1,5 +1,6 @@ ; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=nehalem | grep movups | count 5 -; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core2 | grep movups | count 5 +; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=core2 | grep movl | count 20 +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core2 | grep movq | count 10 define void @bork() nounwind { entry: Modified: llvm/trunk/test/CodeGen/X86/small-byval-memcpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/small-byval-memcpy.ll?rev=123015&r1=123014&r2=123015&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/small-byval-memcpy.ll (original) +++ llvm/trunk/test/CodeGen/X86/small-byval-memcpy.ll Fri Jan 7 13:35:30 2011 @@ -1,12 +1,8 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=nehalem | FileCheck %s +; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=core2 | grep movsd | count 8 +; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=nehalem | grep movups | count 2 define void @ccosl({ x86_fp80, x86_fp80 }* noalias sret %agg.result, { x86_fp80, x86_fp80 }* byval align 4 %z) nounwind { entry: -; CHECK: ccosl: -; CHECK: movaps -; CHECK: movaps -; CHECK: movups -; CHECK: movups %iz = alloca { x86_fp80, x86_fp80 } ; <{ x86_fp80, x86_fp80 }*> [#uses=3] %tmp1 = getelementptr { x86_fp80, x86_fp80 }* %z, i32 0, i32 1 ; [#uses=1] %tmp2 = load x86_fp80* %tmp1, align 16 ; [#uses=1] Modified: llvm/trunk/test/CodeGen/X86/tlv-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tlv-1.ll?rev=123015&r1=123014&r2=123015&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tlv-1.ll (original) +++ llvm/trunk/test/CodeGen/X86/tlv-1.ll Fri Jan 7 13:35:30 2011 @@ -10,12 +10,8 @@ unreachable ; CHECK: movq _c at TLVP(%rip), %rdi ; CHECK-NEXT: callq *(%rdi) - ; CHECK-NEXT: pxor %xmm0, %xmm0 - ; CHECK-NEXT: movups %xmm0, 32(%rax) - ; CHECK-NEXT: movups %xmm0, 16(%rax) - ; CHECK-NEXT: movups %xmm0, (%rax) - ; CHECK-NEXT: movl $0, 56(%rax) - ; CHECK-NEXT: movq $0, 48(%rax) + ; CHECK-NEXT: movl $0, 56(%rax) + ; CHECK-NEXT: movq $0, 48(%rax) } declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind Modified: llvm/trunk/test/CodeGen/X86/unaligned-load.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/unaligned-load.ll?rev=123015&r1=123014&r2=123015&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/unaligned-load.ll (original) +++ llvm/trunk/test/CodeGen/X86/unaligned-load.ll Fri Jan 7 13:35:30 2011 @@ -1,4 +1,6 @@ -; RUN: llc < %s -mtriple=x86_64-apple-darwin10.0 -mcpu=core2 -relocation-model=dynamic-no-pic --asm-verbose=0 | FileCheck %s +; RUN: llc < %s -mtriple=i386-apple-darwin10.0 -mcpu=core2 -relocation-model=dynamic-no-pic --asm-verbose=0 | FileCheck -check-prefix=I386 %s +; RUN: llc < %s -mtriple=x86_64-apple-darwin10.0 -mcpu=core2 -relocation-model=dynamic-no-pic --asm-verbose=0 | FileCheck -check-prefix=CORE2 %s +; RUN: llc < %s -mtriple=x86_64-apple-darwin10.0 -mcpu=corei7 -relocation-model=dynamic-no-pic --asm-verbose=0 | FileCheck -check-prefix=COREI7 %s @.str1 = internal constant [31 x i8] c"DHRYSTONE PROGRAM, SOME STRING\00", align 8 @.str3 = internal constant [31 x i8] c"DHRYSTONE PROGRAM, 2'ND STRING\00", align 8 @@ -11,8 +13,13 @@ bb: %String2Loc9 = getelementptr inbounds [31 x i8]* %String2Loc, i64 0, i64 0 call void @llvm.memcpy.i64(i8* %String2Loc9, i8* getelementptr inbounds ([31 x i8]* @.str3, i64 0, i64 0), i64 31, i32 1) -; CHECK: movabsq $2325069237881678925, %rax -; CHECK: movups _.str3(%rip), %xmm0 +; I386: calll {{_?}}memcpy + +; CORE2: movabsq +; CORE2: movabsq +; CORE2: movabsq + +; COREI7: movups _.str3 br label %bb return: @@ -21,9 +28,9 @@ declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind -; CHECK: .section -; CHECK: .align 4 -; CHECK-NEXT: _.str1: -; CHECK-NEXT: .asciz "DHRYSTONE PROGRAM, SOME STRING" -; CHECK: .align 4 -; CHECK-NEXT: _.str3: +; CORE2: .section +; CORE2: .align 4 +; CORE2-NEXT: _.str1: +; CORE2-NEXT: .asciz "DHRYSTONE PROGRAM, SOME STRING" +; CORE2: .align 4 +; CORE2-NEXT: _.str3: From bob.wilson at apple.com Fri Jan 7 14:00:46 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 7 Jan 2011 12:00:46 -0800 Subject: [llvm-commits] [llvm] r122959 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/objsize.ll In-Reply-To: <20110106131105.59E222A6C12C@llvm.org> References: <20110106131105.59E222A6C12C@llvm.org> Message-ID: <36B13217-CC55-4CF9-9570-1ECCD6389A62@apple.com> On Jan 6, 2011, at 5:11 AM, Benjamin Kramer wrote: > Author: d0k > Date: Thu Jan 6 07:11:05 2011 > New Revision: 122959 > > URL: http://llvm.org/viewvc/llvm-project?rev=122959&view=rev > Log: > InstCombine: If we call llvm.objectsize on a malloc call we can replace it with the size passed to malloc. > > Modified: > llvm/trunk/lib/Target/README.txt > llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp > llvm/trunk/test/Transforms/InstCombine/objsize.ll This caused a significant performance regression in the MultiSource/Benchmarks/Prolangs-C/cdecl test: http://llvm.org/perf/db_default/simple/nts/69/ The compile-time regression is just a symptom of having larger code. The ds() function in cdecl.c is: char *ds(s) char *s; { register char *p = malloc((unsigned)(strlen(s)+1)); if (p) (void) strcpy(p,s); else { (void) fprintf (stderr, "%s: malloc() failed!\n", progname); exit(1); } return p; } Before this change, codegenprepare folded the strcpy_chk to strcpy because it treated the malloc size as unknown. Now, it knows the malloc size but not the source size, so it's keeping the strcpy_chk. The ds() function is inlined to lots of places, so the effect is greatly magnified. In this case, it ought to be possible to recognize that the source is the same size as the destination and have instcombine fold to strcpy. Could you look into doing that, or at least add a comment to the README file about it? > > Modified: llvm/trunk/lib/Target/README.txt > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=122959&r1=122958&r2=122959&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/README.txt (original) > +++ llvm/trunk/lib/Target/README.txt Thu Jan 6 07:11:05 2011 > @@ -2020,29 +2020,6 @@ > > //===---------------------------------------------------------------------===// > > -This code can be seen in viterbi: > - > - %64 = call noalias i8* @malloc(i64 %62) nounwind > -... > - %67 = call i64 @llvm.objectsize.i64(i8* %64, i1 false) nounwind > - %68 = call i8* @__memset_chk(i8* %64, i32 0, i64 %62, i64 %67) nounwind > - > -llvm.objectsize.i64 should be taught about malloc/calloc, allowing it to > -fold to %62. This is a security win (overflows of malloc will get caught) > -and also a performance win by exposing more memsets to the optimizer. > - > -This occurs several times in viterbi. > - > -Stuff like this occurs in drystone: > - > - %call5 = call i8* @malloc(i32 48) optsize > - %5 = getelementptr inbounds i8* %call5, i32 16 > - %6 = call i32 @llvm.objectsize.i32(i8* %5, i1 false) > - > -We should be able to constant fold that. > - > -//===---------------------------------------------------------------------===// > - > This code (from Benchmarks/Dhrystone/dry.c): > > define i32 @Func1(i32, i32) nounwind readnone optsize ssp { > > Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=122959&r1=122958&r2=122959&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original) > +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Thu Jan 6 07:11:05 2011 > @@ -298,12 +298,16 @@ > } > } > } else if (CallInst *MI = extractMallocCall(Op1)) { > - // Get alloca size. > + // Get allocation size. > const Type* MallocType = getMallocAllocatedType(MI); > if (MallocType && MallocType->isSized()) > if (Value *NElems = getMallocArraySize(MI, TD, true)) > if (ConstantInt *NElements = dyn_cast(NElems)) > Size = NElements->getZExtValue() * TD->getTypeAllocSize(MallocType); > + > + // If there is no offset we can just return the size passed to malloc. > + if (Offset == 0) > + return ReplaceInstUsesWith(CI, MI->getArgOperand(0)); > } > > // Do not return "I don't know" here. Later optimization passes could > > Modified: llvm/trunk/test/Transforms/InstCombine/objsize.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/objsize.ll?rev=122959&r1=122958&r2=122959&view=diff > ============================================================================== > --- llvm/trunk/test/Transforms/InstCombine/objsize.ll (original) > +++ llvm/trunk/test/Transforms/InstCombine/objsize.ll Thu Jan 6 07:11:05 2011 > @@ -160,3 +160,19 @@ > ret i32 %objsize > } > > +define i32 @test8(i32 %x) { > +; CHECK: @test8 > + %alloc = call noalias i8* @malloc(i32 %x) nounwind > + %objsize = call i32 @llvm.objectsize.i32(i8* %alloc, i1 false) nounwind readonly > +; CHECK-NEXT: ret i32 %x > + ret i32 %objsize > +} > + > +define i32 @test9(i32 %x) { > +; CHECK: @test9 > + %alloc = call noalias i8* @malloc(i32 %x) nounwind > + %gep = getelementptr inbounds i8* %alloc, i32 16 > + %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false) nounwind readonly > +; CHECK-NOT: ret i32 %x > + ret i32 %objsize > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From grosser at fim.uni-passau.de Fri Jan 7 14:11:39 2011 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Fri, 07 Jan 2011 15:11:39 -0500 Subject: [llvm-commits] [PATCH] Fix: instcombine does not get max if hidden by sext In-Reply-To: References: <4D22A780.6060209@fim.uni-passau.de> <48360275-C1A1-4AB1-A1A2-F5609C52094B@apple.com> <4D272A03.5030008@fim.uni-passau.de> Message-ID: <4D27737B.9040607@fim.uni-passau.de> On 01/07/2011 11:01 AM, Frits van Bommel wrote: > On Fri, Jan 7, 2011 at 3:58 PM, Tobias Grosser > wrote: >> On 01/06/2011 05:49 AM, Frits van Bommel wrote: >>> >>> On Thu, Jan 6, 2011 at 7:49 AM, Chris Lattner wrote: >>>> >>>> On Jan 3, 2011, at 8:52 PM, Tobias Grosser wrote: >>>>> >>>>> I fixed a recent bug report, that blocked me on a large FORTRAN test >>>>> case: >>>>> >>>>> InstCombine: >>>>> X = sext x ; x< c ? X : C-1 >>>>> --> >>>>> X = sext x; X> C-1 ? C-1 : X >>>>> >>>>> Instead of calculating this with mixed types promote all to the >>>>> larger type. This enables scalar evolution to analyze this >>>>> expression. PR8866 > switch (Pred) { > default: break; > - case ICmpInst::ICMP_ULT: > case ICmpInst::ICMP_SLT: { > // X< MIN ? T : F --> F > - if (CI->isMinValue(Pred == ICmpInst::ICMP_SLT)) > + if (CI->isMinValue(true /* signed */)) > return ReplaceInstUsesWith(SI, FalseVal); > ... > break; > } > - case ICmpInst::ICMP_UGT: > case ICmpInst::ICMP_SGT: { > // X> MAX ? T : F --> F > - if (CI->isMaxValue(Pred == ICmpInst::ICMP_SGT)) > + if (CI->isMaxValue(true /* signed */)) > return ReplaceInstUsesWith(SI, FalseVal); > + break; > + } > > Why not do this for the unsigned cases anymore? X as is X>u -1. Fixed. > Also, this switch might be cleaner as an if/else if but that's perhaps > a matter of taste. Fixed. > + // X = sext x; x>s c ? X : C+1 --> X = sext x; X + // X = sext x; x X = sext x; X>s C-1 ? C-1 : X > + if (Pred == ICI->getSignedPredicate()) { > > You can use ICI->isSigned() or (I)CmpInst::isSigned(Pred) here. Fixed. > I also noticed that you're no longer handling the sext + unsigned > compare case. I know it's kind of counter-intuitive, but when I was > examining the original patch I tried to find a case where it was wrong > but couldn't find one. > For instance, for x If both x and y are=s 0, (sext x) and (sext y) are > still the same relative values when interpreted as unsigned (just with > possibly some 1s prepended) so the result of x sext'ing the operands. > If x=s 0, x to y doesn't change that. > If x>=s 0 and y y doesn't change that. > A similar argument can be made for x>u y. I added support for this case and two more test cases. > The same doesn't hold for zext + signed compare, by the way. For > instance, 0xffs 0x0000. I copied this example in a comment. Thanks for your helpful review. New version attached. Cheers Tobi -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-InstCombine-Match-min-max-hidden-by-sext-zext.patch Type: text/x-diff Size: 6883 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110107/dfb45f2f/attachment.bin From jay.foad at gmail.com Fri Jan 7 14:25:56 2011 From: jay.foad at gmail.com (Jay Foad) Date: Fri, 07 Jan 2011 20:25:56 -0000 Subject: [llvm-commits] [llvm] r123025 - in /llvm/trunk/lib/Transforms/Utils: Local.cpp LoopUnroll.cpp Message-ID: <20110107202556.7C0012A6C12C@llvm.org> Author: foad Date: Fri Jan 7 14:25:56 2011 New Revision: 123025 URL: http://llvm.org/viewvc/llvm-project?rev=123025&view=rev Log: Remove all uses of the "ugly" method BranchInst::setUnconditionalDest(). Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=123025&r1=123024&r2=123025&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Fri Jan 7 14:25:56 2011 @@ -67,9 +67,9 @@ assert(BI->getParent() && "Terminator not inserted in block!"); OldDest->removePredecessor(BI->getParent()); - // Set the unconditional destination, and change the insn to be an - // unconditional branch. - BI->setUnconditionalDest(Destination); + // Replace the conditional branch with an unconditional one. + BranchInst::Create(Destination, BI); + BI->eraseFromParent(); return true; } @@ -82,8 +82,9 @@ assert(BI->getParent() && "Terminator not inserted in block!"); Dest1->removePredecessor(BI->getParent()); - // Change a conditional branch to unconditional. - BI->setUnconditionalDest(Dest1); + // Replace the conditional branch with an unconditional one. + BranchInst::Create(Dest1, BI); + BI->eraseFromParent(); return true; } return false; Modified: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp?rev=123025&r1=123024&r2=123025&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Fri Jan 7 14:25:56 2011 @@ -341,7 +341,9 @@ // iteration. Term->setSuccessor(!ContinueOnTrue, Dest); } else { - Term->setUnconditionalDest(Dest); + // Replace the conditional branch with an unconditional one. + BranchInst::Create(Dest, Term); + Term->eraseFromParent(); // Merge adjacent basic blocks, if possible. if (BasicBlock *Fold = FoldBlockIntoPredecessor(Dest, LI)) { std::replace(Latches.begin(), Latches.end(), Dest, Fold); From jay.foad at gmail.com Fri Jan 7 14:26:51 2011 From: jay.foad at gmail.com (Jay Foad) Date: Fri, 07 Jan 2011 20:26:51 -0000 Subject: [llvm-commits] [llvm] r123026 - in /llvm/trunk: include/llvm/Instructions.h unittests/VMCore/InstructionsTest.cpp Message-ID: <20110107202651.D31CA2A6C12C@llvm.org> Author: foad Date: Fri Jan 7 14:26:51 2011 New Revision: 123026 URL: http://llvm.org/viewvc/llvm-project?rev=123026&view=rev Log: Remove the "ugly" method BranchInst::setUnconditionalDest(). Modified: llvm/trunk/include/llvm/Instructions.h llvm/trunk/unittests/VMCore/InstructionsTest.cpp Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=123026&r1=123025&r2=123026&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Fri Jan 7 14:26:51 2011 @@ -2100,19 +2100,6 @@ Op<-3>() = V; } - // setUnconditionalDest - Change the current branch to an unconditional branch - // targeting the specified block. - // FIXME: Eliminate this ugly method. - void setUnconditionalDest(BasicBlock *Dest) { - Op<-1>() = (Value*)Dest; - if (isConditional()) { // Convert this to an uncond branch. - Op<-2>() = 0; - Op<-3>() = 0; - NumOperands = 1; - OperandList = op_begin(); - } - } - unsigned getNumSuccessors() const { return 1+isConditional(); } BasicBlock *getSuccessor(unsigned i) const { Modified: llvm/trunk/unittests/VMCore/InstructionsTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/VMCore/InstructionsTest.cpp?rev=123026&r1=123025&r2=123026&view=diff ============================================================================== --- llvm/trunk/unittests/VMCore/InstructionsTest.cpp (original) +++ llvm/trunk/unittests/VMCore/InstructionsTest.cpp Fri Jan 7 14:26:51 2011 @@ -99,23 +99,6 @@ EXPECT_EQ(b, b1->op_end()); - // shrink it - b1->setUnconditionalDest(bb1); - - // check num operands - EXPECT_EQ(b1->getNumOperands(), 1U); - - User::const_op_iterator c(b1->op_begin()); - EXPECT_NE(c, b1->op_end()); - - // check THEN - EXPECT_EQ(*c, bb1); - EXPECT_EQ(b1->getOperand(0), bb1); - EXPECT_EQ(b1->getSuccessor(0), bb1); - ++c; - - EXPECT_EQ(c, b1->op_end()); - // clean up delete b0; delete b1; From jay.foad at gmail.com Fri Jan 7 14:29:02 2011 From: jay.foad at gmail.com (Jay Foad) Date: Fri, 07 Jan 2011 20:29:02 -0000 Subject: [llvm-commits] [llvm] r123027 - in /llvm/trunk: include/llvm/Instructions.h include/llvm/Use.h include/llvm/User.h lib/VMCore/Instructions.cpp lib/VMCore/Use.cpp Message-ID: <20110107202903.12B0C2A6C12C@llvm.org> Author: foad Date: Fri Jan 7 14:29:02 2011 New Revision: 123027 URL: http://llvm.org/viewvc/llvm-project?rev=123027&view=rev Log: Simplify the allocation and freeing of Users' operand lists, now that every BranchInst has a fixed number of operands. Modified: llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/Use.h llvm/trunk/include/llvm/User.h llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/lib/VMCore/Use.cpp Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=123027&r1=123026&r2=123027&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Fri Jan 7 14:29:02 2011 @@ -2068,22 +2068,20 @@ virtual BranchInst *clone_impl() const; public: static BranchInst *Create(BasicBlock *IfTrue, Instruction *InsertBefore = 0) { - return new(1, true) BranchInst(IfTrue, InsertBefore); + return new(1) BranchInst(IfTrue, InsertBefore); } static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, Instruction *InsertBefore = 0) { return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertBefore); } static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) { - return new(1, true) BranchInst(IfTrue, InsertAtEnd); + return new(1) BranchInst(IfTrue, InsertAtEnd); } static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BasicBlock *InsertAtEnd) { return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertAtEnd); } - ~BranchInst(); - /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); Modified: llvm/trunk/include/llvm/Use.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Use.h?rev=123027&r1=123026&r2=123027&view=diff ============================================================================== --- llvm/trunk/include/llvm/Use.h (original) +++ llvm/trunk/include/llvm/Use.h Fri Jan 7 14:29:02 2011 @@ -112,8 +112,6 @@ /// a User changes. static void zap(Use *Start, const Use *Stop, bool del = false); - /// getPrefix - Return deletable pointer if appropriate - Use *getPrefix(); private: const Use* getImpliedUser() const; static Use *initTags(Use *Start, Use *Stop, ptrdiff_t Done = 0); Modified: llvm/trunk/include/llvm/User.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/User.h?rev=123027&r1=123026&r2=123027&view=diff ============================================================================== --- llvm/trunk/include/llvm/User.h (original) +++ llvm/trunk/include/llvm/User.h Fri Jan 7 14:29:02 2011 @@ -61,7 +61,6 @@ unsigned NumOperands; void *operator new(size_t s, unsigned Us); - void *operator new(size_t s, unsigned Us, bool Prefix); User(const Type *ty, unsigned vty, Use *OpList, unsigned NumOps) : Value(ty, vty), OperandList(OpList), NumOperands(NumOps) {} Use *allocHungoffUses(unsigned) const; @@ -74,8 +73,7 @@ } public: ~User() { - if ((intptr_t(OperandList) & 1) == 0) - Use::zap(OperandList, OperandList + NumOperands); + Use::zap(OperandList, OperandList + NumOperands); } /// operator delete - free memory allocated for User and Use objects void operator delete(void *Usr); Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=123027&r1=123026&r2=123027&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Fri Jan 7 14:29:02 2011 @@ -730,31 +730,6 @@ SubclassOptionalData = BI.SubclassOptionalData; } - -Use* Use::getPrefix() { - PointerIntPair &PotentialPrefix(this[-1].Prev); - if (PotentialPrefix.getOpaqueValue()) - return 0; - - return reinterpret_cast((char*)&PotentialPrefix + 1); -} - -BranchInst::~BranchInst() { - if (NumOperands == 1) { - if (Use *Prefix = OperandList->getPrefix()) { - Op<-1>() = 0; - // - // mark OperandList to have a special value for scrutiny - // by baseclass destructors and operator delete - OperandList = Prefix; - } else { - NumOperands = 3; - OperandList = op_begin(); - } - } -} - - BasicBlock *BranchInst::getSuccessorV(unsigned idx) const { return getSuccessor(idx); } @@ -3329,8 +3304,7 @@ } BranchInst *BranchInst::clone_impl() const { - unsigned Ops(getNumOperands()); - return new(Ops, Ops == 1) BranchInst(*this); + return new(getNumOperands()) BranchInst(*this); } SwitchInst *SwitchInst::clone_impl() const { Modified: llvm/trunk/lib/VMCore/Use.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Use.cpp?rev=123027&r1=123026&r2=123027&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Use.cpp (original) +++ llvm/trunk/lib/VMCore/Use.cpp Fri Jan 7 14:29:02 2011 @@ -191,31 +191,6 @@ return Obj; } -/// Prefixed allocation - just before the first Use, allocate a NULL pointer. -/// The destructor can detect its presence and readjust the OperandList -/// for deletition. -/// -void *User::operator new(size_t s, unsigned Us, bool Prefix) { - // currently prefixed allocation only admissible for - // unconditional branch instructions - if (!Prefix) - return operator new(s, Us); - - assert(Us == 1 && "Other than one Use allocated?"); - typedef PointerIntPair TaggedPrefix; - void *Raw = ::operator new(s + sizeof(TaggedPrefix) + sizeof(Use) * Us); - TaggedPrefix *Pre = static_cast(Raw); - Pre->setFromOpaqueValue(0); - void *Storage = Pre + 1; // skip over prefix - Use *Start = static_cast(Storage); - Use *End = Start + Us; - User *Obj = reinterpret_cast(End); - Obj->OperandList = Start; - Obj->NumOperands = Us; - Use::initTags(Start, End); - return Obj; -} - //===----------------------------------------------------------------------===// // User operator delete Implementation //===----------------------------------------------------------------------===// @@ -230,14 +205,6 @@ return; } // - // check for the flag whether the destructor has detected a prefixed - // allocation, in which case we remove the flag and delete starting - // at OperandList - if (reinterpret_cast(Start->OperandList) & 1) { - ::operator delete(reinterpret_cast(Start->OperandList) - 1); - return; - } - // // in all other cases just delete the nullary User (covers hung-off // uses also ::operator delete(Usr); From ofv at wanadoo.es Fri Jan 7 14:31:03 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Fri, 07 Jan 2011 20:31:03 -0000 Subject: [llvm-commits] [llvm] r123028 - in /llvm/trunk: CMakeLists.txt cmake/modules/LLVMProcessSources.cmake Message-ID: <20110107203103.4CF6C2A6C12C@llvm.org> Author: ofv Date: Fri Jan 7 14:31:03 2011 New Revision: 123028 URL: http://llvm.org/viewvc/llvm-project?rev=123028&view=rev Log: Don't use -O3 on Mingw, as people report it as unreliable. Use -O2 instead. Modified: llvm/trunk/CMakeLists.txt llvm/trunk/cmake/modules/LLVMProcessSources.cmake Modified: llvm/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/CMakeLists.txt?rev=123028&r1=123027&r2=123028&view=diff ============================================================================== --- llvm/trunk/CMakeLists.txt (original) +++ llvm/trunk/CMakeLists.txt Fri Jan 7 14:31:03 2011 @@ -317,6 +317,12 @@ set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES}${LLVM_SYSTEM_LIBS}") endif() +if( MINGW ) + # People report that -O3 is unreliable on MinGW. The traditional + # build also uses -O2 for that reason: + llvm_replace_compiler_option(CMAKE_CXX_FLAGS_RELEASE "-O3" "-O2") +endif() + add_subdirectory(lib/Support) # Everything else depends on Support: Modified: llvm/trunk/cmake/modules/LLVMProcessSources.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMProcessSources.cmake?rev=123028&r1=123027&r2=123028&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVMProcessSources.cmake (original) +++ llvm/trunk/cmake/modules/LLVMProcessSources.cmake Fri Jan 7 14:31:03 2011 @@ -1,5 +1,15 @@ include(AddFileDependencies) +macro(llvm_replace_compiler_option var old new) + # Replaces a compiler option or switch `old' in `var' by `new'. + # If `old' is not in `var', appends `new' to `var'. + # Example: llvm_replace_compiler_option(CMAKE_CXX_FLAGS_RELEASE "-O3" "-O2") + if( "${${var}}" MATCHES "(^| )${old}($| )" ) + string( REGEX REPLACE "(^| )${old}($| )" " ${new} " ${var} "${${var}}" ) + else() + set( ${var} "${${var}} ${new}" ) + endif() +endmacro(llvm_replace_compiler_option) macro(add_td_sources srcs) file(GLOB tds *.td) From ofv at wanadoo.es Fri Jan 7 14:35:05 2011 From: ofv at wanadoo.es (=?utf-8?Q?=C3=93scar_Fuentes?=) Date: Fri, 07 Jan 2011 21:35:05 +0100 Subject: [llvm-commits] [llvm] r122945 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: (Anton Korobeynikov's message of "Fri, 7 Jan 2011 12:51:45 +0300") References: <20110106025642.47BA92A6C12C@llvm.org> Message-ID: <87fwt4h2py.fsf@wanadoo.es> Hello Anton. Anton Korobeynikov writes: >> ?- Use clang++! (recommended :D ) >> ?- Use -O2. (-O3 by default with CMake and -O2 by default with autoconf) > Yes, numerous miscompilations was the reason why O2 was forced on mingw32. > CMake should do the same. Done. Thanks for the heads up. From fvbommel at gmail.com Fri Jan 7 14:36:14 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Fri, 7 Jan 2011 21:36:14 +0100 Subject: [llvm-commits] [PATCH] Fix: instcombine does not get max if hidden by sext In-Reply-To: <4D27737B.9040607@fim.uni-passau.de> References: <4D22A780.6060209@fim.uni-passau.de> <48360275-C1A1-4AB1-A1A2-F5609C52094B@apple.com> <4D272A03.5030008@fim.uni-passau.de> <4D27737B.9040607@fim.uni-passau.de> Message-ID: On Fri, Jan 7, 2011 at 9:11 PM, Tobias Grosser wrote: > New version attached. You might be able to de-duplicate the sext case by using something like /* Check for sext */ else if (ICI->isUnsigned()) { /* Check for zext */ else break; } else break; (or the other way around) instead of if (ICI->isSigned()) { /* Check for sext */; } else { /* Check for sext and zext */ } You didn't include the test case patch this time, so I couldn't check that, but it should be fine as long as you have a test for each of the transformations mentioned at the top of the patch. Other than that, it looks fine to me (though I haven't completely re-checked the logic this time). From benny.kra at googlemail.com Fri Jan 7 14:42:20 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 07 Jan 2011 20:42:20 -0000 Subject: [llvm-commits] [llvm] r123030 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/objsize.ll Message-ID: <20110107204220.9C2482A6C12C@llvm.org> Author: d0k Date: Fri Jan 7 14:42:20 2011 New Revision: 123030 URL: http://llvm.org/viewvc/llvm-project?rev=123030&view=rev Log: Revert 122959, it needs more thought. Add it back to README.txt with additional notes. Modified: llvm/trunk/lib/Target/README.txt llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/trunk/test/Transforms/InstCombine/objsize.ll Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=123030&r1=123029&r2=123030&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Fri Jan 7 14:42:20 2011 @@ -2009,6 +2009,28 @@ //===---------------------------------------------------------------------===// +This code can be seen in viterbi: + + %64 = call noalias i8* @malloc(i64 %62) nounwind +... + %67 = call i64 @llvm.objectsize.i64(i8* %64, i1 false) nounwind + %68 = call i8* @__memset_chk(i8* %64, i32 0, i64 %62, i64 %67) nounwind + +llvm.objectsize.i64 should be taught about malloc/calloc, allowing it to +fold to %62. This is a security win (overflows of malloc will get caught) +and also a performance win by exposing more memsets to the optimizer. + +This occurs several times in viterbi. + +Note that this would change the semantics of @llvm.objectsize which by its +current definition always folds to a constant. We also should make sure that +we remove checking in code like + + char *p = malloc(strlen(s)+1); + __strcpy_chk(p, s, __builtin_objectsize(p, 0)); + +//===---------------------------------------------------------------------===// + This code (from Benchmarks/Dhrystone/dry.c): define i32 @Func1(i32, i32) nounwind readnone optsize ssp { Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=123030&r1=123029&r2=123030&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Fri Jan 7 14:42:20 2011 @@ -304,10 +304,6 @@ if (Value *NElems = getMallocArraySize(MI, TD, true)) if (ConstantInt *NElements = dyn_cast(NElems)) Size = NElements->getZExtValue() * TD->getTypeAllocSize(MallocType); - - // If there is no offset we can just return the size passed to malloc. - if (Offset == 0) - return ReplaceInstUsesWith(CI, MI->getArgOperand(0)); } // Do not return "I don't know" here. Later optimization passes could Modified: llvm/trunk/test/Transforms/InstCombine/objsize.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/objsize.ll?rev=123030&r1=123029&r2=123030&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/objsize.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/objsize.ll Fri Jan 7 14:42:20 2011 @@ -160,30 +160,3 @@ ret i32 %objsize } -define i32 @test8(i32 %x) { -; CHECK: @test8 - %alloc = call noalias i8* @malloc(i32 %x) nounwind - %objsize = call i32 @llvm.objectsize.i32(i8* %alloc, i1 false) nounwind readonly -; CHECK-NEXT: ret i32 %x - ret i32 %objsize -} - -define i32 @test9(i32 %x) { -; CHECK: @test9 - %alloc = call noalias i8* @malloc(i32 %x) nounwind - %gep = getelementptr inbounds i8* %alloc, i32 16 - %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false) nounwind readonly -; CHECK-NOT: ret i32 %x - ret i32 %objsize -} - -define i8* @test10(i32 %x) { -; CHECK: @test10 - %alloc = call noalias i8* @malloc(i32 %x) nounwind - %objsize = call i32 @llvm.objectsize.i32(i8* %alloc, i1 false) nounwind readonly - tail call i8* @__memset_chk(i8* %alloc, i32 0, i32 %x, i32 %objsize) nounwind -; CHECK-NOT: @llvm.objectsize -; CHECK: @llvm.memset - ret i8* %alloc -; CHECK: ret i8* -} From benny.kra at googlemail.com Fri Jan 7 14:49:09 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 7 Jan 2011 21:49:09 +0100 Subject: [llvm-commits] [llvm] r122959 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/objsize.ll In-Reply-To: <36B13217-CC55-4CF9-9570-1ECCD6389A62@apple.com> References: <20110106131105.59E222A6C12C@llvm.org> <36B13217-CC55-4CF9-9570-1ECCD6389A62@apple.com> Message-ID: On 07.01.2011, at 21:00, Bob Wilson wrote: > On Jan 6, 2011, at 5:11 AM, Benjamin Kramer wrote: > >> Author: d0k >> Date: Thu Jan 6 07:11:05 2011 >> New Revision: 122959 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122959&view=rev >> Log: >> InstCombine: If we call llvm.objectsize on a malloc call we can replace it with the size passed to malloc. >> >> Modified: >> llvm/trunk/lib/Target/README.txt >> llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp >> llvm/trunk/test/Transforms/InstCombine/objsize.ll > > This caused a significant performance regression in the MultiSource/Benchmarks/Prolangs-C/cdecl test: > http://llvm.org/perf/db_default/simple/nts/69/ > > The compile-time regression is just a symptom of having larger code. The ds() function in cdecl.c is: > > char *ds(s) > char *s; > { > register char *p = malloc((unsigned)(strlen(s)+1)); > > if (p) > (void) strcpy(p,s); > else > { > (void) fprintf (stderr, "%s: malloc() failed!\n", progname); > exit(1); > } > return p; > } > > Before this change, codegenprepare folded the strcpy_chk to strcpy because it treated the malloc size as unknown. Now, it knows the malloc size but not the source size, so it's keeping the strcpy_chk. The ds() function is inlined to lots of places, so the effect is greatly magnified. In this case, it ought to be possible to recognize that the source is the same size as the destination and have instcombine fold to strcpy. Could you look into doing that, or at least add a comment to the README file about it? I reverted the change for now, there is another issue with this as it changes the semantics of __builtin_objectsize. Unless we want to extend this GCC extension even more my patch is not safe in it's current form :( From fvbommel at gmail.com Fri Jan 7 15:00:36 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Fri, 7 Jan 2011 22:00:36 +0100 Subject: [llvm-commits] [llvm] r122959 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/objsize.ll In-Reply-To: References: <20110106131105.59E222A6C12C@llvm.org> <36B13217-CC55-4CF9-9570-1ECCD6389A62@apple.com> Message-ID: On Fri, Jan 7, 2011 at 9:49 PM, Benjamin Kramer wrote: > On 07.01.2011, at 21:00, Bob Wilson wrote: >> On Jan 6, 2011, at 5:11 AM, Benjamin Kramer wrote: >> Before this change, codegenprepare folded the strcpy_chk to strcpy because it treated the malloc size as unknown. ?Now, it knows the malloc size but not the source size, so it's keeping the strcpy_chk. ?The ds() function is inlined to lots of places, so the effect is greatly magnified. ?In this case, it ought to be possible to recognize that the source is the same size as the destination and have instcombine fold to strcpy. ?Could you look into doing that, or at least add a comment to the README file about it? > > I reverted the change for now, there is another issue with this as it changes the semantics of __builtin_objectsize. > Unless we want to extend this GCC extension even more my patch is not safe in it's current form :( The "changes the semantics" issue should be easily avoidable by adding an isa() check. That would allow it to work for simpler cases like 'malloc(sizeof(Struct))'. From benny.kra at googlemail.com Fri Jan 7 15:07:10 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 7 Jan 2011 22:07:10 +0100 Subject: [llvm-commits] [llvm] r122959 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/objsize.ll In-Reply-To: References: <20110106131105.59E222A6C12C@llvm.org> <36B13217-CC55-4CF9-9570-1ECCD6389A62@apple.com> Message-ID: On 07.01.2011, at 22:00, Frits van Bommel wrote: > On Fri, Jan 7, 2011 at 9:49 PM, Benjamin Kramer > wrote: >> On 07.01.2011, at 21:00, Bob Wilson wrote: >>> On Jan 6, 2011, at 5:11 AM, Benjamin Kramer wrote: >>> Before this change, codegenprepare folded the strcpy_chk to strcpy because it treated the malloc size as unknown. Now, it knows the malloc size but not the source size, so it's keeping the strcpy_chk. The ds() function is inlined to lots of places, so the effect is greatly magnified. In this case, it ought to be possible to recognize that the source is the same size as the destination and have instcombine fold to strcpy. Could you look into doing that, or at least add a comment to the README file about it? >> >> I reverted the change for now, there is another issue with this as it changes the semantics of __builtin_objectsize. >> Unless we want to extend this GCC extension even more my patch is not safe in it's current form :( > > The "changes the semantics" issue should be easily avoidable by adding > an isa() check. That would allow it to work for simpler > cases like 'malloc(sizeof(Struct))'. That worked without this patch and still does its job now :) From evan.cheng at apple.com Fri Jan 7 15:08:26 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 07 Jan 2011 21:08:26 -0000 Subject: [llvm-commits] [llvm] r123031 - in /llvm/trunk: include/llvm/Target/Target.td lib/CodeGen/MachineInstr.cpp lib/CodeGen/PeepholeOptimizer.cpp lib/CodeGen/VirtRegRewriter.cpp Message-ID: <20110107210826.3FD6C2A6C12C@llvm.org> Author: evancheng Date: Fri Jan 7 15:08:26 2011 New Revision: 123031 URL: http://llvm.org/viewvc/llvm-project?rev=123031&view=rev Log: DBG_VALUE does not have any side effects; it also makes no sense to mark it cheap as a copy. Modified: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/lib/CodeGen/MachineInstr.cpp llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=123031&r1=123030&r2=123031&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Fri Jan 7 15:08:26 2011 @@ -484,7 +484,7 @@ let OutOperandList = (outs); let InOperandList = (ins variable_ops); let AsmString = "DBG_VALUE"; - let isAsCheapAsAMove = 1; + let neverHasSideEffects = 1; } def REG_SEQUENCE : Instruction { let OutOperandList = (outs unknown:$dst); Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=123031&r1=123030&r2=123031&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Fri Jan 7 15:08:26 2011 @@ -1115,7 +1115,9 @@ SawStore = true; return false; } - if (TID->isTerminator() || TID->hasUnmodeledSideEffects()) + + if (isLabel() || isDebugValue() || + TID->isTerminator() || TID->hasUnmodeledSideEffects()) return false; // See if this instruction does a load. If so, we have to guarantee that the Modified: llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp?rev=123031&r1=123030&r2=123031&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp (original) +++ llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp Fri Jan 7 15:08:26 2011 @@ -336,7 +336,9 @@ MachineInstr *MI = &*MII++; LocalMIs.insert(MI); - if (MI->getDesc().hasUnmodeledSideEffects()) + if (MI->isLabel() || MI->isPHI() || MI->isImplicitDef() || + MI->isKill() || MI->isInlineAsm() || MI->isDebugValue() || + MI->getDesc().hasUnmodeledSideEffects()) continue; if (MI->getDesc().isCompare()) { Modified: llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp?rev=123031&r1=123030&r2=123031&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Fri Jan 7 15:08:26 2011 @@ -1620,7 +1620,8 @@ const TargetInstrDesc &TID = MI.getDesc(); if (TID.mayLoad() || TID.mayStore() || TID.isCall() || TID.isTerminator() || TID.isCall() || TID.isBarrier() || TID.isReturn() || - TID.hasUnmodeledSideEffects()) + TID.hasUnmodeledSideEffects() || + MI.isLabel() || MI.isDebugValue()) return false; for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); From dpatel at apple.com Fri Jan 7 15:30:41 2011 From: dpatel at apple.com (Devang Patel) Date: Fri, 07 Jan 2011 21:30:41 -0000 Subject: [llvm-commits] [llvm] r123032 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/LiveDebugVariables.cpp test/CodeGen/X86/2010-05-26-DotDebugLoc.ll test/CodeGen/X86/2010-05-28-Crash.ll test/CodeGen/X86/dbg-value-range.ll Message-ID: <20110107213041.963852A6C12C@llvm.org> Author: dpatel Date: Fri Jan 7 15:30:41 2011 New Revision: 123032 URL: http://llvm.org/viewvc/llvm-project?rev=123032&view=rev Log: Appropriately truncate debug info range in dwarf output. Enable live debug variables pass. Added: llvm/trunk/test/CodeGen/X86/dbg-value-range.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll llvm/trunk/test/CodeGen/X86/2010-05-28-Crash.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=123032&r1=123031&r2=123032&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Fri Jan 7 15:30:41 2011 @@ -2257,15 +2257,6 @@ } } -/// isDbgValueInUndefinedReg - Return true if debug value, encoded by -/// DBG_VALUE instruction, is in undefined reg. -static bool isDbgValueInUndefinedReg(const MachineInstr *MI) { - assert (MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!"); - if (MI->getOperand(0).isReg() && !MI->getOperand(0).getReg()) - return true; - return false; -} - /// isDbgValueInDefinedReg - Return true if debug value, encoded by /// DBG_VALUE instruction, is in a defined reg. static bool isDbgValueInDefinedReg(const MachineInstr *MI) { @@ -2290,7 +2281,7 @@ for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); II != IE; ++II) { const MachineInstr *MInsn = II; - if (!MInsn->isDebugValue() || isDbgValueInUndefinedReg(MInsn)) + if (!MInsn->isDebugValue()) continue; DbgValues.push_back(MInsn); } @@ -2312,19 +2303,18 @@ ME = DbgValues.end(); MI != ME; ++MI) { const MDNode *Var = (*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata(); - if (Var == DV && isDbgValueInDefinedReg(*MI) && + if (Var == DV && !PrevMI->isIdenticalTo(*MI)) MultipleValues.push_back(*MI); PrevMI = *MI; } - DbgScope *Scope = findDbgScope(MInsn); - bool CurFnArg = false; + DbgScope *Scope = NULL; if (DV.getTag() == dwarf::DW_TAG_arg_variable && DISubprogram(DV.getContext()).describes(MF->getFunction())) - CurFnArg = true; - if (!Scope && CurFnArg) Scope = CurrentFnDbgScope; + else + Scope = findDbgScope(MInsn); // If variable scope is not found then skip this variable. if (!Scope) continue; Modified: llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp?rev=123032&r1=123031&r2=123032&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp Fri Jan 7 15:30:41 2011 @@ -39,10 +39,6 @@ using namespace llvm; -static cl::opt -EnableLDV("live-debug-variables", - cl::desc("Enable the live debug variables pass"), cl::Hidden); - char LiveDebugVariables::ID = 0; INITIALIZE_PASS_BEGIN(LiveDebugVariables, "livedebugvars", @@ -622,8 +618,6 @@ } bool LiveDebugVariables::runOnMachineFunction(MachineFunction &mf) { - if (!EnableLDV) - return false; if (!pImpl) pImpl = new LDVImpl(this); return static_cast(pImpl)->runOnMachineFunction(mf); Modified: llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll?rev=123032&r1=123031&r2=123032&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll Fri Jan 7 15:30:41 2011 @@ -61,6 +61,6 @@ ; CHECK-NEXT: .short 1 ; CHECK-NEXT: .byte 85 ; CHECK-NEXT: .quad Ltmp3 -; CHECK-NEXT: .quad Lfunc_end +; CHECK-NEXT: .quad Ltmp6 ; CHECK-NEXT: .short 1 ; CHECK-NEXT: .byte 83 Modified: llvm/trunk/test/CodeGen/X86/2010-05-28-Crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-05-28-Crash.ll?rev=123032&r1=123031&r2=123032&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-05-28-Crash.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-05-28-Crash.ll Fri Jan 7 15:30:41 2011 @@ -39,6 +39,5 @@ !13 = metadata !{i32 7, i32 0, metadata !14, null} !14 = metadata !{i32 524299, metadata !8, i32 6, i32 0} ; [ DW_TAG_lexical_block ] -;CHECK: DEBUG_VALUE: bar:x <- EBX+0 -;CHECK-NEXT:Ltmp +;CHECK:Ltmp8 ;CHECK-NEXT: DEBUG_VALUE: foo:y <- 1+0 Added: llvm/trunk/test/CodeGen/X86/dbg-value-range.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dbg-value-range.ll?rev=123032&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/dbg-value-range.ll (added) +++ llvm/trunk/test/CodeGen/X86/dbg-value-range.ll Fri Jan 7 15:30:41 2011 @@ -0,0 +1,56 @@ +; RUN: llc -mtriple=x86_64-apple-darwin < %s | FileCheck %s + +%struct.a = type { i32 } + +define i32 @bar(%struct.a* nocapture %b) nounwind ssp { +entry: + tail call void @llvm.dbg.value(metadata !{%struct.a* %b}, i64 0, metadata !6), !dbg !13 + %tmp1 = getelementptr inbounds %struct.a* %b, i64 0, i32 0, !dbg !14 + %tmp2 = load i32* %tmp1, align 4, !dbg !14, !tbaa !15 + tail call void @llvm.dbg.value(metadata !{i32 %tmp2}, i64 0, metadata !11), !dbg !14 + %call = tail call i32 (...)* @foo(i32 %tmp2) nounwind , !dbg !18 + %add = add nsw i32 %tmp2, 1, !dbg !19 + ret i32 %add, !dbg !19 +} + +declare i32 @foo(...) + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +!llvm.dbg.sp = !{!0} +!llvm.dbg.lv.bar = !{!6, !11} + +!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"bar", metadata !"bar", metadata !"", metadata !1, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (%struct.a*)* @bar} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 589865, metadata !"bar.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"bar.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 122997)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{metadata !5} +!5 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 590081, metadata !0, metadata !"b", metadata !1, i32 5, metadata !7, i32 0} ; [ DW_TAG_arg_variable ] +!7 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !8} ; [ DW_TAG_pointer_type ] +!8 = metadata !{i32 589843, metadata !2, metadata !"a", metadata !1, i32 1, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !9, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!9 = metadata !{metadata !10} +!10 = metadata !{i32 589837, metadata !1, metadata !"c", metadata !1, i32 2, i64 32, i64 32, i64 0, i32 0, metadata !5} ; [ DW_TAG_member ] +!11 = metadata !{i32 590080, metadata !12, metadata !"x", metadata !1, i32 6, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] +!12 = metadata !{i32 589835, metadata !0, i32 5, i32 22, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!13 = metadata !{i32 5, i32 19, metadata !0, null} +!14 = metadata !{i32 6, i32 14, metadata !12, null} +!15 = metadata !{metadata !"int", metadata !16} +!16 = metadata !{metadata !"omnipotent char", metadata !17} +!17 = metadata !{metadata !"Simple C/C++ TBAA", null} +!18 = metadata !{i32 7, i32 2, metadata !12, null} +!19 = metadata !{i32 8, i32 2, metadata !12, null} + +; check that variable bar:b value range is appropriately trucated in debug info. Here Ltmp5 is end of +; location range. + +;CHECK:Ltmp5 +;CHECK-NEXT: DEBUG_VALUE: bar:b <- undef + +;CHECK:Ldebug_loc0: +;CHECK-NEXT: .quad Ltmp +;CHECK-NEXT: .quad Ltmp5 +;CHECK-NEXT: .short 1 +;CHECK-NEXT: .byte 85 +;CHECK-NEXT: .quad 0 +;CHECK-NEXT: .quad 0 From grosser at fim.uni-passau.de Fri Jan 7 15:33:13 2011 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Fri, 07 Jan 2011 21:33:13 -0000 Subject: [llvm-commits] [llvm] r123033 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Message-ID: <20110107213313.5DFF42A6C12C@llvm.org> Author: grosser Date: Fri Jan 7 15:33:13 2011 New Revision: 123033 URL: http://llvm.org/viewvc/llvm-project?rev=123033&view=rev Log: Some whitespace fixes Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=123033&r1=123032&r2=123033&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Fri Jan 7 15:33:13 2011 @@ -24,14 +24,14 @@ MatchSelectPattern(Value *V, Value *&LHS, Value *&RHS) { SelectInst *SI = dyn_cast(V); if (SI == 0) return SPF_UNKNOWN; - + ICmpInst *ICI = dyn_cast(SI->getCondition()); if (ICI == 0) return SPF_UNKNOWN; - + LHS = ICI->getOperand(0); RHS = ICI->getOperand(1); - - // (icmp X, Y) ? X : Y + + // (icmp X, Y) ? X : Y if (SI->getTrueValue() == ICI->getOperand(0) && SI->getFalseValue() == ICI->getOperand(1)) { switch (ICI->getPredicate()) { @@ -46,8 +46,8 @@ case ICmpInst::ICMP_SLE: return SPF_SMIN; } } - - // (icmp X, Y) ? Y : X + + // (icmp X, Y) ? Y : X if (SI->getTrueValue() == ICI->getOperand(1) && SI->getFalseValue() == ICI->getOperand(0)) { switch (ICI->getPredicate()) { @@ -62,9 +62,9 @@ case ICmpInst::ICMP_SLE: return SPF_SMAX; } } - + // TODO: (X > 4) ? X : 5 --> (X >= 5) ? X : 5 --> MAX(X, 5) - + return SPF_UNKNOWN; } @@ -136,7 +136,7 @@ SelectInst *NewSI = SelectInst::Create(SI.getCondition(), TI->getOperand(0), FI->getOperand(0), SI.getName()+".v"); InsertNewInstBefore(NewSI, SI); - return CastInst::Create(Instruction::CastOps(TI->getOpcode()), NewSI, + return CastInst::Create(Instruction::CastOps(TI->getOpcode()), NewSI, TI->getType()); } @@ -402,28 +402,28 @@ // can always be mapped. const Instruction *I = dyn_cast(V); if (I == 0) return true; - + // If V is a PHI node defined in the same block as the condition PHI, we can // map the arguments. const PHINode *CondPHI = cast(SI.getCondition()); - + if (const PHINode *VP = dyn_cast(I)) if (VP->getParent() == CondPHI->getParent()) return true; - + // Otherwise, if the PHI and select are defined in the same block and if V is // defined in a different block, then we can transform it. if (SI.getParent() == CondPHI->getParent() && I->getParent() != CondPHI->getParent()) return true; - + // Otherwise we have a 'hard' case and we can't tell without doing more // detailed dominator based analysis, punt. return false; } /// FoldSPFofSPF - We have an SPF (e.g. a min or max) of an SPF of the form: -/// SPF2(SPF1(A, B), C) +/// SPF2(SPF1(A, B), C) Instruction *InstCombiner::FoldSPFofSPF(Instruction *Inner, SelectPatternFlavor SPF1, Value *A, Value *B, @@ -434,7 +434,7 @@ // MIN(MIN(a, b), a) -> MIN(a, b) if (SPF1 == SPF2) return ReplaceInstUsesWith(Outer, Inner); - + // MAX(MIN(a, b), a) -> a // MIN(MAX(a, b), a) -> a if ((SPF1 == SPF_SMIN && SPF2 == SPF_SMAX) || @@ -443,7 +443,7 @@ (SPF1 == SPF_UMAX && SPF2 == SPF_UMIN)) return ReplaceInstUsesWith(Outer, C); } - + // TODO: MIN(MIN(A, 23), 97) return 0; } @@ -550,7 +550,7 @@ "not."+CondVal->getName()), SI); return BinaryOperator::CreateOr(NotCond, TrueVal); } - + // select a, b, a -> a&b // select a, a, b -> a|b if (CondVal == TrueVal) @@ -569,7 +569,7 @@ // select C, -1, 0 -> sext C to int if (FalseValC->isZero() && TrueValC->isAllOnesValue()) return new SExtInst(CondVal, SI.getType()); - + // select C, 0, 1 -> zext !C to int if (TrueValC->isZero() && FalseValC->getValue() == 1) { Value *NotCond = Builder->CreateNot(CondVal, "not."+CondVal->getName()); @@ -591,7 +591,7 @@ if (FCI->getOperand(0) == TrueVal && FCI->getOperand(1) == FalseVal) { // Transform (X == Y) ? X : Y -> Y if (FCI->getPredicate() == FCmpInst::FCMP_OEQ) { - // This is not safe in general for floating point: + // This is not safe in general for floating point: // consider X== -0, Y== +0. // It becomes safe if either operand is a nonzero constant. ConstantFP *CFPt, *CFPf; @@ -603,7 +603,7 @@ } // Transform (X une Y) ? X : Y -> X if (FCI->getPredicate() == FCmpInst::FCMP_UNE) { - // This is not safe in general for floating point: + // This is not safe in general for floating point: // consider X== -0, Y== +0. // It becomes safe if either operand is a nonzero constant. ConstantFP *CFPt, *CFPf; @@ -618,7 +618,7 @@ } else if (FCI->getOperand(0) == FalseVal && FCI->getOperand(1) == TrueVal){ // Transform (X == Y) ? Y : X -> X if (FCI->getPredicate() == FCmpInst::FCMP_OEQ) { - // This is not safe in general for floating point: + // This is not safe in general for floating point: // consider X== -0, Y== +0. // It becomes safe if either operand is a nonzero constant. ConstantFP *CFPt, *CFPf; @@ -630,7 +630,7 @@ } // Transform (X une Y) ? Y : X -> Y if (FCI->getPredicate() == FCmpInst::FCMP_UNE) { - // This is not safe in general for floating point: + // This is not safe in general for floating point: // consider X== -0, Y== +0. // It becomes safe if either operand is a nonzero constant. ConstantFP *CFPt, *CFPf; @@ -719,7 +719,7 @@ if (SI.getType()->isIntegerTy()) { if (Instruction *FoldI = FoldSelectIntoOp(SI, TrueVal, FalseVal)) return FoldI; - + // MAX(MAX(a, b), a) -> MAX(a, b) // MIN(MIN(a, b), a) -> MIN(a, b) // MAX(MIN(a, b), a) -> a @@ -742,7 +742,7 @@ } // See if we can fold the select into a phi node if the condition is a select. - if (isa(SI.getCondition())) + if (isa(SI.getCondition())) // The true/false values have to be live in the PHI predecessor's blocks. if (CanSelectOperandBeMappingIntoPredBlock(TrueVal, SI) && CanSelectOperandBeMappingIntoPredBlock(FalseVal, SI)) From grosser at fim.uni-passau.de Fri Jan 7 15:33:14 2011 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Fri, 07 Jan 2011 21:33:14 -0000 Subject: [llvm-commits] [llvm] r123034 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineSelect.cpp test/Transforms/InstCombine/select.ll Message-ID: <20110107213315.0085B2A6C12D@llvm.org> Author: grosser Date: Fri Jan 7 15:33:14 2011 New Revision: 123034 URL: http://llvm.org/viewvc/llvm-project?rev=123034&view=rev Log: InstCombine: Match min/max hidden by sext/zext X = sext x; x >s c ? X : C+1 --> X = sext x; X X = sext x; X >s C-1 ? C-1 : X X = zext x; x >u c ? X : C+1 --> X = zext x; X X = zext x; X >u C-1 ? C-1 : X X = sext x; x >u c ? X : C+1 --> X = sext x; X X = sext x; X >u C-1 ? C-1 : X Instead of calculating this with mixed types promote all to the larger type. This enables scalar evolution to analyze this expression. PR8866 Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp llvm/trunk/test/Transforms/InstCombine/select.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=123034&r1=123033&r2=123034&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Fri Jan 7 15:33:14 2011 @@ -285,48 +285,83 @@ // place here, so make sure the select is the only user. if (ICI->hasOneUse()) if (ConstantInt *CI = dyn_cast(CmpRHS)) { + // X < MIN ? T : F --> F + if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_ULT) + && CI->isMinValue(Pred == ICmpInst::ICMP_SLT)) + return ReplaceInstUsesWith(SI, FalseVal); + // X > MAX ? T : F --> F + else if ((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_UGT) + && CI->isMaxValue(Pred == ICmpInst::ICMP_SGT)) + return ReplaceInstUsesWith(SI, FalseVal); switch (Pred) { default: break; case ICmpInst::ICMP_ULT: - case ICmpInst::ICMP_SLT: { - // X < MIN ? T : F --> F - if (CI->isMinValue(Pred == ICmpInst::ICMP_SLT)) - return ReplaceInstUsesWith(SI, FalseVal); - // X < C ? X : C-1 --> X > C-1 ? C-1 : X - Constant *AdjustedRHS = - ConstantInt::get(CI->getContext(), CI->getValue()-1); - if ((CmpLHS == TrueVal && AdjustedRHS == FalseVal) || - (CmpLHS == FalseVal && AdjustedRHS == TrueVal)) { - Pred = ICmpInst::getSwappedPredicate(Pred); - CmpRHS = AdjustedRHS; - std::swap(FalseVal, TrueVal); - ICI->setPredicate(Pred); - ICI->setOperand(1, CmpRHS); - SI.setOperand(1, TrueVal); - SI.setOperand(2, FalseVal); - Changed = true; - } - break; - } + case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_SGT: { - // X > MAX ? T : F --> F - if (CI->isMaxValue(Pred == ICmpInst::ICMP_SGT)) - return ReplaceInstUsesWith(SI, FalseVal); + Constant *AdjustedRHS; + if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_SGT) + AdjustedRHS = ConstantInt::get(CI->getContext(), CI->getValue() + 1); + else // (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SLT) + AdjustedRHS = ConstantInt::get(CI->getContext(), CI->getValue() - 1); + // X > C ? X : C+1 --> X < C+1 ? C+1 : X - Constant *AdjustedRHS = - ConstantInt::get(CI->getContext(), CI->getValue()+1); + // X < C ? X : C-1 --> X > C-1 ? C-1 : X if ((CmpLHS == TrueVal && AdjustedRHS == FalseVal) || - (CmpLHS == FalseVal && AdjustedRHS == TrueVal)) { - Pred = ICmpInst::getSwappedPredicate(Pred); - CmpRHS = AdjustedRHS; - std::swap(FalseVal, TrueVal); - ICI->setPredicate(Pred); - ICI->setOperand(1, CmpRHS); - SI.setOperand(1, TrueVal); - SI.setOperand(2, FalseVal); - Changed = true; - } + (CmpLHS == FalseVal && AdjustedRHS == TrueVal)) + ; // Nothing to do here. Values match without any sign/zero extension. + + // Types do not match. Instead of calculating this with mixed types + // promote all to the larger type. This enables scalar evolution to + // analyze this expression. + else if (CmpRHS->getType()->getScalarSizeInBits() + < SI.getType()->getScalarSizeInBits()) { + Constant *sextRHS = ConstantExpr::getSExt(AdjustedRHS, + SI.getType()); + + // X = sext x; x >s c ? X : C+1 --> X = sext x; X X = sext x; X >s C-1 ? C-1 : X + // X = sext x; x >u c ? X : C+1 --> X = sext x; X X = sext x; X >u C-1 ? C-1 : X + if (match(TrueVal, m_SExt(m_Specific(CmpLHS))) && + sextRHS == FalseVal) { + CmpLHS = TrueVal; + AdjustedRHS = sextRHS; + } else if (match(FalseVal, m_SExt(m_Specific(CmpLHS))) && + sextRHS == TrueVal) { + CmpLHS = FalseVal; + AdjustedRHS = sextRHS; + } else if (ICI->isUnsigned()) { + Constant *zextRHS = ConstantExpr::getZExt(AdjustedRHS, + SI.getType()); + // X = zext x; x >u c ? X : C+1 --> X = zext x; X X = zext x; X >u C-1 ? C-1 : X + // zext + signed compare cannot be changed: + // 0xff s 0x0000 + if (match(TrueVal, m_ZExt(m_Specific(CmpLHS))) && + zextRHS == FalseVal) { + CmpLHS = TrueVal; + AdjustedRHS = zextRHS; + } else if (match(FalseVal, m_ZExt(m_Specific(CmpLHS))) && + zextRHS == TrueVal) { + CmpLHS = FalseVal; + AdjustedRHS = zextRHS; + } else + break; + } else + break; + } else + break; + + Pred = ICmpInst::getSwappedPredicate(Pred); + CmpRHS = AdjustedRHS; + std::swap(FalseVal, TrueVal); + ICI->setPredicate(Pred); + ICI->setOperand(0, CmpLHS); + ICI->setOperand(1, CmpRHS); + SI.setOperand(1, TrueVal); + SI.setOperand(2, FalseVal); + Changed = true; break; } } Modified: llvm/trunk/test/Transforms/InstCombine/select.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select.ll?rev=123034&r1=123033&r2=123034&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/select.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/select.ll Fri Jan 7 15:33:14 2011 @@ -596,3 +596,85 @@ ; CHECK-NEXT: %c = add i32 %b, %y ; CHECK-NEXT: ret i32 %c } + +define i64 @test43(i32 %a) nounwind { + %a_ext = sext i32 %a to i64 + %is_a_nonnegative = icmp sgt i32 %a, -1 + %max = select i1 %is_a_nonnegative, i64 %a_ext, i64 0 + ret i64 %max +; CHECK: @test43 +; CHECK-NEXT: %a_ext = sext i32 %a to i64 +; CHECK-NEXT: %is_a_nonnegative = icmp slt i64 %a_ext, 0 +; CHECK-NEXT: %max = select i1 %is_a_nonnegative, i64 0, i64 %a_ext +; CHECK-NEXT: ret i64 %max +} + +define i64 @test44(i32 %a) nounwind { + %a_ext = sext i32 %a to i64 + %is_a_nonpositive = icmp slt i32 %a, 1 + %min = select i1 %is_a_nonpositive, i64 %a_ext, i64 0 + ret i64 %min +; CHECK: @test44 +; CHECK-NEXT: %a_ext = sext i32 %a to i64 +; CHECK-NEXT: %is_a_nonpositive = icmp sgt i64 %a_ext, 0 +; CHECK-NEXT: %min = select i1 %is_a_nonpositive, i64 0, i64 %a_ext +; CHECK-NEXT: ret i64 %min +} +define i64 @test45(i32 %a) nounwind { + %a_ext = zext i32 %a to i64 + %is_a_nonnegative = icmp ugt i32 %a, 2 + %max = select i1 %is_a_nonnegative, i64 %a_ext, i64 3 + ret i64 %max +; CHECK: @test45 +; CHECK-NEXT: %a_ext = zext i32 %a to i64 +; CHECK-NEXT: %is_a_nonnegative = icmp ult i64 %a_ext, 3 +; CHECK-NEXT: %max = select i1 %is_a_nonnegative, i64 3, i64 %a_ext +; CHECK-NEXT: ret i64 %max +} + +define i64 @test46(i32 %a) nounwind { + %a_ext = zext i32 %a to i64 + %is_a_nonpositive = icmp ult i32 %a, 3 + %min = select i1 %is_a_nonpositive, i64 %a_ext, i64 2 + ret i64 %min +; CHECK: @test46 +; CHECK-NEXT: %a_ext = zext i32 %a to i64 +; CHECK-NEXT: %is_a_nonpositive = icmp ugt i64 %a_ext, 2 +; CHECK-NEXT: %min = select i1 %is_a_nonpositive, i64 2, i64 %a_ext +; CHECK-NEXT: ret i64 %min +} +define i64 @test47(i32 %a) nounwind { + %a_ext = sext i32 %a to i64 + %is_a_nonnegative = icmp ugt i32 %a, 2 + %max = select i1 %is_a_nonnegative, i64 %a_ext, i64 3 + ret i64 %max +; CHECK: @test47 +; CHECK-NEXT: %a_ext = sext i32 %a to i64 +; CHECK-NEXT: %is_a_nonnegative = icmp ult i64 %a_ext, 3 +; CHECK-NEXT: %max = select i1 %is_a_nonnegative, i64 3, i64 %a_ext +; CHECK-NEXT: ret i64 %max +} + +define i64 @test48(i32 %a) nounwind { + %a_ext = sext i32 %a to i64 + %is_a_nonpositive = icmp ult i32 %a, 3 + %min = select i1 %is_a_nonpositive, i64 %a_ext, i64 2 + ret i64 %min +; CHECK: @test48 +; CHECK-NEXT: %a_ext = sext i32 %a to i64 +; CHECK-NEXT: %is_a_nonpositive = icmp ugt i64 %a_ext, 2 +; CHECK-NEXT: %min = select i1 %is_a_nonpositive, i64 2, i64 %a_ext +; CHECK-NEXT: ret i64 %min +} + +define i64 @test49(i32 %a) nounwind { + %a_ext = sext i32 %a to i64 + %is_a_nonpositive = icmp ult i32 %a, 3 + %min = select i1 %is_a_nonpositive, i64 2, i64 %a_ext + ret i64 %min +; CHECK: @test49 +; CHECK-NEXT: %a_ext = sext i32 %a to i64 +; CHECK-NEXT: %is_a_nonpositive = icmp ugt i64 %a_ext, 2 +; CHECK-NEXT: %min = select i1 %is_a_nonpositive, i64 %a_ext, i64 2 +; CHECK-NEXT: ret i64 %min +} From grosser at fim.uni-passau.de Fri Jan 7 15:39:16 2011 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Fri, 07 Jan 2011 16:39:16 -0500 Subject: [llvm-commits] [PATCH] Fix: instcombine does not get max if hidden by sext In-Reply-To: References: <4D22A780.6060209@fim.uni-passau.de> <48360275-C1A1-4AB1-A1A2-F5609C52094B@apple.com> <4D272A03.5030008@fim.uni-passau.de> <4D27737B.9040607@fim.uni-passau.de> Message-ID: <4D278804.5050405@fim.uni-passau.de> On 01/07/2011 03:36 PM, Frits van Bommel wrote: > On Fri, Jan 7, 2011 at 9:11 PM, Tobias Grosser > wrote: >> New version attached. > > You might be able to de-duplicate the sext case by using something like > /* Check for sext */ > else if (ICI->isUnsigned()) { > /* Check for zext */ > else > break; > } else > break; > (or the other way around) instead of > if (ICI->isSigned()) { > /* Check for sext */; > } else { > /* Check for sext and zext */ > } Right. Changed and retested. > You didn't include the test case patch this time, so I couldn't check > that, but it should be fine as long as you have a test for each of the > transformations mentioned at the top of the patch. I do. > Other than that, it looks fine to me (though I haven't completely > re-checked the logic this time). OK. Thanks. I committed the patch in 123034: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20110103/114784.html Tobi From evan.cheng at apple.com Fri Jan 7 15:38:59 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 07 Jan 2011 21:38:59 -0000 Subject: [llvm-commits] [llvm] r123036 - /llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Message-ID: <20110107213859.E63B82A6C12C@llvm.org> Author: evancheng Date: Fri Jan 7 15:38:59 2011 New Revision: 123036 URL: http://llvm.org/viewvc/llvm-project?rev=123036&view=rev Log: Fix comment. INLINEASM node operand #3 is IsAlignStack bit. Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=123036&r1=123035&r2=123036&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Fri Jan 7 15:38:59 2011 @@ -482,6 +482,7 @@ // Operand #0 : Input chain. // Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string. // Operand #2 : a MDNodeSDNode with the !srcloc metadata. + // Operand #3 : IsAlignStack bit. // After this, it is followed by a list of operands with this format: // ConstantSDNode: Flags that encode whether it is a mem or not, the // of operands that follow, etc. See InlineAsm.h. From bob.wilson at apple.com Fri Jan 7 15:42:31 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 7 Jan 2011 13:42:31 -0800 Subject: [llvm-commits] shufflevector on ARM (clumsy x-post from llvmdev) In-Reply-To: <4D2729D0.7030705@arm.com> References: <4D2729D0.7030705@arm.com> Message-ID: <6AEC1D65-D0F8-41ED-8E2A-F053FFF71A11@apple.com> On Jan 7, 2011, at 6:57 AM, Tim Northover wrote: > On 07/01/11 07:28, Bob Wilson wrote: > >> The extract_subvector patch looks good, except for the testsuite >> changes. Those tests are supposed to test spill code, and your patch >> causes them to stop spilling. I'll commit the patch after I fix the >> tests to continue spilling in spite of your change. > > Ah thanks. I'd convinced myself it was spilling, just slightly > differently. Glad you picked that up. You were right -- it was spilling. The difference was in whether there was an aligned stack slot for something other than a spill. I added an aligned alloca and that fixed the test. > >> The build_vector patch looks good, too. Can you also provide some tests >> that exercise this? (The test/CodeGen/ARM/vext.ll file would be a good >> place to put them.) > > Yep, I've attached the replacement patch (hopefully). > > It incorporates your comments and some tests that I believe exercise > most of the code (some is just there in case weird lowering creates > something unexpected and I can't actually produce an example). Looks good. I've committed it as svn 123035. > >> This new code will apply to <4 x i32> vectors. The following code to >> implement the BUILD_VECTOR by directly assigning subregisters will also >> handle that case.Have you looked at which is better? It might be better >> to swap the order of these. I suppose accessing S subregisters can be >> slow since the move instructions will run in the VFP pipeline and cause >> stalls on some processors > > I hadn't thought of anything so cunning. If both pieces of code apply > then the result is <4 x i32> and both source vectors are <4 x i32> as > well (if <2 x i32> I bail). I think this means that the result of my > code would be identical to a perfect shuffle with no added overhead (no > VEXTs). > > So assuming that perfect shuffles are indeed handled optimally the order > I gave happens to be correct. More by luck than judgement. OK, that makes sense to me. From dpatel at apple.com Fri Jan 7 16:26:26 2011 From: dpatel at apple.com (Devang Patel) Date: Fri, 07 Jan 2011 22:26:26 -0000 Subject: [llvm-commits] [llvm] r123038 - in /llvm/trunk: include/llvm-c/lto.h tools/lto/lto.cpp Message-ID: <20110107222626.165922A6C12C@llvm.org> Author: dpatel Date: Fri Jan 7 16:26:25 2011 New Revision: 123038 URL: http://llvm.org/viewvc/llvm-project?rev=123038&view=rev Log: Do not include DataTypes.h in llvm-c/lto.h. This means avoid using uint32_t. This patch reverts r112200 and fixes original problem by fixing argument type in lto.cpp. Modified: llvm/trunk/include/llvm-c/lto.h llvm/trunk/tools/lto/lto.cpp Modified: llvm/trunk/include/llvm-c/lto.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/lto.h?rev=123038&r1=123037&r2=123038&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/lto.h (original) +++ llvm/trunk/include/llvm-c/lto.h Fri Jan 7 16:26:25 2011 @@ -18,7 +18,6 @@ #include #include -#include "llvm/Support/DataTypes.h" #define LTO_API_VERSION 4 @@ -147,7 +146,7 @@ /** * Returns the number of symbols in the object module. */ -extern uint32_t +extern unsigned int lto_module_get_num_symbols(lto_module_t mod); @@ -155,14 +154,14 @@ * Returns the name of the ith symbol in the object module. */ extern const char* -lto_module_get_symbol_name(lto_module_t mod, uint32_t index); +lto_module_get_symbol_name(lto_module_t mod, unsigned int index); /** * Returns the attributes of the ith symbol in the object module. */ extern lto_symbol_attributes -lto_module_get_symbol_attribute(lto_module_t mod, uint32_t index); +lto_module_get_symbol_attribute(lto_module_t mod, unsigned int index); /** Modified: llvm/trunk/tools/lto/lto.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.cpp?rev=123038&r1=123037&r2=123038&view=diff ============================================================================== --- llvm/trunk/tools/lto/lto.cpp (original) +++ llvm/trunk/tools/lto/lto.cpp Fri Jan 7 16:26:25 2011 @@ -132,7 +132,7 @@ // // returns the number of symbols in the object module // -uint32_t lto_module_get_num_symbols(lto_module_t mod) +unsigned int lto_module_get_num_symbols(lto_module_t mod) { return mod->getSymbolCount(); } @@ -140,7 +140,7 @@ // // returns the name of the ith symbol in the object module // -const char* lto_module_get_symbol_name(lto_module_t mod, uint32_t index) +const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) { return mod->getSymbolName(index); } @@ -150,7 +150,7 @@ // returns the attributes of the ith symbol in the object module // lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod, - uint32_t index) + unsigned int index) { return mod->getSymbolAttributes(index); } From bob.wilson at apple.com Fri Jan 7 16:35:53 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 7 Jan 2011 14:35:53 -0800 Subject: [llvm-commits] [llvm] r122993 - in /llvm/trunk: include/llvm/CodeGen/ISDOpcodes.h lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp In-Reply-To: <4D26C65B.40104@free.fr> References: <20110107045856.34AB22A6C12C@llvm.org> <4D26C65B.40104@free.fr> Message-ID: On Jan 6, 2011, at 11:52 PM, Duncan Sands wrote: > Hi Bob, > >> Change EXTRACT_SUBVECTOR to require a constant index. > > how about storing the index as an "int" in the node, rather than using a > constant node? I just tried that. It seems to be more trouble than it's worth. There are as many places where it's easier to have a constant node (e.g., the ARM .td file and LegalizeDAG's ExpandExtractFromVectorThroughStack, which handles both EXTRACT_VECTOR_ELT and EXTRACT_SUBVECTOR) as there are places where an "int" is better. From dpatel at apple.com Fri Jan 7 16:33:41 2011 From: dpatel at apple.com (Devang Patel) Date: Fri, 07 Jan 2011 22:33:41 -0000 Subject: [llvm-commits] [llvm] r123039 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/LiveDebugVariables.cpp test/CodeGen/X86/2010-05-26-DotDebugLoc.ll test/CodeGen/X86/2010-05-28-Crash.ll test/CodeGen/X86/dbg-value-range.ll Message-ID: <20110107223341.653972A6C12C@llvm.org> Author: dpatel Date: Fri Jan 7 16:33:41 2011 New Revision: 123039 URL: http://llvm.org/viewvc/llvm-project?rev=123039&view=rev Log: Speculatively revert r123032. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll llvm/trunk/test/CodeGen/X86/2010-05-28-Crash.ll llvm/trunk/test/CodeGen/X86/dbg-value-range.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=123039&r1=123038&r2=123039&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Fri Jan 7 16:33:41 2011 @@ -2257,6 +2257,15 @@ } } +/// isDbgValueInUndefinedReg - Return true if debug value, encoded by +/// DBG_VALUE instruction, is in undefined reg. +static bool isDbgValueInUndefinedReg(const MachineInstr *MI) { + assert (MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!"); + if (MI->getOperand(0).isReg() && !MI->getOperand(0).getReg()) + return true; + return false; +} + /// isDbgValueInDefinedReg - Return true if debug value, encoded by /// DBG_VALUE instruction, is in a defined reg. static bool isDbgValueInDefinedReg(const MachineInstr *MI) { @@ -2281,7 +2290,7 @@ for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); II != IE; ++II) { const MachineInstr *MInsn = II; - if (!MInsn->isDebugValue()) + if (!MInsn->isDebugValue() || isDbgValueInUndefinedReg(MInsn)) continue; DbgValues.push_back(MInsn); } @@ -2303,18 +2312,19 @@ ME = DbgValues.end(); MI != ME; ++MI) { const MDNode *Var = (*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata(); - if (Var == DV && + if (Var == DV && isDbgValueInDefinedReg(*MI) && !PrevMI->isIdenticalTo(*MI)) MultipleValues.push_back(*MI); PrevMI = *MI; } - DbgScope *Scope = NULL; + DbgScope *Scope = findDbgScope(MInsn); + bool CurFnArg = false; if (DV.getTag() == dwarf::DW_TAG_arg_variable && DISubprogram(DV.getContext()).describes(MF->getFunction())) + CurFnArg = true; + if (!Scope && CurFnArg) Scope = CurrentFnDbgScope; - else - Scope = findDbgScope(MInsn); // If variable scope is not found then skip this variable. if (!Scope) continue; Modified: llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp?rev=123039&r1=123038&r2=123039&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp Fri Jan 7 16:33:41 2011 @@ -39,6 +39,10 @@ using namespace llvm; +static cl::opt +EnableLDV("live-debug-variables", + cl::desc("Enable the live debug variables pass"), cl::Hidden); + char LiveDebugVariables::ID = 0; INITIALIZE_PASS_BEGIN(LiveDebugVariables, "livedebugvars", @@ -618,6 +622,8 @@ } bool LiveDebugVariables::runOnMachineFunction(MachineFunction &mf) { + if (!EnableLDV) + return false; if (!pImpl) pImpl = new LDVImpl(this); return static_cast(pImpl)->runOnMachineFunction(mf); Modified: llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll?rev=123039&r1=123038&r2=123039&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll Fri Jan 7 16:33:41 2011 @@ -61,6 +61,6 @@ ; CHECK-NEXT: .short 1 ; CHECK-NEXT: .byte 85 ; CHECK-NEXT: .quad Ltmp3 -; CHECK-NEXT: .quad Ltmp6 +; CHECK-NEXT: .quad Lfunc_end ; CHECK-NEXT: .short 1 ; CHECK-NEXT: .byte 83 Modified: llvm/trunk/test/CodeGen/X86/2010-05-28-Crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-05-28-Crash.ll?rev=123039&r1=123038&r2=123039&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-05-28-Crash.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-05-28-Crash.ll Fri Jan 7 16:33:41 2011 @@ -39,5 +39,6 @@ !13 = metadata !{i32 7, i32 0, metadata !14, null} !14 = metadata !{i32 524299, metadata !8, i32 6, i32 0} ; [ DW_TAG_lexical_block ] -;CHECK:Ltmp8 +;CHECK: DEBUG_VALUE: bar:x <- EBX+0 +;CHECK-NEXT:Ltmp ;CHECK-NEXT: DEBUG_VALUE: foo:y <- 1+0 Modified: llvm/trunk/test/CodeGen/X86/dbg-value-range.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dbg-value-range.ll?rev=123039&r1=123038&r2=123039&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/dbg-value-range.ll (original) +++ llvm/trunk/test/CodeGen/X86/dbg-value-range.ll Fri Jan 7 16:33:41 2011 @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=x86_64-apple-darwin < %s | FileCheck %s +; XFAIL: * %struct.a = type { i32 } From matthewbg at google.com Fri Jan 7 16:34:58 2011 From: matthewbg at google.com (Matt Beaumont-Gay) Date: Fri, 07 Jan 2011 22:34:58 -0000 Subject: [llvm-commits] [llvm] r123040 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <20110107223458.A3DA52A6C12C@llvm.org> Author: matthewbg Date: Fri Jan 7 16:34:58 2011 New Revision: 123040 URL: http://llvm.org/viewvc/llvm-project?rev=123040&view=rev Log: Eliminate variable only used in debug builds. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=123040&r1=123039&r2=123040&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Jan 7 16:34:58 2011 @@ -3712,12 +3712,10 @@ // break it down again in a shuffle. return SDValue(); } - - unsigned SrcNumElts = SourceVecs[i].getValueType().getVectorNumElements(); // Since only 64-bit and 128-bit vectors are legal on ARM and // we've eliminated the other cases... - assert(SrcNumElts == 2*NumElts); + assert(SourceVecs[i].getValueType().getVectorNumElements() == 2*NumElts); if (MaxElts[i] - MinElts[i] >= NumElts) { // Span too large for a VEXT to cope From wendling at apple.com Fri Jan 7 16:45:31 2011 From: wendling at apple.com (Bill Wendling) Date: Fri, 7 Jan 2011 14:45:31 -0800 Subject: [llvm-commits] [llvm] r123040 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp In-Reply-To: <20110107223458.A3DA52A6C12C@llvm.org> References: <20110107223458.A3DA52A6C12C@llvm.org> Message-ID: <0ECE1585-1762-4A2C-88C9-307523FA56A8@apple.com> On Jan 7, 2011, at 2:34 PM, Matt Beaumont-Gay wrote: > Author: matthewbg > Date: Fri Jan 7 16:34:58 2011 > New Revision: 123040 > > URL: http://llvm.org/viewvc/llvm-project?rev=123040&view=rev > Log: > Eliminate variable only used in debug builds. > > Modified: > llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > > Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=123040&r1=123039&r2=123040&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Jan 7 16:34:58 2011 > @@ -3712,12 +3712,10 @@ > // break it down again in a shuffle. > return SDValue(); > } > - > - unsigned SrcNumElts = SourceVecs[i].getValueType().getVectorNumElements(); > > // Since only 64-bit and 128-bit vectors are legal on ARM and > // we've eliminated the other cases... > - assert(SrcNumElts == 2*NumElts); > + assert(SourceVecs[i].getValueType().getVectorNumElements() == 2*NumElts); > Could you provide an explanation string with this assert? -bw From matthewbg at google.com Fri Jan 7 17:18:16 2011 From: matthewbg at google.com (Matt Beaumont-Gay) Date: Fri, 7 Jan 2011 15:18:16 -0800 Subject: [llvm-commits] [llvm] r123040 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp In-Reply-To: <0ECE1585-1762-4A2C-88C9-307523FA56A8@apple.com> References: <20110107223458.A3DA52A6C12C@llvm.org> <0ECE1585-1762-4A2C-88C9-307523FA56A8@apple.com> Message-ID: Cc'ing the folks responsible for originally adding the assertion (in r123035). On Fri, Jan 7, 2011 at 14:45, Bill Wendling wrote: > On Jan 7, 2011, at 2:34 PM, Matt Beaumont-Gay wrote: > >> Author: matthewbg >> Date: Fri Jan ?7 16:34:58 2011 >> New Revision: 123040 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=123040&view=rev >> Log: >> Eliminate variable only used in debug builds. >> >> Modified: >> ? ?llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp >> >> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=123040&r1=123039&r2=123040&view=diff >> ============================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) >> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Jan ?7 16:34:58 2011 >> @@ -3712,12 +3712,10 @@ >> ? ? ? // break it down again in a shuffle. >> ? ? ? return SDValue(); >> ? ? } >> - >> - ? ?unsigned SrcNumElts = SourceVecs[i].getValueType().getVectorNumElements(); >> >> ? ? // Since only 64-bit and 128-bit vectors are legal on ARM and >> ? ? // we've eliminated the other cases... >> - ? ?assert(SrcNumElts == 2*NumElts); >> + ? ?assert(SourceVecs[i].getValueType().getVectorNumElements() == 2*NumElts); >> > Could you provide an explanation string with this assert? > > -bw > > From bob.wilson at apple.com Fri Jan 7 17:31:13 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 7 Jan 2011 15:31:13 -0800 Subject: [llvm-commits] [llvm] r123040 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp In-Reply-To: References: <20110107223458.A3DA52A6C12C@llvm.org> <0ECE1585-1762-4A2C-88C9-307523FA56A8@apple.com> Message-ID: <936FE860-AE94-49D4-84A8-BE14CE777688@apple.com> On Jan 7, 2011, at 3:18 PM, Matt Beaumont-Gay wrote: > Cc'ing the folks responsible for originally adding the assertion (in r123035). I'll add something. > > On Fri, Jan 7, 2011 at 14:45, Bill Wendling wrote: >> On Jan 7, 2011, at 2:34 PM, Matt Beaumont-Gay wrote: >> >>> Author: matthewbg >>> Date: Fri Jan 7 16:34:58 2011 >>> New Revision: 123040 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=123040&view=rev >>> Log: >>> Eliminate variable only used in debug builds. >>> >>> Modified: >>> llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp >>> >>> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=123040&r1=123039&r2=123040&view=diff >>> ============================================================================== >>> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) >>> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Jan 7 16:34:58 2011 >>> @@ -3712,12 +3712,10 @@ >>> // break it down again in a shuffle. >>> return SDValue(); >>> } >>> - >>> - unsigned SrcNumElts = SourceVecs[i].getValueType().getVectorNumElements(); >>> >>> // Since only 64-bit and 128-bit vectors are legal on ARM and >>> // we've eliminated the other cases... >>> - assert(SrcNumElts == 2*NumElts); >>> + assert(SourceVecs[i].getValueType().getVectorNumElements() == 2*NumElts); >>> >> Could you provide an explanation string with this assert? >> >> -bw >> >> From bob.wilson at apple.com Fri Jan 7 17:40:47 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 07 Jan 2011 23:40:47 -0000 Subject: [llvm-commits] [llvm] r123042 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <20110107234047.398B72A6C12C@llvm.org> Author: bwilson Date: Fri Jan 7 17:40:46 2011 New Revision: 123042 URL: http://llvm.org/viewvc/llvm-project?rev=123042&view=rev Log: Add an explanatory message for an assertion. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=123042&r1=123041&r2=123042&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Jan 7 17:40:46 2011 @@ -3715,7 +3715,8 @@ // Since only 64-bit and 128-bit vectors are legal on ARM and // we've eliminated the other cases... - assert(SourceVecs[i].getValueType().getVectorNumElements() == 2*NumElts); + assert(SourceVecs[i].getValueType().getVectorNumElements() == 2*NumElts && + "unexpected vector sizes in ReconstructShuffle"); if (MaxElts[i] - MinElts[i] >= NumElts) { // Span too large for a VEXT to cope From bob.wilson at apple.com Fri Jan 7 17:40:49 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 07 Jan 2011 23:40:49 -0000 Subject: [llvm-commits] [llvm] r123043 - /llvm/trunk/utils/TableGen/NeonEmitter.cpp Message-ID: <20110107234049.D1F362A6C12D@llvm.org> Author: bwilson Date: Fri Jan 7 17:40:49 2011 New Revision: 123043 URL: http://llvm.org/viewvc/llvm-project?rev=123043&view=rev Log: Use __builtin_shufflevector to implement vget_low and vget_high intrinsics. This was suggested by Edmund Grimley Evans in pr8411. Modified: llvm/trunk/utils/TableGen/NeonEmitter.cpp Modified: llvm/trunk/utils/TableGen/NeonEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/NeonEmitter.cpp?rev=123043&r1=123042&r2=123043&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/NeonEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/NeonEmitter.cpp Fri Jan 7 17:40:49 2011 @@ -576,9 +576,7 @@ std::string ts = TypeString(proto[0], typestr); std::string s; - if (op == OpHi || op == OpLo) { - s = "union { " + ts + " r; double d; } u; u.d = "; - } else if (!define) { + if (!define) { s = "return "; } @@ -727,10 +725,12 @@ s += ", (int64x1_t)__b, 0, 1);"; break; case OpHi: - s += "(((float64x2_t)__a)[1]);"; + s += "(" + ts + + ")__builtin_shufflevector((int64x2_t)__a, (int64x2_t)__a, 1);"; break; case OpLo: - s += "(((float64x2_t)__a)[0]);"; + s += "(" + ts + + ")__builtin_shufflevector((int64x2_t)__a, (int64x2_t)__a, 0);"; break; case OpDup: s += Duplicate(nElts, typestr, "__a") + ";"; @@ -804,11 +804,6 @@ throw "unknown OpKind!"; break; } - if (op == OpHi || op == OpLo) { - if (!define) - s += " return"; - s += " u.r;"; - } return s; } @@ -1135,11 +1130,6 @@ OS << " " << TypeString('d', TDTypeVec[i]) << ";\n"; } OS << "\n"; - OS << "typedef __attribute__((__vector_size__(8))) " - "double float64x1_t;\n"; - OS << "typedef __attribute__((__vector_size__(16))) " - "double float64x2_t;\n"; - OS << "\n"; // Emit struct typedefs. for (unsigned vi = 2; vi != 5; ++vi) { From wendling at apple.com Fri Jan 7 17:46:22 2011 From: wendling at apple.com (Bill Wendling) Date: Fri, 7 Jan 2011 15:46:22 -0800 Subject: [llvm-commits] [llvm] r123040 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp In-Reply-To: <936FE860-AE94-49D4-84A8-BE14CE777688@apple.com> References: <20110107223458.A3DA52A6C12C@llvm.org> <0ECE1585-1762-4A2C-88C9-307523FA56A8@apple.com> <936FE860-AE94-49D4-84A8-BE14CE777688@apple.com> Message-ID: <52D53949-6B13-404B-938F-DE079DFB614D@apple.com> On Jan 7, 2011, at 3:31 PM, Bob Wilson wrote: > On Jan 7, 2011, at 3:18 PM, Matt Beaumont-Gay wrote: > >> Cc'ing the folks responsible for originally adding the assertion (in r123035). > > I'll add something. > Thanks! -bw From evan.cheng at apple.com Fri Jan 7 17:50:32 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 07 Jan 2011 23:50:32 -0000 Subject: [llvm-commits] [llvm] r123044 - in /llvm/trunk: include/llvm/ include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/Target/ARM/ lib/Target/MBlaze/ lib/Target/X86/ test/CodeGen/X86/ Message-ID: <20110107235033.3E7602A6C12C@llvm.org> Author: evancheng Date: Fri Jan 7 17:50:32 2011 New Revision: 123044 URL: http://llvm.org/viewvc/llvm-project?rev=123044&view=rev Log: Do not model all INLINEASM instructions as having unmodelled side effects. Instead encode llvm IR level property "HasSideEffects" in an operand (shared with IsAlignStack). Added MachineInstrs::hasUnmodeledSideEffects() to check the operand when the instruction is an INLINEASM. This allows memory instructions to be moved around INLINEASM instructions. Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h llvm/trunk/include/llvm/CodeGen/MachineInstr.h llvm/trunk/include/llvm/InlineAsm.h llvm/trunk/include/llvm/Target/Target.td llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp llvm/trunk/lib/CodeGen/MachineCSE.cpp llvm/trunk/lib/CodeGen/MachineInstr.cpp llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp llvm/trunk/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp llvm/trunk/lib/Target/X86/X86FastISel.cpp llvm/trunk/test/CodeGen/X86/2008-09-17-inline-asm-1.ll Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Fri Jan 7 17:50:32 2011 @@ -482,7 +482,7 @@ // Operand #0 : Input chain. // Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string. // Operand #2 : a MDNodeSDNode with the !srcloc metadata. - // Operand #3 : IsAlignStack bit. + // Operand #3 : HasSideEffect, IsAlignStack bits. // After this, it is followed by a list of operands with this format: // ConstantSDNode: Flags that encode whether it is a mem or not, the // of operands that follow, etc. See InlineAsm.h. Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstr.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h Fri Jan 7 17:50:32 2011 @@ -237,6 +237,7 @@ bool isKill() const { return getOpcode() == TargetOpcode::KILL; } bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; } + bool isStackAligningInlineAsm() const; bool isInsertSubreg() const { return getOpcode() == TargetOpcode::INSERT_SUBREG; } @@ -432,6 +433,15 @@ /// return 0. unsigned isConstantValuePHI() const; + /// hasUnmodeledSideEffects - Return true if this instruction has side + /// effects that are not modeled by mayLoad / mayStore, etc. + /// For all instructions, the property is encoded in TargetInstrDesc::Flags + /// (see TargetInstrDesc::hasUnmodeledSideEffects(). The only exception is + /// INLINEASM instruction, in which case the side effect property is encoded + /// in one of its operands (see InlineAsm::Extra_HasSideEffect). + /// + bool hasUnmodeledSideEffects() const; + /// allDefsAreDead - Return true if all the defs of this instruction are dead. /// bool allDefsAreDead() const; Modified: llvm/trunk/include/llvm/InlineAsm.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InlineAsm.h?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/include/llvm/InlineAsm.h (original) +++ llvm/trunk/include/llvm/InlineAsm.h Fri Jan 7 17:50:32 2011 @@ -190,8 +190,15 @@ Op_InputChain = 0, Op_AsmString = 1, Op_MDNode = 2, - Op_IsAlignStack = 3, + Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack Op_FirstOperand = 4, + + MIOp_AsmString = 0, + MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack + MIOp_FirstOperand = 2, + + Extra_HasSideEffects = 1, + Extra_IsAlignStack = 2, Kind_RegUse = 1, Kind_RegDef = 2, Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Fri Jan 7 17:50:32 2011 @@ -418,6 +418,7 @@ let OutOperandList = (outs); let InOperandList = (ins variable_ops); let AsmString = ""; + let neverHasSideEffects = 1; // Note side effect is encoded in an operand. } def PROLOG_LABEL : Instruction { let OutOperandList = (outs); Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp Fri Jan 7 17:50:32 2011 @@ -304,7 +304,7 @@ // Okay, we finally have a value number. Ask the target to print this // operand! if (CurVariant == -1 || CurVariant == AsmPrinterVariant) { - unsigned OpNo = 2; + unsigned OpNo = InlineAsm::MIOp_FirstOperand; bool Error = false; Modified: llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp (original) +++ llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp Fri Jan 7 17:50:32 2011 @@ -54,6 +54,12 @@ } bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const { + // Technically speaking inline asm without side effects and no defs can still + // be deleted. But there is so much bad inline asm code out there, we should + // let them be. + if (MI->isInlineAsm()) + return false; + // Don't delete instructions with side effects. bool SawStore = false; if (!MI->isSafeToMove(TII, 0, SawStore) && !MI->isPHI()) Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Fri Jan 7 17:50:32 2011 @@ -262,7 +262,7 @@ // Ignore stuff that we obviously can't move. const TargetInstrDesc &TID = MI->getDesc(); if (TID.mayStore() || TID.isCall() || TID.isTerminator() || - TID.hasUnmodeledSideEffects()) + MI->hasUnmodeledSideEffects()) return false; if (TID.mayLoad()) { Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Fri Jan 7 17:50:32 2011 @@ -826,6 +826,14 @@ return NumOperands; } +bool MachineInstr::isStackAligningInlineAsm() const { + if (isInlineAsm()) { + unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); + if (ExtraInfo & InlineAsm::Extra_IsAlignStack) + return true; + } + return false; +} /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of /// the specific register or -1 if it is not found. It further tightens @@ -925,14 +933,15 @@ bool MachineInstr:: isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const { if (isInlineAsm()) { - assert(DefOpIdx >= 3); + assert(DefOpIdx > InlineAsm::MIOp_FirstOperand); const MachineOperand &MO = getOperand(DefOpIdx); if (!MO.isReg() || !MO.isDef() || MO.getReg() == 0) return false; // Determine the actual operand index that corresponds to this index. unsigned DefNo = 0; unsigned DefPart = 0; - for (unsigned i = 2, e = getNumOperands(); i < e; ) { + for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); + i < e; ) { const MachineOperand &FMO = getOperand(i); // After the normal asm operands there may be additional imp-def regs. if (!FMO.isImm()) @@ -947,7 +956,8 @@ } ++DefNo; } - for (unsigned i = 2, e = getNumOperands(); i != e; ++i) { + for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); + i != e; ++i) { const MachineOperand &FMO = getOperand(i); if (!FMO.isImm()) continue; @@ -990,7 +1000,8 @@ // Find the flag operand corresponding to UseOpIdx unsigned FlagIdx, NumOps=0; - for (FlagIdx = 2; FlagIdx < UseOpIdx; FlagIdx += NumOps+1) { + for (FlagIdx = InlineAsm::MIOp_FirstOperand; + FlagIdx < UseOpIdx; FlagIdx += NumOps+1) { const MachineOperand &UFMO = getOperand(FlagIdx); // After the normal asm operands there may be additional imp-def regs. if (!UFMO.isImm()) @@ -1008,9 +1019,9 @@ if (!DefOpIdx) return true; - unsigned DefIdx = 2; + unsigned DefIdx = InlineAsm::MIOp_FirstOperand; // Remember to adjust the index. First operand is asm string, second is - // the AlignStack bit, then there is a flag for each. + // the HasSideEffects and AlignStack bits, then there is a flag for each. while (DefNo) { const MachineOperand &FMO = getOperand(DefIdx); assert(FMO.isImm()); @@ -1117,7 +1128,7 @@ } if (isLabel() || isDebugValue() || - TID->isTerminator() || TID->hasUnmodeledSideEffects()) + TID->isTerminator() || hasUnmodeledSideEffects()) return false; // See if this instruction does a load. If so, we have to guarantee that the @@ -1168,7 +1179,7 @@ if (!TID->mayStore() && !TID->mayLoad() && !TID->isCall() && - !TID->hasUnmodeledSideEffects()) + !hasUnmodeledSideEffects()) return false; // Otherwise, if the instruction has no memory reference information, @@ -1242,6 +1253,18 @@ return Reg; } +bool MachineInstr::hasUnmodeledSideEffects() const { + if (getDesc().hasUnmodeledSideEffects()) + return true; + if (isInlineAsm()) { + unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); + if (ExtraInfo & InlineAsm::Extra_HasSideEffects) + return true; + } + + return false; +} + /// allDefsAreDead - Return true if all the defs of this instruction are dead. /// bool MachineInstr::allDefsAreDead() const { @@ -1329,6 +1352,24 @@ // Print the rest of the operands. bool OmittedAnyCallClobbers = false; bool FirstOp = true; + + if (isInlineAsm()) { + // Print asm string. + OS << " "; + getOperand(InlineAsm::MIOp_AsmString).print(OS, TM); + + // Print HasSideEffects, IsAlignStack + unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); + if (ExtraInfo & InlineAsm::Extra_HasSideEffects) + OS << " [sideeffect]"; + if (ExtraInfo & InlineAsm::Extra_IsAlignStack) + OS << " [alignstack]"; + + StartOp = InlineAsm::MIOp_FirstOperand; + FirstOp = false; + } + + for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { const MachineOperand &MO = getOperand(i); Modified: llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp (original) +++ llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp Fri Jan 7 17:50:32 2011 @@ -338,7 +338,7 @@ if (MI->isLabel() || MI->isPHI() || MI->isImplicitDef() || MI->isKill() || MI->isInlineAsm() || MI->isDebugValue() || - MI->getDesc().hasUnmodeledSideEffects()) + MI->hasUnmodeledSideEffects()) continue; if (MI->getDesc().isCompare()) { Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original) +++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Fri Jan 7 17:50:32 2011 @@ -21,6 +21,7 @@ #define DEBUG_TYPE "pei" #include "PrologEpilogInserter.h" +#include "llvm/InlineAsm.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineInstr.h" @@ -172,7 +173,8 @@ FrameSDOps.push_back(I); } else if (I->isInlineAsm()) { // Some inline asm's need a stack frame, as indicated by operand 1. - if (I->getOperand(1).getImm()) + unsigned ExtraInfo = I->getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); + if (ExtraInfo & InlineAsm::Extra_IsAlignStack) AdjustsStack = true; } Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Fri Jan 7 17:50:32 2011 @@ -410,7 +410,7 @@ // produce more precise dependence information. #define STORE_LOAD_LATENCY 1 unsigned TrueMemOrderLatency = 0; - if (TID.isCall() || TID.hasUnmodeledSideEffects() || + if (TID.isCall() || MI->hasUnmodeledSideEffects() || (MI->hasVolatileMemoryRef() && (!TID.mayLoad() || !MI->isInvariantLoad(AA)))) { // Be conservative with these and add dependencies on all memory Modified: llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp Fri Jan 7 17:50:32 2011 @@ -821,11 +821,11 @@ const char *AsmStr = cast(AsmStrV)->getSymbol(); MI->addOperand(MachineOperand::CreateES(AsmStr)); - // Add the isAlignStack bit. - int64_t isAlignStack = - cast(Node->getOperand(InlineAsm::Op_IsAlignStack))-> + // Add the HasSideEffect and isAlignStack bits. + int64_t ExtraInfo = + cast(Node->getOperand(InlineAsm::Op_ExtraInfo))-> getZExtValue(); - MI->addOperand(MachineOperand::CreateImm(isAlignStack)); + MI->addOperand(MachineOperand::CreateImm(ExtraInfo)); // Add all of the operand registers to the instruction. for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Fri Jan 7 17:50:32 2011 @@ -5738,9 +5738,14 @@ const MDNode *SrcLoc = CS.getInstruction()->getMetadata("srcloc"); AsmNodeOperands.push_back(DAG.getMDNode(SrcLoc)); - // Remember the AlignStack bit as operand 3. - AsmNodeOperands.push_back(DAG.getTargetConstant(IA->isAlignStack() ? 1 : 0, - MVT::i1)); + // Remember the HasSideEffect and AlignStack bits as operand 3. + unsigned ExtraInfo = 0; + if (IA->hasSideEffects()) + ExtraInfo |= InlineAsm::Extra_HasSideEffects; + if (IA->isAlignStack()) + ExtraInfo |= InlineAsm::Extra_IsAlignStack; + AsmNodeOperands.push_back(DAG.getTargetConstant(ExtraInfo, + TLI.getPointerTy())); // Loop over all of the inputs, copying the operand values into the // appropriate registers and processing the output regs. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Jan 7 17:50:32 2011 @@ -380,10 +380,8 @@ II = MBB->begin(), IE = MBB->end(); II != IE; ++II) { const TargetInstrDesc &TID = TM.getInstrInfo()->get(II->getOpcode()); - // Operand 1 of an inline asm instruction indicates whether the asm - // needs stack or not. - if ((II->isInlineAsm() && II->getOperand(1).getImm()) || - (TID.isCall() && !TID.isReturn())) { + if ((TID.isCall() && !TID.isReturn()) || + II->isStackAligningInlineAsm()) { MFI->setHasCalls(true); goto done; } @@ -1283,7 +1281,7 @@ Ops.push_back(InOps[InlineAsm::Op_InputChain]); // 0 Ops.push_back(InOps[InlineAsm::Op_AsmString]); // 1 Ops.push_back(InOps[InlineAsm::Op_MDNode]); // 2, !srcloc - Ops.push_back(InOps[InlineAsm::Op_IsAlignStack]); // 3 + Ops.push_back(InOps[InlineAsm::Op_ExtraInfo]); // 3 (SideEffect, AlignStack) unsigned i = InlineAsm::Op_FirstOperand, e = InOps.size(); if (InOps[e-1].getValueType() == MVT::Glue) Modified: llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp (original) +++ llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp Fri Jan 7 17:50:32 2011 @@ -329,8 +329,13 @@ const TargetInstrDesc &TID = MI->getDesc(); // Avoid instructions obviously unsafe for remat. - if (TID.hasUnmodeledSideEffects() || TID.isNotDuplicable() || - TID.mayStore()) + if (TID.isNotDuplicable() || TID.mayStore() || + MI->hasUnmodeledSideEffects()) + return false; + + // Don't remat inline asm. We have no idea how expensive it is + // even if it's side effect free. + if (MI->isInlineAsm()) return false; // Avoid instructions which load from potentially varying memory. Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp (original) +++ llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Fri Jan 7 17:50:32 2011 @@ -743,7 +743,7 @@ const TargetInstrDesc &TID = MI->getDesc(); if (TID.mayStore() || TID.isCall()) return false; - if (TID.isTerminator() || TID.hasUnmodeledSideEffects()) + if (TID.isTerminator() || MI->hasUnmodeledSideEffects()) return false; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { Modified: llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Fri Jan 7 17:50:32 2011 @@ -1620,9 +1620,16 @@ const TargetInstrDesc &TID = MI.getDesc(); if (TID.mayLoad() || TID.mayStore() || TID.isCall() || TID.isTerminator() || TID.isCall() || TID.isBarrier() || TID.isReturn() || - TID.hasUnmodeledSideEffects() || - MI.isLabel() || MI.isDebugValue()) + MI.isLabel() || MI.isDebugValue() || + MI.hasUnmodeledSideEffects()) return false; + + // Technically speaking inline asm without side effects and no defs can still + // be deleted. But there is so much bad inline asm code out there, we should + // let them be. + if (MI.isInlineAsm()) + return false; + for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); if (!MO.isReg() || !MO.getReg()) Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Fri Jan 7 17:50:32 2011 @@ -1467,7 +1467,7 @@ if (I->isDebugValue() || MemOps.count(&*I)) continue; const TargetInstrDesc &TID = I->getDesc(); - if (TID.isCall() || TID.isTerminator() || TID.hasUnmodeledSideEffects()) + if (TID.isCall() || TID.isTerminator() || I->hasUnmodeledSideEffects()) return false; if (isLd && TID.mayStore()) return false; Modified: llvm/trunk/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp Fri Jan 7 17:50:32 2011 @@ -187,9 +187,8 @@ return (brdesc.hasDelaySlot()); } -static bool hasUnknownSideEffects(MachineBasicBlock::iterator &I, - TargetInstrDesc &desc) { - if (!desc.hasUnmodeledSideEffects()) +static bool hasUnknownSideEffects(MachineBasicBlock::iterator &I) { + if (!I->hasUnmodeledSideEffects()) return false; unsigned op = I->getOpcode(); @@ -215,7 +214,7 @@ TargetInstrDesc desc = I->getDesc(); if (desc.hasDelaySlot() || desc.isBranch() || isDelayFiller(MBB,I) || desc.isCall() || desc.isReturn() || desc.isBarrier() || - hasUnknownSideEffects(I,desc)) + hasUnknownSideEffects(I)) break; if (hasImmInstruction(I) || delayHasHazard(I,slot)) Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Fri Jan 7 17:50:32 2011 @@ -1036,8 +1036,8 @@ } const TargetInstrDesc &TID = MI.getDesc(); - if (TID.hasUnmodeledSideEffects() || - TID.hasImplicitDefOfPhysReg(X86::EFLAGS)) + if (TID.hasImplicitDefOfPhysReg(X86::EFLAGS) || + MI.hasUnmodeledSideEffects()) break; } Modified: llvm/trunk/test/CodeGen/X86/2008-09-17-inline-asm-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-09-17-inline-asm-1.ll?rev=123044&r1=123043&r2=123044&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-09-17-inline-asm-1.ll (original) +++ llvm/trunk/test/CodeGen/X86/2008-09-17-inline-asm-1.ll Fri Jan 7 17:50:32 2011 @@ -15,14 +15,16 @@ 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-darwin8" - at x = common global i32 0 ; [#uses=1] + at x = common global i32 0 define i32 @aci(i32* %pw) nounwind { entry: - %0 = load i32* @x, align 4 ; [#uses=1] - %asmtmp = tail call { i32, i32 } asm "movl $0, %eax\0A\090:\0A\09test %eax, %eax\0A\09je 1f\0A\09movl %eax, $2\0A\09incl $2\0A\09lock\0A\09cmpxchgl $2, $0\0A\09jne 0b\0A\091:", "=*m,=&{ax},=&r,*m,~{dirflag},~{fpsr},~{flags},~{memory},~{cc}"(i32* %pw, i32* %pw) nounwind ; <{ i32, i32 }> [#uses=0] - %asmtmp2 = tail call { i32, i32 } asm "movl $0, %edx\0A\090:\0A\09test %edx, %edx\0A\09je 1f\0A\09movl %edx, $2\0A\09incl $2\0A\09lock\0A\09cmpxchgl $2, $0\0A\09jne 0b\0A\091:", "=*m,=&{dx},=&r,*m,~{dirflag},~{fpsr},~{flags},~{memory},~{cc}"(i32* %pw, i32* %pw) nounwind ; <{ i32, i32 }> [#uses=1] - %asmresult3 = extractvalue { i32, i32 } %asmtmp2, 0 ; [#uses=1] - %1 = add i32 %asmresult3, %0 ; [#uses=1] - ret i32 %1 + %0 = load i32* @x, align 4 + %asmtmp = tail call { i32, i32 } asm "movl $0, %eax\0A\090:\0A\09test %eax, %eax\0A\09je 1f\0A\09movl %eax, $2\0A\09incl $2\0A\09lock\0A\09cmpxchgl $2, $0\0A\09jne 0b\0A\091:", "=*m,=&{ax},=&r,*m,~{dirflag},~{fpsr},~{flags},~{memory},~{cc}"(i32* %pw, i32* %pw) nounwind + %asmtmp2 = tail call { i32, i32 } asm "movl $0, %edx\0A\090:\0A\09test %edx, %edx\0A\09je 1f\0A\09movl %edx, $2\0A\09incl $2\0A\09lock\0A\09cmpxchgl $2, $0\0A\09jne 0b\0A\091:", "=*m,=&{dx},=&r,*m,~{dirflag},~{fpsr},~{flags},~{memory},~{cc}"(i32* %pw, i32* %pw) nounwind + %asmresult2 = extractvalue { i32, i32 } %asmtmp, 0 + %asmresult3 = extractvalue { i32, i32 } %asmtmp2, 0 + %1 = add i32 %asmresult2, %asmresult3 + %2 = add i32 %0, %1 + ret i32 %2 } From evan.cheng at apple.com Fri Jan 7 19:24:27 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 08 Jan 2011 01:24:27 -0000 Subject: [llvm-commits] [llvm] r123048 - in /llvm/trunk: include/llvm/CodeGen/IntrinsicLowering.h lib/CodeGen/IntrinsicLowering.cpp lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/X86/X86ISelLowering.cpp test/CodeGen/ARM/bswap-inline-asm.ll test/CodeGen/X86/bswap-inline-asm.ll Message-ID: <20110108012427.BA87E2A6C12C@llvm.org> Author: evancheng Date: Fri Jan 7 19:24:27 2011 New Revision: 123048 URL: http://llvm.org/viewvc/llvm-project?rev=123048&view=rev Log: Recognize inline asm 'rev /bin/bash, ' as a bswap intrinsic call. Added: llvm/trunk/test/CodeGen/ARM/bswap-inline-asm.ll Modified: llvm/trunk/include/llvm/CodeGen/IntrinsicLowering.h llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/test/CodeGen/X86/bswap-inline-asm.ll Modified: llvm/trunk/include/llvm/CodeGen/IntrinsicLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/IntrinsicLowering.h?rev=123048&r1=123047&r2=123048&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/IntrinsicLowering.h (original) +++ llvm/trunk/include/llvm/CodeGen/IntrinsicLowering.h Fri Jan 7 19:24:27 2011 @@ -48,6 +48,11 @@ /// be capable of handling this kind of change. /// void LowerIntrinsicCall(CallInst *CI); + + /// LowerToByteSwap - Replace a call instruction into a call to bswap + /// intrinsic. Return false if it has determined the call is not a + /// simple integer bswap. + static bool LowerToByteSwap(CallInst *CI); }; } Modified: llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp?rev=123048&r1=123047&r2=123048&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp Fri Jan 7 19:24:27 2011 @@ -538,3 +538,27 @@ "Lowering should have eliminated any uses of the intrinsic call!"); CI->eraseFromParent(); } + +bool IntrinsicLowering::LowerToByteSwap(CallInst *CI) { + // Verify this is a simple bswap. + if (CI->getNumArgOperands() != 1 || + CI->getType() != CI->getArgOperand(0)->getType() || + !CI->getType()->isIntegerTy()) + return false; + + const IntegerType *Ty = dyn_cast(CI->getType()); + if (!Ty) + return false; + + // Okay, we can do this xform, do so now. + const Type *Tys[] = { Ty }; + Module *M = CI->getParent()->getParent()->getParent(); + Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Tys, 1); + + Value *Op = CI->getArgOperand(0); + Op = CallInst::Create(Int, Op, CI->getName(), CI); + + CI->replaceAllUsesWith(Op); + CI->eraseFromParent(); + return true; +} Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=123048&r1=123047&r2=123048&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Fri Jan 7 19:24:27 2011 @@ -2071,7 +2071,6 @@ if (!ItinData || ItinData->isEmpty()) return DefTID.mayLoad() ? 3 : 1; - const TargetInstrDesc &UseTID = UseMI->getDesc(); const MachineOperand &DefMO = DefMI->getOperand(DefIdx); if (DefMO.getReg() == ARM::CPSR) { Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=123048&r1=123047&r2=123048&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Jan 7 19:24:27 2011 @@ -33,6 +33,7 @@ #include "llvm/Intrinsics.h" #include "llvm/Type.h" #include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/IntrinsicLowering.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -43,6 +44,7 @@ #include "llvm/MC/MCSectionMachO.h" #include "llvm/Target/TargetOptions.h" #include "llvm/ADT/VectorExtras.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" @@ -6092,6 +6094,37 @@ // ARM Inline Assembly Support //===----------------------------------------------------------------------===// +bool ARMTargetLowering::ExpandInlineAsm(CallInst *CI) const { + // Looking for "rev" which is V6+. + if (!Subtarget->hasV6Ops()) + return false; + + InlineAsm *IA = cast(CI->getCalledValue()); + std::string AsmStr = IA->getAsmString(); + SmallVector AsmPieces; + SplitString(AsmStr, AsmPieces, ";\n"); + + switch (AsmPieces.size()) { + default: return false; + case 1: + AsmStr = AsmPieces[0]; + AsmPieces.clear(); + SplitString(AsmStr, AsmPieces, " \t,"); + + // rev $0, $1 + if (AsmPieces.size() == 3 && + AsmPieces[0] == "rev" && AsmPieces[1] == "$0" && AsmPieces[2] == "$1" && + IA->getConstraintString().compare(0, 4, "=l,l") == 0) { + const IntegerType *Ty = dyn_cast(CI->getType()); + if (Ty && Ty->getBitWidth() == 32) + return IntrinsicLowering::LowerToByteSwap(CI); + } + break; + } + + return false; +} + /// getConstraintType - Given a constraint letter, return the type of /// constraint it is for this target. ARMTargetLowering::ConstraintType Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=123048&r1=123047&r2=123048&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Fri Jan 7 19:24:27 2011 @@ -257,6 +257,8 @@ unsigned Depth) const; + virtual bool ExpandInlineAsm(CallInst *CI) const; + ConstraintType getConstraintType(const std::string &Constraint) const; /// Examine constraint string and operand type and determine a weight value. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=123048&r1=123047&r2=123048&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Jan 7 19:24:27 2011 @@ -28,6 +28,7 @@ #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/LLVMContext.h" +#include "llvm/CodeGen/IntrinsicLowering.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -11729,38 +11730,8 @@ // X86 Inline Assembly Support //===----------------------------------------------------------------------===// -static bool LowerToBSwap(CallInst *CI) { - // FIXME: this should verify that we are targetting a 486 or better. If not, - // we will turn this bswap into something that will be lowered to logical ops - // instead of emitting the bswap asm. For now, we don't support 486 or lower - // so don't worry about this. - - // Verify this is a simple bswap. - if (CI->getNumArgOperands() != 1 || - CI->getType() != CI->getArgOperand(0)->getType() || - !CI->getType()->isIntegerTy()) - return false; - - const IntegerType *Ty = dyn_cast(CI->getType()); - if (!Ty || Ty->getBitWidth() % 16 != 0) - return false; - - // Okay, we can do this xform, do so now. - const Type *Tys[] = { Ty }; - Module *M = CI->getParent()->getParent()->getParent(); - Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Tys, 1); - - Value *Op = CI->getArgOperand(0); - Op = CallInst::Create(Int, Op, CI->getName(), CI); - - CI->replaceAllUsesWith(Op); - CI->eraseFromParent(); - return true; -} - bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const { InlineAsm *IA = cast(CI->getCalledValue()); - InlineAsm::ConstraintInfoVector Constraints = IA->ParseConstraints(); std::string AsmStr = IA->getAsmString(); @@ -11775,6 +11746,10 @@ AsmPieces.clear(); SplitString(AsmStr, AsmPieces, " \t"); // Split with whitespace. + // FIXME: this should verify that we are targetting a 486 or better. If not, + // we will turn this bswap into something that will be lowered to logical ops + // instead of emitting the bswap asm. For now, we don't support 486 or lower + // so don't worry about this. // bswap $0 if (AsmPieces.size() == 2 && (AsmPieces[0] == "bswap" || @@ -11784,7 +11759,10 @@ AsmPieces[1] == "${0:q}")) { // No need to check constraints, nothing other than the equivalent of // "=r,0" would be valid here. - return LowerToBSwap(CI); + const IntegerType *Ty = dyn_cast(CI->getType()); + if (!Ty || Ty->getBitWidth() % 16 != 0) + return false; + return IntrinsicLowering::LowerToByteSwap(CI); } // rorw $$8, ${0:w} --> llvm.bswap.i16 if (CI->getType()->isIntegerTy(16) && @@ -11794,15 +11772,18 @@ AsmPieces[2] == "${0:w}" && IA->getConstraintString().compare(0, 5, "=r,0,") == 0) { AsmPieces.clear(); - const std::string &Constraints = IA->getConstraintString(); - SplitString(StringRef(Constraints).substr(5), AsmPieces, ","); + const std::string &ConstraintsStr = IA->getConstraintString(); + SplitString(StringRef(ConstraintsStr).substr(5), AsmPieces, ","); std::sort(AsmPieces.begin(), AsmPieces.end()); if (AsmPieces.size() == 4 && AsmPieces[0] == "~{cc}" && AsmPieces[1] == "~{dirflag}" && AsmPieces[2] == "~{flags}" && AsmPieces[3] == "~{fpsr}") { - return LowerToBSwap(CI); + const IntegerType *Ty = dyn_cast(CI->getType()); + if (!Ty || Ty->getBitWidth() % 16 != 0) + return false; + return IntrinsicLowering::LowerToByteSwap(CI); } } break; @@ -11822,36 +11803,45 @@ if (Words.size() == 3 && Words[0] == "rorw" && Words[1] == "$$8" && Words[2] == "${0:w}") { AsmPieces.clear(); - const std::string &Constraints = IA->getConstraintString(); - SplitString(StringRef(Constraints).substr(5), AsmPieces, ","); + const std::string &ConstraintsStr = IA->getConstraintString(); + SplitString(StringRef(ConstraintsStr).substr(5), AsmPieces, ","); std::sort(AsmPieces.begin(), AsmPieces.end()); if (AsmPieces.size() == 4 && AsmPieces[0] == "~{cc}" && AsmPieces[1] == "~{dirflag}" && AsmPieces[2] == "~{flags}" && AsmPieces[3] == "~{fpsr}") { - return LowerToBSwap(CI); + const IntegerType *Ty = dyn_cast(CI->getType()); + if (!Ty || Ty->getBitWidth() % 16 != 0) + return false; + return IntrinsicLowering::LowerToByteSwap(CI); } } } } } - if (CI->getType()->isIntegerTy(64) && - Constraints.size() >= 2 && - Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" && - Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") { - // bswap %eax / bswap %edx / xchgl %eax, %edx -> llvm.bswap.i64 - SmallVector Words; - SplitString(AsmPieces[0], Words, " \t"); - if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%eax") { - Words.clear(); - SplitString(AsmPieces[1], Words, " \t"); - if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%edx") { + + if (CI->getType()->isIntegerTy(64)) { + InlineAsm::ConstraintInfoVector Constraints = IA->ParseConstraints(); + if (Constraints.size() >= 2 && + Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" && + Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") { + // bswap %eax / bswap %edx / xchgl %eax, %edx -> llvm.bswap.i64 + SmallVector Words; + SplitString(AsmPieces[0], Words, " \t"); + if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%eax") { Words.clear(); - SplitString(AsmPieces[2], Words, " \t,"); - if (Words.size() == 3 && Words[0] == "xchgl" && Words[1] == "%eax" && - Words[2] == "%edx") { - return LowerToBSwap(CI); + SplitString(AsmPieces[1], Words, " \t"); + if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%edx") { + Words.clear(); + SplitString(AsmPieces[2], Words, " \t,"); + if (Words.size() == 3 && Words[0] == "xchgl" && Words[1] == "%eax" && + Words[2] == "%edx") { + const IntegerType *Ty = dyn_cast(CI->getType()); + if (!Ty || Ty->getBitWidth() % 16 != 0) + return false; + return IntrinsicLowering::LowerToByteSwap(CI); + } } } } Added: llvm/trunk/test/CodeGen/ARM/bswap-inline-asm.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/bswap-inline-asm.ll?rev=123048&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/bswap-inline-asm.ll (added) +++ llvm/trunk/test/CodeGen/ARM/bswap-inline-asm.ll Fri Jan 7 19:24:27 2011 @@ -0,0 +1,9 @@ +; RUN: llc < %s -mtriple=arm-apple-darwin -mattr=+v6 | FileCheck %s + +define i32 @t1(i32 %x) nounwind { +; CHECK: t1: +; CHECK-NOT: InlineAsm +; CHECK: rev + %asmtmp = tail call i32 asm "rev $0, $1\0A", "=l,l"(i32 %x) nounwind + ret i32 %asmtmp +} Modified: llvm/trunk/test/CodeGen/X86/bswap-inline-asm.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bswap-inline-asm.ll?rev=123048&r1=123047&r2=123048&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/bswap-inline-asm.ll (original) +++ llvm/trunk/test/CodeGen/X86/bswap-inline-asm.ll Fri Jan 7 19:24:27 2011 @@ -1,5 +1,5 @@ -; RUN: llc < %s -march=x86-64 > %t -; RUN: not grep APP %t +; RUN: llc < %s -mtriple=x86_64-apple-darwin > %t +; RUN: not grep InlineAsm %t ; RUN: FileCheck %s < %t ; CHECK: foo: From benny.kra at googlemail.com Fri Jan 7 19:44:21 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Sat, 8 Jan 2011 02:44:21 +0100 Subject: [llvm-commits] [llvm] r123034 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineSelect.cpp test/Transforms/InstCombine/select.ll In-Reply-To: <20110107213315.0085B2A6C12D@llvm.org> References: <20110107213315.0085B2A6C12D@llvm.org> Message-ID: <888D394F-773B-453E-BE5C-4D92DA1B00C5@gmail.com> On 07.01.2011, at 22:33, Tobias Grosser wrote: > Author: grosser > Date: Fri Jan 7 15:33:14 2011 > New Revision: 123034 > > URL: http://llvm.org/viewvc/llvm-project?rev=123034&view=rev > Log: > InstCombine: Match min/max hidden by sext/zext > > X = sext x; x >s c ? X : C+1 --> X = sext x; X X = sext x; x X = sext x; X >s C-1 ? C-1 : X > X = zext x; x >u c ? X : C+1 --> X = zext x; X X = zext x; x X = zext x; X >u C-1 ? C-1 : X > X = sext x; x >u c ? X : C+1 --> X = sext x; X X = sext x; x X = sext x; X >u C-1 ? C-1 : X > > Instead of calculating this with mixed types promote all to the > larger type. This enables scalar evolution to analyze this > expression. PR8866 > > Modified: > llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp > llvm/trunk/test/Transforms/InstCombine/select.ll > > Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=123034&r1=123033&r2=123034&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original) > +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Fri Jan 7 15:33:14 2011 > @@ -285,48 +285,83 @@ > // place here, so make sure the select is the only user. > if (ICI->hasOneUse()) > if (ConstantInt *CI = dyn_cast(CmpRHS)) { > + // X < MIN ? T : F --> F > + if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_ULT) > + && CI->isMinValue(Pred == ICmpInst::ICMP_SLT)) > + return ReplaceInstUsesWith(SI, FalseVal); > + // X > MAX ? T : F --> F > + else if ((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_UGT) > + && CI->isMaxValue(Pred == ICmpInst::ICMP_SGT)) > + return ReplaceInstUsesWith(SI, FalseVal); > switch (Pred) { > default: break; > case ICmpInst::ICMP_ULT: > - case ICmpInst::ICMP_SLT: { > - // X < MIN ? T : F --> F > - if (CI->isMinValue(Pred == ICmpInst::ICMP_SLT)) > - return ReplaceInstUsesWith(SI, FalseVal); > - // X < C ? X : C-1 --> X > C-1 ? C-1 : X > - Constant *AdjustedRHS = > - ConstantInt::get(CI->getContext(), CI->getValue()-1); > - if ((CmpLHS == TrueVal && AdjustedRHS == FalseVal) || > - (CmpLHS == FalseVal && AdjustedRHS == TrueVal)) { > - Pred = ICmpInst::getSwappedPredicate(Pred); > - CmpRHS = AdjustedRHS; > - std::swap(FalseVal, TrueVal); > - ICI->setPredicate(Pred); > - ICI->setOperand(1, CmpRHS); > - SI.setOperand(1, TrueVal); > - SI.setOperand(2, FalseVal); > - Changed = true; > - } > - break; > - } > + case ICmpInst::ICMP_SLT: > case ICmpInst::ICMP_UGT: > case ICmpInst::ICMP_SGT: { > - // X > MAX ? T : F --> F > - if (CI->isMaxValue(Pred == ICmpInst::ICMP_SGT)) > - return ReplaceInstUsesWith(SI, FalseVal); > + Constant *AdjustedRHS; > + if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_SGT) > + AdjustedRHS = ConstantInt::get(CI->getContext(), CI->getValue() + 1); > + else // (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SLT) > + AdjustedRHS = ConstantInt::get(CI->getContext(), CI->getValue() - 1); > + > // X > C ? X : C+1 --> X < C+1 ? C+1 : X > - Constant *AdjustedRHS = > - ConstantInt::get(CI->getContext(), CI->getValue()+1); > + // X < C ? X : C-1 --> X > C-1 ? C-1 : X > if ((CmpLHS == TrueVal && AdjustedRHS == FalseVal) || > - (CmpLHS == FalseVal && AdjustedRHS == TrueVal)) { > - Pred = ICmpInst::getSwappedPredicate(Pred); > - CmpRHS = AdjustedRHS; > - std::swap(FalseVal, TrueVal); > - ICI->setPredicate(Pred); > - ICI->setOperand(1, CmpRHS); > - SI.setOperand(1, TrueVal); > - SI.setOperand(2, FalseVal); > - Changed = true; > - } > + (CmpLHS == FalseVal && AdjustedRHS == TrueVal)) > + ; // Nothing to do here. Values match without any sign/zero extension. > + > + // Types do not match. Instead of calculating this with mixed types > + // promote all to the larger type. This enables scalar evolution to > + // analyze this expression. > + else if (CmpRHS->getType()->getScalarSizeInBits() > + < SI.getType()->getScalarSizeInBits()) { > + Constant *sextRHS = ConstantExpr::getSExt(AdjustedRHS, > + SI.getType()); Hi Tobias, This line (ConstantExpr::getSExt) hits an assertion failure in some files in the test suite MultiSource/Applications/JM/lencod/lencod MultiSource/Applications/oggenc/oggenc MultiSource/Benchmarks/MiBench/consumer-lame/consumer-lame SingleSource/Benchmarks/Misc/perlin The assert is: Assertion failed: (Ty->isIntOrIntVectorTy() && "SExt produces only integer"), function getSExt, file Constants.cpp, line 1268. And the offending IR is: %175 = sitofp i32 %j.3 to double %174 = icmp slt i32 %j.3, 2 %176 = select i1 %174, double 2.000000e+00, double %175 From echristo at apple.com Fri Jan 7 19:52:20 2011 From: echristo at apple.com (Eric Christopher) Date: Sat, 08 Jan 2011 01:52:20 -0000 Subject: [llvm-commits] [llvm] r123051 - /llvm/trunk/utils/buildit/build_llvm Message-ID: <20110108015220.E72C12A6C12C@llvm.org> Author: echristo Date: Fri Jan 7 19:52:20 2011 New Revision: 123051 URL: http://llvm.org/viewvc/llvm-project?rev=123051&view=rev Log: I don't think I could find a 10.2.x box if I tried. Modified: llvm/trunk/utils/buildit/build_llvm Modified: llvm/trunk/utils/buildit/build_llvm URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/buildit/build_llvm?rev=123051&r1=123050&r2=123051&view=diff ============================================================================== --- llvm/trunk/utils/buildit/build_llvm (original) +++ llvm/trunk/utils/buildit/build_llvm Fri Jan 7 19:52:20 2011 @@ -174,11 +174,6 @@ # Figure out how many make processes to run. SYSCTL=`sysctl -n hw.activecpu` - # hw.activecpu only available in 10.2.6 and later - if [ -z "$SYSCTL" ]; then - SYSCTL=`sysctl -n hw.ncpu` - fi - # sysctl -n hw.* does not work when invoked via B&I chroot /BuildRoot. # Builders can default to 2, since even if they are single processor, # nothing else is running on the machine. From clattner at apple.com Fri Jan 7 20:02:09 2011 From: clattner at apple.com (Chris Lattner) Date: Fri, 7 Jan 2011 18:02:09 -0800 Subject: [llvm-commits] [llvm] r123048 - in /llvm/trunk: include/llvm/CodeGen/IntrinsicLowering.h lib/CodeGen/IntrinsicLowering.cpp lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/X86/X86ISelLowering.cpp test/CodeGen/ARM/bswap-inline-asm.ll test/CodeGen/X86/bswap-inline-asm.ll In-Reply-To: <20110108012427.BA87E2A6C12C@llvm.org> References: <20110108012427.BA87E2A6C12C@llvm.org> Message-ID: <7F520A19-4C69-45EF-93D9-215A7D1EE1E3@apple.com> On Jan 7, 2011, at 5:24 PM, Evan Cheng wrote: > URL: http://llvm.org/viewvc/llvm-project?rev=123048&view=rev > Log: > Recognize inline asm 'rev /bin/bash, ' as a bswap intrinsic call. Reversing bash eh? Nice instruction! A comment: > + /// LowerToByteSwap - Replace a call instruction into a call to bswap > + /// intrinsic. Return false if it has determined the call is not a > + /// simple integer bswap. > + static bool LowerToByteSwap(CallInst *CI); Instead of having it be layered like this, I'd prefer that you add an IRBuilder::CreateBSwap operation (just like CreateMemSet) and use that. This means that you'll be creating a new call (+ RAUW) then deleting the old one, but the compile time impact doesn't matter in this case. -Chris From rafael.espindola at gmail.com Fri Jan 7 21:56:19 2011 From: rafael.espindola at gmail.com (=?ISO-8859-1?Q?Rafael_=C1vila_de_Esp=EDndola?=) Date: Fri, 07 Jan 2011 22:56:19 -0500 Subject: [llvm-commits] [patch][8927] Add an unnamed_addr attribute Message-ID: <4D27E063.6060605@gmail.com> This is the first step in fixing PR8927: The attached patch adds a unnamed_addr bit to global constants and functions. This will be used to indicate that the address is not significant and therefore the constant or function can be merged with others. If an optimization pass can show that an address is not used, it can set this. Examples of things that can have this set by the FE are globals created to hold string literals and C++ constructors. Aliases and non constant globals are not allowed to have unnamed_addr since I couldn't figure out any use for it. Comments? Cheers, Rafael -------------- next part -------------- A non-text attachment was scrubbed... Name: unnamed_addr.patch Type: text/x-patch Size: 16760 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110107/da56720a/attachment.bin From clattner at apple.com Sat Jan 8 00:45:48 2011 From: clattner at apple.com (Chris Lattner) Date: Fri, 7 Jan 2011 22:45:48 -0800 Subject: [llvm-commits] [patch][8927] Add an unnamed_addr attribute In-Reply-To: <4D27E063.6060605@gmail.com> References: <4D27E063.6060605@gmail.com> Message-ID: <7F35CC51-49B3-4DF4-8921-FAB062D6B8DD@apple.com> On Jan 7, 2011, at 7:56 PM, Rafael ?vila de Esp?ndola wrote: > This is the first step in fixing PR8927: > > The attached patch adds a unnamed_addr bit to global constants and functions. This will be used to indicate that the address is not significant and therefore the constant or function can be merged with others. > > If an optimization pass can show that an address is not used, it can set this. > > Examples of things that can have this set by the FE are globals created to hold string literals and C++ constructors. > > Aliases and This patch looks great except for: > non constant globals are not allowed to have unnamed_addr since I couldn't figure out any use for it. I also can't figure out any use for it in C, but I don't think that the verifier should reject this. The property is orthogonal from immutability. Here's a contrived example where it could be useful: imagine a language that doesn't have pointer comparisons: in that language the frontend could mark all globals as unnamed_addr, regardless of whether they are const or not. If the optimizer realizes later that there are no stores to a global, it could be marked const, and then (because it has the attr) merged with other constant globals. Does that make any sense? -Chris From clattner at apple.com Sat Jan 8 00:52:59 2011 From: clattner at apple.com (Chris Lattner) Date: Fri, 7 Jan 2011 22:52:59 -0800 Subject: [llvm-commits] [llvm] r122959 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/objsize.ll In-Reply-To: References: <20110106131105.59E222A6C12C@llvm.org> <36B13217-CC55-4CF9-9570-1ECCD6389A62@apple.com> Message-ID: <96404383-9073-4D74-8FE3-65CF220AC676@apple.com> On Jan 7, 2011, at 12:49 PM, Benjamin Kramer wrote: >> >> Before this change, codegenprepare folded the strcpy_chk to strcpy because it treated the malloc size as unknown. Now, it knows the malloc size but not the source size, so it's keeping the strcpy_chk. The ds() function is inlined to lots of places, so the effect is greatly magnified. In this case, it ought to be possible to recognize that the source is the same size as the destination and have instcombine fold to strcpy. Could you look into doing that, or at least add a comment to the README file about it? > > I reverted the change for now, there is another issue with this as it changes the semantics of __builtin_objectsize. > Unless we want to extend this GCC extension even more my patch is not safe in it's current form :( What exactly is the issue here? While I'm sympathetic to the "cdecl.c/ds" regression, I still think that your patch is a good route forward. Optimizing to "know" the strlen size seems like a nice second step. However, if your patch wasn't safe, then it clearly isn't good. What is the issue? -Chris From clattner at apple.com Sat Jan 8 00:55:33 2011 From: clattner at apple.com (Chris Lattner) Date: Fri, 7 Jan 2011 22:55:33 -0800 Subject: [llvm-commits] [PATCH] Bug 889: make FixedNumOperandTraits and VariadicOperandTraits more robust In-Reply-To: References: Message-ID: <130284C5-14F1-42EB-84F8-5D84ABAF1C2A@apple.com> On Jan 5, 2011, at 7:29 AM, Jay Foad wrote: > http://llvm.org/bugs/show_bug.cgi?id=889 > > This bug is about removing virtual methods from Value and its subclasses. Nice. It would be really great to fix this. Doing so will save 8 bytes off *every* IR object when the compiler is built for 64-bit. This is "a big deal" :). > While playing with fixes for this bug, I noticed that > FixedNumOperandTraits and VariadicOperandTraits only work for > subclasses of User, where the instance data for User is at offset 0 in > the instance data for the subclass. However, if the subclass has > virtual methods but User does not, this is no longer true. (There are > probably other cases where it would not be true, e.g. for a subclass > that inherits from multiple base classes, and User is not the first > base class.) > > The attached patch fixes this by making FixedNumOperandTraits and > VariadicOperandTraits take an extra template argument specifying the > type of the subclass. It passes "make check". Makes sense: it is a good intermediate step before zapping all virtual methods, looks great to me! -Chris From sabre at nondot.org Sat Jan 8 01:21:31 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Jan 2011 07:21:31 -0000 Subject: [llvm-commits] [llvm] r123057 - /llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Message-ID: <20110108072131.720452A6C12C@llvm.org> Author: lattner Date: Sat Jan 8 01:21:31 2011 New Revision: 123057 URL: http://llvm.org/viewvc/llvm-project?rev=123057&view=rev Log: two minor changes: switch to the standard ValueToValueMapTy map from ValueMapper.h (giving us access to its utilities) and add a fastpath in the loop rotation code, avoiding expensive ssa updator manipulation for values with nothing to update. Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=123057&r1=123056&r2=123057&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sat Jan 8 01:21:31 2011 @@ -21,10 +21,10 @@ #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/SSAUpdater.h" +#include "llvm/Transforms/Utils/ValueMapper.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" -#include "llvm/ADT/SmallVector.h" using namespace llvm; #define MAX_HEADER_SIZE 16 @@ -177,7 +177,7 @@ // Begin by walking OrigHeader and populating ValueMap with an entry for // each Instruction. BasicBlock::iterator I = OrigHeader->begin(), E = OrigHeader->end(); - DenseMap ValueMap; + ValueToValueMapTy ValueMap; // For PHI nodes, the value available in OldPreHeader is just the // incoming value from OldPreHeader. @@ -233,6 +233,11 @@ Value *OrigHeaderVal = I; Value *OrigPreHeaderVal = ValueMap[OrigHeaderVal]; + // If there are no uses of the value (e.g. because it returns void), there + // is nothing to rewrite. + if (OrigHeaderVal->use_empty() && OrigPreHeaderVal->use_empty()) + continue; + // The value now exits in two versions: the initial value in the preheader // and the loop "next" value in the original header. SSA.Initialize(OrigHeaderVal->getType(), OrigHeaderVal->getName()); From sabre at nondot.org Sat Jan 8 02:15:20 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Jan 2011 08:15:20 -0000 Subject: [llvm-commits] [llvm] r123058 - in /llvm/trunk: include/llvm/Transforms/Utils/ValueMapper.h lib/Linker/LinkModules.cpp lib/Transforms/Scalar/LoopRotation.cpp lib/Transforms/Scalar/LoopUnswitch.cpp lib/Transforms/Utils/CloneFunction.cpp lib/Transforms/Utils/CloneModule.cpp lib/Transforms/Utils/ValueMapper.cpp Message-ID: <20110108081520.F125B2A6C12C@llvm.org> Author: lattner Date: Sat Jan 8 02:15:20 2011 New Revision: 123058 URL: http://llvm.org/viewvc/llvm-project?rev=123058&view=rev Log: Revamp the ValueMapper interfaces in a couple ways: 1. Take a flags argument instead of a bool. This makes it more clear to the reader what it is used for. 2. Add a flag that says that "remapping a value not in the map is ok". 3. Reimplement MapValue to share a bunch of code and be a lot more efficient. For lookup failures, don't drop null values into the map. 4. Using the new flag a bunch of code can vaporize in LinkModules and LoopUnswitch, kill it. No functionality change. Modified: llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h llvm/trunk/lib/Linker/LinkModules.cpp llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp llvm/trunk/lib/Transforms/Utils/CloneModule.cpp llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h?rev=123058&r1=123057&r2=123058&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h Sat Jan 8 02:15:20 2011 @@ -22,10 +22,29 @@ class Instruction; typedef ValueMap > ValueToValueMapTy; + /// RemapFlags - These are flags that the value mapping APIs allow. + enum RemapFlags { + RF_None = 0, + + /// RF_NoModuleLevelChanges - If this flag is set, the remapper knows that + /// only local values within a function (such as an instruction or argument) + /// are mapped, not global values like functions and global metadata. + RF_NoModuleLevelChanges = 1, + + /// RF_IgnoreMissingEntries - If this flag is set, the remapper ignores + /// entries that are not in the value map. If it is unset, it aborts if an + /// operand is asked to be remapped which doesn't exist in the mapping. + RF_IgnoreMissingEntries = 2 + }; + + static inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) { + return RemapFlags(unsigned(LHS)|unsigned(RHS)); + } + Value *MapValue(const Value *V, ValueToValueMapTy &VM, - bool ModuleLevelChanges); + RemapFlags Flags = RF_None); void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, - bool ModuleLevelChanges); + RemapFlags Flags = RF_None); } // End llvm namespace #endif Modified: llvm/trunk/lib/Linker/LinkModules.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=123058&r1=123057&r2=123058&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp (original) +++ llvm/trunk/lib/Linker/LinkModules.cpp Sat Jan 8 02:15:20 2011 @@ -451,8 +451,7 @@ // Add Src elements into Dest node. for (unsigned i = 0, e = SrcNMD->getNumOperands(); i != e; ++i) DestNMD->addOperand(cast(MapValue(SrcNMD->getOperand(i), - ValueMap, - true))); + ValueMap))); } } @@ -814,9 +813,9 @@ const GlobalVariable *SGV = I; if (SGV->hasInitializer()) { // Only process initialized GV's - // Figure out what the initializer looks like in the dest module... + // Figure out what the initializer looks like in the dest module. Constant *SInit = - cast(MapValue(SGV->getInitializer(), ValueMap, true)); + cast(MapValue(SGV->getInitializer(), ValueMap)); // Grab destination global variable or alias. GlobalValue *DGV = cast(ValueMap[SGV]->stripPointerCasts()); @@ -996,32 +995,10 @@ // At this point, all of the instructions and values of the function are now // copied over. The only problem is that they are still referencing values in // the Source function as operands. Loop through all of the operands of the - // functions and patch them up to point to the local versions... - // - // This is the same as RemapInstruction, except that it avoids remapping - // instruction and basic block operands. - // + // functions and patch them up to point to the local versions. for (Function::iterator BB = Dest->begin(), BE = Dest->end(); BB != BE; ++BB) - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { - // Remap operands. - for (Instruction::op_iterator OI = I->op_begin(), OE = I->op_end(); - OI != OE; ++OI) - if (!isa(*OI) && !isa(*OI)) - *OI = MapValue(*OI, ValueMap, true); - - // Remap attached metadata. - SmallVector, 4> MDs; - I->getAllMetadata(MDs); - for (SmallVectorImpl >::iterator - MI = MDs.begin(), ME = MDs.end(); MI != ME; ++MI) { - Value *Old = MI->second; - if (!isa(Old) && !isa(Old)) { - Value *New = MapValue(Old, ValueMap, true); - if (New != Old) - I->setMetadata(MI->first, cast(New)); - } - } - } + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries); // There is no need to map the arguments anymore. for (Function::arg_iterator I = Src->arg_begin(), E = Src->arg_end(); Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=123058&r1=123057&r2=123058&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sat Jan 8 02:15:20 2011 @@ -22,7 +22,6 @@ #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/SSAUpdater.h" #include "llvm/Transforms/Utils/ValueMapper.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" using namespace llvm; @@ -205,6 +204,7 @@ // Otherwise, create a duplicate of the instruction. Instruction *C = Inst->clone(); + C->setName(Inst->getName()); C->insertBefore(LoopEntryBranch); ValueMap[Inst] = C; Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=123058&r1=123057&r2=123058&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Sat Jan 8 02:15:20 2011 @@ -457,19 +457,6 @@ return true; } -// RemapInstruction - Convert the instruction operands from referencing the -// current values into those specified by VMap. -// -static inline void RemapInstruction(Instruction *I, - ValueToValueMapTy &VMap) { - for (unsigned op = 0, E = I->getNumOperands(); op != E; ++op) { - Value *Op = I->getOperand(op); - ValueToValueMapTy::iterator It = VMap.find(Op); - if (It != VMap.end()) Op = It->second; - I->setOperand(op, Op); - } -} - /// CloneLoop - Recursively clone the specified loop and all of its children, /// mapping the blocks with the specified map. static Loop *CloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM, @@ -664,7 +651,7 @@ for (unsigned i = 0, e = NewBlocks.size(); i != e; ++i) for (BasicBlock::iterator I = NewBlocks[i]->begin(), E = NewBlocks[i]->end(); I != E; ++I) - RemapInstruction(I, VMap); + RemapInstruction(I, VMap,RF_NoModuleLevelChanges|RF_IgnoreMissingEntries); // Rewrite the original preheader to select between versions of the loop. BranchInst *OldBR = cast(loopPreheader->getTerminator()); Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=123058&r1=123057&r2=123058&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Sat Jan 8 02:15:20 2011 @@ -112,8 +112,7 @@ const BasicBlock &BB = *BI; // Create a new basic block and copy instructions into it! - BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, - CodeInfo); + BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo); VMap[&BB] = CBB; // Add basic block mapping. if (ReturnInst *RI = dyn_cast(CBB->getTerminator())) @@ -122,12 +121,12 @@ // Loop over all of the instructions in the function, fixing up operand // references as we go. This uses VMap to do all the hard work. - // for (Function::iterator BB = cast(VMap[OldFunc->begin()]), BE = NewFunc->end(); BB != BE; ++BB) // Loop over all instructions, fixing each one as we find it... for (BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II) - RemapInstruction(II, VMap, ModuleLevelChanges); + RemapInstruction(II, VMap, + ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges); } /// CloneFunction - Return a copy of the specified function, but without @@ -138,8 +137,7 @@ /// updated to include mappings from all of the instructions and basicblocks in /// the function from their old to new values. /// -Function *llvm::CloneFunction(const Function *F, - ValueToValueMapTy &VMap, +Function *llvm::CloneFunction(const Function *F, ValueToValueMapTy &VMap, bool ModuleLevelChanges, ClonedCodeInfo *CodeInfo) { std::vector ArgTypes; @@ -322,7 +320,8 @@ SmallVector Ops; for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) if (Constant *Op = dyn_cast_or_null(MapValue(I->getOperand(i), - VMap, ModuleLevelChanges))) + VMap, + ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges))) Ops.push_back(Op); else return 0; // All operands not constant! @@ -460,7 +459,8 @@ I->setDebugLoc(DebugLoc()); } } - RemapInstruction(I, VMap, ModuleLevelChanges); + RemapInstruction(I, VMap, + ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges); } } @@ -480,10 +480,10 @@ PHINode *PN = cast(VMap[OPN]); for (unsigned pred = 0, e = NumPreds; pred != e; ++pred) { Value *V = VMap[PN->getIncomingBlock(pred)]; - if (BasicBlock *MappedBlock = - cast_or_null(V)) { + if (BasicBlock *MappedBlock = cast_or_null(V)) { Value *InVal = MapValue(PN->getIncomingValue(pred), - VMap, ModuleLevelChanges); + VMap, + ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges); assert(InVal && "Unknown input value?"); PN->setIncomingValue(pred, InVal); PN->setIncomingBlock(pred, MappedBlock); Modified: llvm/trunk/lib/Transforms/Utils/CloneModule.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneModule.cpp?rev=123058&r1=123057&r2=123058&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneModule.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CloneModule.cpp Sat Jan 8 02:15:20 2011 @@ -89,8 +89,7 @@ GlobalVariable *GV = cast(VMap[I]); if (I->hasInitializer()) GV->setInitializer(cast(MapValue(I->getInitializer(), - VMap, - true))); + VMap, RF_None))); GV->setLinkage(I->getLinkage()); GV->setThreadLocal(I->isThreadLocal()); GV->setConstant(I->isConstant()); @@ -121,7 +120,7 @@ GlobalAlias *GA = cast(VMap[I]); GA->setLinkage(I->getLinkage()); if (const Constant* C = I->getAliasee()) - GA->setAliasee(cast(MapValue(C, VMap, true))); + GA->setAliasee(cast(MapValue(C, VMap, RF_None))); } // And named metadata.... @@ -130,7 +129,8 @@ const NamedMDNode &NMD = *I; NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName()); for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i) - NewNMD->addOperand(cast(MapValue(NMD.getOperand(i), VMap, true))); + NewNMD->addOperand(cast(MapValue(NMD.getOperand(i), VMap, + RF_None))); } return New; Modified: llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=123058&r1=123057&r2=123058&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp Sat Jan 8 02:15:20 2011 @@ -21,147 +21,106 @@ using namespace llvm; Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, - bool ModuleLevelChanges) { - TrackingVH &VMSlot = VM[V]; - if (VMSlot) return VMSlot; // Does it exist in the map yet? + RemapFlags Flags) { + ValueToValueMapTy::iterator I = VM.find(V); + + // If the value already exists in the map, use it. + if (I != VM.end() && I->second) return I->second; - // NOTE: VMSlot can be invalidated by any reference to VM, which can grow the - // DenseMap. This includes any recursive calls to MapValue. - // Global values do not need to be seeded into the VM if they // are using the identity mapping. - if (isa(V) || isa(V) || isa(V) || - (isa(V) && !cast(V)->isFunctionLocal() && - !ModuleLevelChanges)) - return VMSlot = const_cast(V); + if (isa(V) || isa(V) || isa(V)) + return VM[V] = const_cast(V); if (const MDNode *MD = dyn_cast(V)) { - // Start by assuming that we'll use the identity mapping. - VMSlot = const_cast(V); - + // If this is a module-level metadata and we know that nothing at the module + // level is changing, then use an identity mapping. + if (!MD->isFunctionLocal() && (Flags & RF_NoModuleLevelChanges)) + return VM[V] = const_cast(V); + // Check all operands to see if any need to be remapped. for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) { Value *OP = MD->getOperand(i); - if (!OP || MapValue(OP, VM, ModuleLevelChanges) == OP) continue; + if (OP == 0 || MapValue(OP, VM, Flags) == OP) continue; - // Ok, at least one operand needs remapping. + // Ok, at least one operand needs remapping. Create a dummy node in case + // we have a metadata cycle. MDNode *Dummy = MDNode::getTemporary(V->getContext(), 0, 0); VM[V] = Dummy; SmallVector Elts; Elts.reserve(MD->getNumOperands()); - for (i = 0; i != e; ++i) - Elts.push_back(MD->getOperand(i) ? - MapValue(MD->getOperand(i), VM, ModuleLevelChanges) : 0); + for (i = 0; i != e; ++i) { + Value *Op = MD->getOperand(i); + Elts.push_back(Op ? MapValue(Op, VM, Flags) : 0); + } MDNode *NewMD = MDNode::get(V->getContext(), Elts.data(), Elts.size()); Dummy->replaceAllUsesWith(NewMD); MDNode::deleteTemporary(Dummy); return VM[V] = NewMD; } - // No operands needed remapping; keep the identity map. - return const_cast(V); + // No operands needed remapping. Use an identity mapping. + return VM[V] = const_cast(V); } + // Okay, this either must be a constant (which may or may not be mappable) or + // is something that is not in the mapping table. Constant *C = const_cast(dyn_cast(V)); if (C == 0) return 0; - if (isa(C) || isa(C) || - isa(C) || isa(C) || - isa(C)) - return VMSlot = C; // Primitive constants map directly - - if (ConstantArray *CA = dyn_cast(C)) { - for (User::op_iterator b = CA->op_begin(), i = b, e = CA->op_end(); - i != e; ++i) { - Value *MV = MapValue(*i, VM, ModuleLevelChanges); - if (MV != *i) { - // This array must contain a reference to a global, make a new array - // and return it. - // - std::vector Values; - Values.reserve(CA->getNumOperands()); - for (User::op_iterator j = b; j != i; ++j) - Values.push_back(cast(*j)); - Values.push_back(cast(MV)); - for (++i; i != e; ++i) - Values.push_back(cast(MapValue(*i, VM, - ModuleLevelChanges))); - return VM[V] = ConstantArray::get(CA->getType(), Values); - } - } - return VM[V] = C; + if (BlockAddress *BA = dyn_cast(C)) { + Function *F = cast(MapValue(BA->getFunction(), VM, Flags)); + BasicBlock *BB = cast_or_null(MapValue(BA->getBasicBlock(), VM, + Flags)); + return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock()); } - if (ConstantStruct *CS = dyn_cast(C)) { - for (User::op_iterator b = CS->op_begin(), i = b, e = CS->op_end(); - i != e; ++i) { - Value *MV = MapValue(*i, VM, ModuleLevelChanges); - if (MV != *i) { - // This struct must contain a reference to a global, make a new struct - // and return it. - // - std::vector Values; - Values.reserve(CS->getNumOperands()); - for (User::op_iterator j = b; j != i; ++j) - Values.push_back(cast(*j)); - Values.push_back(cast(MV)); - for (++i; i != e; ++i) - Values.push_back(cast(MapValue(*i, VM, - ModuleLevelChanges))); - return VM[V] = ConstantStruct::get(CS->getType(), Values); - } - } - return VM[V] = C; - } - - if (ConstantExpr *CE = dyn_cast(C)) { + for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { + Value *Op = C->getOperand(i); + Value *Mapped = MapValue(Op, VM, Flags); + if (Mapped == C) continue; + + // Okay, the operands don't all match. We've already processed some or all + // of the operands, set them up now. std::vector Ops; - for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i) - Ops.push_back(cast(MapValue(*i, VM, ModuleLevelChanges))); - return VM[V] = CE->getWithOperands(Ops); - } - - if (ConstantVector *CV = dyn_cast(C)) { - for (User::op_iterator b = CV->op_begin(), i = b, e = CV->op_end(); - i != e; ++i) { - Value *MV = MapValue(*i, VM, ModuleLevelChanges); - if (MV != *i) { - // This vector value must contain a reference to a global, make a new - // vector constant and return it. - // - std::vector Values; - Values.reserve(CV->getNumOperands()); - for (User::op_iterator j = b; j != i; ++j) - Values.push_back(cast(*j)); - Values.push_back(cast(MV)); - for (++i; i != e; ++i) - Values.push_back(cast(MapValue(*i, VM, - ModuleLevelChanges))); - return VM[V] = ConstantVector::get(Values); - } - } - return VM[V] = C; + Ops.reserve(C->getNumOperands()); + for (unsigned j = 0; j != i; ++j) + Ops.push_back(cast(C->getOperand(i))); + Ops.push_back(cast(Mapped)); + + // Map the rest of the operands that aren't processed yet. + for (++i; i != e; ++i) + Ops.push_back(cast(MapValue(C->getOperand(i), VM, Flags))); + + if (ConstantExpr *CE = dyn_cast(C)) + return VM[V] = CE->getWithOperands(Ops); + if (ConstantArray *CA = dyn_cast(C)) + return VM[V] = ConstantArray::get(CA->getType(), Ops); + if (ConstantStruct *CS = dyn_cast(C)) + return VM[V] = ConstantStruct::get(CS->getType(), Ops); + assert(isa(C) && "Unknown mapped constant type"); + return VM[V] = ConstantVector::get(Ops); } - - BlockAddress *BA = cast(C); - Function *F = cast(MapValue(BA->getFunction(), VM, - ModuleLevelChanges)); - BasicBlock *BB = cast_or_null(MapValue(BA->getBasicBlock(),VM, - ModuleLevelChanges)); - return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock()); + + // If we reach here, all of the operands of the constant match. + return VM[V] = C; } /// RemapInstruction - Convert the instruction operands from referencing the /// current values into those specified by VMap. /// void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap, - bool ModuleLevelChanges) { + RemapFlags Flags) { // Remap operands. for (User::op_iterator op = I->op_begin(), E = I->op_end(); op != E; ++op) { - Value *V = MapValue(*op, VMap, ModuleLevelChanges); - assert(V && "Referenced value not in value map!"); - *op = V; + Value *V = MapValue(*op, VMap, Flags); + // If we aren't ignoring missing entries, assert that something happened. + if (V != 0) + *op = V; + else + assert((Flags & RF_IgnoreMissingEntries) && + "Referenced value not in value map!"); } // Remap attached metadata. @@ -170,7 +129,7 @@ for (SmallVectorImpl >::iterator MI = MDs.begin(), ME = MDs.end(); MI != ME; ++MI) { Value *Old = MI->second; - Value *New = MapValue(Old, VMap, ModuleLevelChanges); + Value *New = MapValue(Old, VMap, Flags); if (New != Old) I->setMetadata(MI->first, cast(New)); } From sabre at nondot.org Sat Jan 8 02:19:49 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Jan 2011 08:19:49 -0000 Subject: [llvm-commits] [llvm] r123059 - /llvm/trunk/include/llvm/Analysis/CodeMetrics.h Message-ID: <20110108081949.46BE22A6C12C@llvm.org> Author: lattner Date: Sat Jan 8 02:19:49 2011 New Revision: 123059 URL: http://llvm.org/viewvc/llvm-project?rev=123059&view=rev Log: make this file properly self contained. Modified: llvm/trunk/include/llvm/Analysis/CodeMetrics.h Modified: llvm/trunk/include/llvm/Analysis/CodeMetrics.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/CodeMetrics.h?rev=123059&r1=123058&r2=123059&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/CodeMetrics.h (original) +++ llvm/trunk/include/llvm/Analysis/CodeMetrics.h Sat Jan 8 02:19:49 2011 @@ -16,6 +16,8 @@ #ifndef LLVM_ANALYSIS_CODEMETRICS_H #define LLVM_ANALYSIS_CODEMETRICS_H +#include "llvm/ADT/DenseMap.h" + namespace llvm { // CodeMetrics - Calculate size and a few similar metrics for a set of // basic blocks. From sabre at nondot.org Sat Jan 8 02:24:46 2011 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Jan 2011 08:24:46 -0000 Subject: [llvm-commits] [llvm] r123060 - in /llvm/trunk: lib/Transforms/Scalar/LoopRotation.cpp test/Transforms/LoopRotate/phi-duplicate.ll Message-ID: <20110108082446.945E22A6C12C@llvm.org> Author: lattner Date: Sat Jan 8 02:24:46 2011 New Revision: 123060 URL: http://llvm.org/viewvc/llvm-project?rev=123060&view=rev Log: Have loop-rotate simplify instructions (yay instsimplify!) as it clones them into the loop preheader, eliminating silly instructions like "icmp i32 0, 100" in fixed tripcount loops. This also better exposes the bigger problem with loop rotate that I'd like to fix: once this has been folded, the duplicated conditional branch *often* turns into an uncond branch. Not aggressively handling this is pessimizing later loop optimizations somethin' fierce by making "dominates all exit blocks" checks fail. Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=123060&r1=123059&r2=123060&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sat Jan 8 02:24:46 2011 @@ -14,9 +14,10 @@ #define DEBUG_TYPE "loop-rotate" #include "llvm/Transforms/Scalar.h" #include "llvm/Function.h" -#include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Analysis/CodeMetrics.h" +#include "llvm/Analysis/DominanceFrontier.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" @@ -205,9 +206,24 @@ // Otherwise, create a duplicate of the instruction. Instruction *C = Inst->clone(); - C->setName(Inst->getName()); - C->insertBefore(LoopEntryBranch); - ValueMap[Inst] = C; + // Eagerly remap the operands of the instruction. + RemapInstruction(C, ValueMap, + RF_NoModuleLevelChanges|RF_IgnoreMissingEntries); + + // With the operands remapped, see if the instruction constant folds or is + // otherwise simplifyable. This commonly occurs because the entry from PHI + // nodes allows icmps and other instructions to fold. + if (Value *V = SimplifyInstruction(C)) { + // If so, then delete the temporary instruction and stick the folded value + // in the map. + delete C; + ValueMap[Inst] = V; + } else { + // Otherwise, stick the new instruction into the new block! + C->setName(Inst->getName()); + C->insertBefore(LoopEntryBranch); + ValueMap[Inst] = C; + } } // Along with all the other instructions, we just cloned OrigHeader's Modified: llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll?rev=123060&r1=123059&r2=123060&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll (original) +++ llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll Sat Jan 8 02:24:46 2011 @@ -34,14 +34,13 @@ ; CHECK: define void @test ; CHECK-NEXT: entry: -; CHECK-NEXT: icmp slt i64 -; CHECK-NEXT: br i1 +; CHECK-NEXT: br i1 true, label %bb.nph, label %for.end ; CHECK-NOT: : ; CHECK: bb.nph: ; CHECK-NEXT: br label %for.body ; CHECK-NOT: : ; CHECK: for.body: -; CHECK-NEXT: %j.02 = phi i64 +; CHECK-NEXT: %j.01 = phi i64 ; CHECK-NOT: phi ; CHECK: ret void ; CHECK-NEXT: } From fvbommel at gmail.com Sat Jan 8 03:12:53 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sat, 8 Jan 2011 10:12:53 +0100 Subject: [llvm-commits] [llvm] r122959 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/objsize.ll In-Reply-To: <96404383-9073-4D74-8FE3-65CF220AC676@apple.com> References: <20110106131105.59E222A6C12C@llvm.org> <36B13217-CC55-4CF9-9570-1ECCD6389A62@apple.com> <96404383-9073-4D74-8FE3-65CF220AC676@apple.com> Message-ID: On Sat, Jan 8, 2011 at 7:52 AM, Chris Lattner wrote: > > On Jan 7, 2011, at 12:49 PM, Benjamin Kramer wrote: >> I reverted the change for now, there is another issue with this as it changes the semantics of __builtin_objectsize. >> Unless we want to extend this GCC extension even more my patch is not safe in it's current form :( > > What exactly is the issue here? ?While I'm sympathetic to the "cdecl.c/ds" regression, I still think that your patch is a good route forward. ?Optimizing to "know" the strlen size seems like a nice second step. > > However, if your patch wasn't safe, then it clearly isn't good. ?What is the issue? The safety concern he refers to is that it changes the semantics of llvm.objectsize. LangRef.html states: "The llvm.objectsize intrinsic is lowered to either a constant representing the size of the object concerned, or i32/i64 -1 or 0, depending on the type argument, if the size cannot be determined at compile time." This patch would instead replace it with a non-constant value. I imagine the reason it's specified to return a constant value is so that conditionals on it can be constant-folded at compile time, leaving only one branch in the compiled program. It might therefore not be unreasonable to replace it with a non-constant value if this is *known* to significantly simplify all uses, for instance by requiring that they all simplify to constants (or in the case of terminators, to an unconditional branch or unreachable). This would still require adjusting the semantics first, though, as it's currently not legal to do any of that. P.S. Is it safe to return a constant malloc argument anyway? malloc() might return null, in which case the only safe-to-use size would be 0... From fvbommel at gmail.com Sat Jan 8 04:51:37 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sat, 08 Jan 2011 10:51:37 -0000 Subject: [llvm-commits] [llvm] r123061 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineSelect.cpp test/Transforms/InstCombine/crash.ll Message-ID: <20110108105137.17E3A2A6C12C@llvm.org> Author: fvbommel Date: Sat Jan 8 04:51:36 2011 New Revision: 123061 URL: http://llvm.org/viewvc/llvm-project?rev=123061&view=rev Log: Fix a bug in r123034 (trying to sext/zext non-integers) and clean up a little. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp llvm/trunk/test/Transforms/InstCombine/crash.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=123061&r1=123060&r2=123061&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Sat Jan 8 04:51:36 2011 @@ -299,6 +299,11 @@ case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_SGT: { + // These transformations only work for selects over integers. + const IntegerType *SelectTy = dyn_cast(SI.getType()); + if (!SelectTy) + break; + Constant *AdjustedRHS; if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_SGT) AdjustedRHS = ConstantInt::get(CI->getContext(), CI->getValue() + 1); @@ -315,9 +320,8 @@ // promote all to the larger type. This enables scalar evolution to // analyze this expression. else if (CmpRHS->getType()->getScalarSizeInBits() - < SI.getType()->getScalarSizeInBits()) { - Constant *sextRHS = ConstantExpr::getSExt(AdjustedRHS, - SI.getType()); + < SelectTy->getBitWidth()) { + Constant *sextRHS = ConstantExpr::getSExt(AdjustedRHS, SelectTy); // X = sext x; x >s c ? X : C+1 --> X = sext x; X X = sext x; X >s C-1 ? C-1 : X @@ -332,8 +336,7 @@ CmpLHS = FalseVal; AdjustedRHS = sextRHS; } else if (ICI->isUnsigned()) { - Constant *zextRHS = ConstantExpr::getZExt(AdjustedRHS, - SI.getType()); + Constant *zextRHS = ConstantExpr::getZExt(AdjustedRHS, SelectTy); // X = zext x; x >u c ? X : C+1 --> X = zext x; X X = zext x; X >u C-1 ? C-1 : X // zext + signed compare cannot be changed: Modified: llvm/trunk/test/Transforms/InstCombine/crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/crash.ll?rev=123061&r1=123060&r2=123061&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/crash.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/crash.ll Sat Jan 8 04:51:36 2011 @@ -335,3 +335,9 @@ declare i32 @func_14() + +define double @test16(i32 %a) nounwind { + %cmp = icmp slt i32 %a, 2 + %select = select i1 %cmp, double 2.000000e+00, double 3.141592e+00 + ret double %select +} From fvbommel at gmail.com Sat Jan 8 04:56:34 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sat, 8 Jan 2011 11:56:34 +0100 Subject: [llvm-commits] [llvm] r123034 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineSelect.cpp test/Transforms/InstCombine/select.ll In-Reply-To: <888D394F-773B-453E-BE5C-4D92DA1B00C5@gmail.com> References: <20110107213315.0085B2A6C12D@llvm.org> <888D394F-773B-453E-BE5C-4D92DA1B00C5@gmail.com> Message-ID: On Sat, Jan 8, 2011 at 2:44 AM, Benjamin Kramer wrote: > On 07.01.2011, at 22:33, Tobias Grosser wrote: >> + ? ? ? ? ?Constant *sextRHS = ConstantExpr::getSExt(AdjustedRHS, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?SI.getType()); > > This line (ConstantExpr::getSExt) hits an assertion failure in some files in the test suite > And the offending IR is: > ?%175 = sitofp i32 %j.3 to double > ?%174 = icmp slt i32 %j.3, 2 > ?%176 = select i1 %174, double 2.000000e+00, double %175 Fixed in r123061. From ofv at wanadoo.es Sat Jan 8 07:20:30 2011 From: ofv at wanadoo.es (=?utf-8?Q?=C3=93scar_Fuentes?=) Date: Sat, 08 Jan 2011 14:20:30 +0100 Subject: [llvm-commits] CMake patch In-Reply-To: (arrowdodger's message of "Sat, 8 Jan 2011 11:21:01 +0300") References: Message-ID: <87bp3rh6qp.fsf@wanadoo.es> arrowdodger <6yearold at gmail.com> writes: > Hello. I've sent my patch 2 days ago, but still no response. > > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20110103/114729.html Seems that gmane ate my response. Here it goes again: arrowdodger <6yearold at gmail.com> writes: > Posting first patch here as ?scar suggested in this thread > http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-January/037209.html > I've decided to start with simple stuff. > > Short summary: > > - Add ENABLE_CBE_PRINTF_A. > - Fix ENABLE_PIC. > The problem was that ENABLE_PIC was set to 1 *after* generating > config.h. I've moved if(ENABLE_PIC) from CMakeLists.txt into > cmake/config-ix.cmake. > - Add check. > - Add fmodf() call check. > This call located in math.h on Linux, FreeBSD, MacOS and Windows, so i > decided, that it's safe to check it using just check_symbol_exists() > command. > - Add HAVE_INT64_T. > - Fix HAVE_INT64_T, HAVE_UINT64_T and HAVE_U_INT64_T defines in > config.h.cmake. > - Remove CAN_DLOPEN_SELF. > This was only in config.h.cmake and not in config.h.in. Additionaly, > there was none check for it. > > I want to mention, that all CMake code is slightly messed up: declarations > are messed with logic, What are declarations? In general, code related with one purpose should be together. If this means putting declarations (whatever they are) scattered all around, it is okay. If you are talking about something else, please provide an example. > there is no convention on naming variables > (LLVM_ENABLE_<> and simply ENABLE_<>) If there is an user-settable option that does not follow the LLVM_<> naming convention, please report it. It is okay, but not required, to nameve variables which are not user-settable as LLVM_<>. > and other things. What do you think about cleaning this up? Any cleaning up is great, but first I'll like to be sure about what you are talking about. > Index: cmake/config-ix.cmake > =================================================================== > --- cmake/config-ix.cmake (revision 122744) > +++ cmake/config-ix.cmake (working copy) > @@ -31,6 +31,7 @@ > # include checks > check_include_file(argz.h HAVE_ARGZ_H) > check_include_file(assert.h HAVE_ASSERT_H) > +check_include_file(ctype.h HAVE_CTYPE_H) > check_include_file(dirent.h HAVE_DIRENT_H) > check_include_file(dl.h HAVE_DL_H) > check_include_file(dld.h HAVE_DLD_H) > @@ -92,6 +93,7 @@ > check_symbol_exists(isnan math.h HAVE_ISNAN_IN_MATH_H) > check_symbol_exists(ceilf math.h HAVE_CEILF) > check_symbol_exists(floorf math.h HAVE_FLOORF) > +check_symbol_exists(fmodf math.h HAVE_FMODF) > check_symbol_exists(nearbyintf math.h HAVE_NEARBYINTF) > check_symbol_exists(mallinfo malloc.h HAVE_MALLINFO) > check_symbol_exists(malloc_zone_statistics malloc/malloc.h > @@ -135,6 +137,7 @@ > set(headers ${headers} "stdint.h") > endif() > > +check_type_exists(int64_t "${headers}" HAVE_INT64_T) > check_type_exists(uint64_t "${headers}" HAVE_UINT64_T) > check_type_exists(u_int64_t "${headers}" HAVE_U_INT64_T) > > @@ -267,6 +270,24 @@ > message(STATUS "Threads disabled.") > endif() > > +#ENABLE_PIC value goes into config.h > +set(ENABLE_PIC 0) > +if( LLVM_ENABLE_PIC ) > + if( XCODE ) > + # Xcode has -mdynamic-no-pic on by default, which overrides -fPIC. I don't > + # know how to disable this, so just force ENABLE_PIC off for now. > + message(STATUS "Warning: -fPIC not supported with Xcode.") > + else( XCODE ) > + if( SUPPORTS_FPIC_FLAG ) > + message(STATUS "Building with -fPIC") > + add_llvm_definitions(-fPIC) > + set(ENABLE_PIC 1) > + else( SUPPORTS_FPIC_FLAG ) > + message(STATUS "Warning: -fPIC not supported.") > + endif() > + endif() > +endif() This is one example of code dispersion I don't like to see. LLVM_ENABLE_PIC is declared in the top level CMakeLists.txt. Moving away code that warns the user about his settings offers no gain. You are right that include(config-ix) should be after that chunk of code, though. [snip] > Index: CMakeLists.txt > =================================================================== > --- CMakeLists.txt (revision 122744) > +++ CMakeLists.txt (working copy) > @@ -101,6 +101,9 @@ > CACHE STRING "Semicolon-separated list of targets to build, or \"all\".") > endif( MSVC ) > > +set(ENABLE_CBE_PRINTF_A 1 CACHE BOOL > + "Set to YES if CBE is enabled for printf %a output") > + Please use `option' and not `set' for boolean user-settable variables. > set(CLANG_RESOURCE_DIR "" CACHE STRING > "Relative directory from the Clang binary to its resource files.") > > @@ -195,26 +198,10 @@ > endif(UNIX) > endif(WIN32) > > -include(config-ix) > - > option(LLVM_ENABLE_PIC "Build Position-Independent Code" ON) > +set(ENABLE_TIMESTAMPS 1 CACHE BOOL "Enable embedding timestamp information in build") Same. > -set(ENABLE_PIC 0) > -if( LLVM_ENABLE_PIC ) > - if( XCODE ) > - # Xcode has -mdynamic-no-pic on by default, which overrides -fPIC. I don't > - # know how to disable this, so just force ENABLE_PIC off for now. > - message(STATUS "Warning: -fPIC not supported with Xcode.") > - else( XCODE ) > - if( SUPPORTS_FPIC_FLAG ) > - message(STATUS "Building with -fPIC") > - add_llvm_definitions(-fPIC) > - set(ENABLE_PIC 1) > - else( SUPPORTS_FPIC_FLAG ) > - message(STATUS "Warning: -fPIC not supported.") > - endif() > - endif() > -endif() > +include(config-ix) Overall looks good. Please return the if( LLVM_ENABLE_PIC ) chunk to the toplevel CMakeLists.txt, replace those set(... BOOL ...) with option, and commit if you have write permissions, or post again the patch if not. Thanks! From baldrick at free.fr Sat Jan 8 07:36:39 2011 From: baldrick at free.fr (Duncan Sands) Date: Sat, 08 Jan 2011 14:36:39 +0100 Subject: [llvm-commits] [llvm] r123060 - in /llvm/trunk: lib/Transforms/Scalar/LoopRotation.cpp test/Transforms/LoopRotate/phi-duplicate.ll In-Reply-To: <20110108082446.945E22A6C12C@llvm.org> References: <20110108082446.945E22A6C12C@llvm.org> Message-ID: <4D286867.2060406@free.fr> Hi Chris, > Have loop-rotate simplify instructions (yay instsimplify!) as it clones > them into the loop preheader, eliminating silly instructions like > "icmp i32 0, 100" in fixed tripcount loops. This also better exposes the > bigger problem with loop rotate that I'd like to fix: once this has been > folded, the duplicated conditional branch *often* turns into an uncond branch. ... > @@ -205,9 +206,24 @@ > // Otherwise, create a duplicate of the instruction. > Instruction *C = Inst->clone(); > > - C->setName(Inst->getName()); > - C->insertBefore(LoopEntryBranch); > - ValueMap[Inst] = C; > + // Eagerly remap the operands of the instruction. > + RemapInstruction(C, ValueMap, > + RF_NoModuleLevelChanges|RF_IgnoreMissingEntries); > + > + // With the operands remapped, see if the instruction constant folds or is > + // otherwise simplifyable. This commonly occurs because the entry from PHI > + // nodes allows icmps and other instructions to fold. > + if (Value *V = SimplifyInstruction(C)) { > + // If so, then delete the temporary instruction and stick the folded value > + // in the map. > + delete C; > + ValueMap[Inst] = V; > + } else { since instsimplify can look through phi nodes, it doesn't automatically preserve LCSSA form. Passes like loop-rotate that need to preserve LCSSA form should do something like this: if (Value *V = SimplifyInstruction(C)) if (LI->replacementPreservesLCSSAForm(C, V)) { .. use the simplification ... } Ciao, Duncan. From grosser at fim.uni-passau.de Sat Jan 8 09:21:58 2011 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Sat, 08 Jan 2011 10:21:58 -0500 Subject: [llvm-commits] [llvm] r123034 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineSelect.cpp test/Transforms/InstCombine/select.ll In-Reply-To: References: <20110107213315.0085B2A6C12D@llvm.org> <888D394F-773B-453E-BE5C-4D92DA1B00C5@gmail.com> Message-ID: <4D288116.4080207@fim.uni-passau.de> On 01/08/2011 05:56 AM, Frits van Bommel wrote: > On Sat, Jan 8, 2011 at 2:44 AM, Benjamin Kramer > wrote: >> On 07.01.2011, at 22:33, Tobias Grosser wrote: >>> + Constant *sextRHS = ConstantExpr::getSExt(AdjustedRHS, >>> + SI.getType()); >> >> This line (ConstantExpr::getSExt) hits an assertion failure in some files in the test suite > >> And the offending IR is: >> %175 = sitofp i32 %j.3 to double >> %174 = icmp slt i32 %j.3, 2 >> %176 = select i1 %174, double 2.000000e+00, double %175 > > Fixed in r123061. Hey Frits, thanks a lot. Tobi From zwarich at apple.com Sat Jan 8 09:52:22 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sat, 08 Jan 2011 15:52:22 -0000 Subject: [llvm-commits] [llvm] r123062 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Message-ID: <20110108155222.D90342A6C12C@llvm.org> Author: zwarich Date: Sat Jan 8 09:52:22 2011 New Revision: 123062 URL: http://llvm.org/viewvc/llvm-project?rev=123062&view=rev Log: Contract subloop bodies. However, it is still important to visit the phis at the top of subloop headers, as the phi uses logically occur outside of the subloop. Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp?rev=123062&r1=123061&r2=123062&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Sat Jan 8 09:52:22 2011 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "loop-instsimplify" +#include "llvm/Instructions.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopInfo.h" @@ -68,7 +69,10 @@ SmallPtrSet S1, S2, *ToSimplify = &S1, *Next = &S2; - SmallVector VisitStack; + // The bit we are stealing from the pointer represents whether this basic + // block is the header of a subloop, in which case we only process its phis. + typedef PointerIntPair WorklistItem; + SmallVector VisitStack; SmallPtrSet Visited; bool Changed = false; @@ -79,10 +83,12 @@ VisitStack.clear(); Visited.clear(); - VisitStack.push_back(L->getHeader()); + VisitStack.push_back(WorklistItem(L->getHeader(), false)); while (!VisitStack.empty()) { - BasicBlock *BB = VisitStack.pop_back_val(); + WorklistItem Item = VisitStack.pop_back_val(); + BasicBlock* BB = Item.getPointer(); + bool IsSubloopHeader = Item.getInt(); // Simplify instructions in the current basic block. for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { @@ -109,16 +115,44 @@ } } LocalChanged |= RecursivelyDeleteTriviallyDeadInstructions(I); + + if (IsSubloopHeader && !isa(I)) + break; } - // Add all successors to the worklist, except for loop exit blocks. + // Add all successors to the worklist, except for loop exit blocks and the + // bodies of subloops. We visit the headers of loops so that we can process + // their phis, but we contract the rest of the subloop body and only follow + // edges leading back to the original loop. for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI) { BasicBlock *SuccBB = *SI; + if (!Visited.insert(SuccBB)) + continue; + + const Loop *SuccLoop = LI->getLoopFor(SuccBB); + if (SuccLoop && SuccLoop->getHeader() == SuccBB + && L->contains(SuccLoop)) { + VisitStack.push_back(WorklistItem(SuccBB, true)); + + SmallVector SubLoopExitBlocks; + SuccLoop->getExitBlocks(SubLoopExitBlocks); + + for (unsigned i = 0; i < SubLoopExitBlocks.size(); ++i) { + BasicBlock *ExitBB = SubLoopExitBlocks[i]; + if (LI->getLoopFor(ExitBB) == L && Visited.insert(ExitBB)) + VisitStack.push_back(WorklistItem(ExitBB, false)); + } + + continue; + } + bool IsExitBlock = std::binary_search(ExitBlocks.begin(), - ExitBlocks.end(), SuccBB); - if (!IsExitBlock && Visited.insert(SuccBB)) - VisitStack.push_back(SuccBB); + ExitBlocks.end(), SuccBB); + if (IsExitBlock) + continue; + + VisitStack.push_back(WorklistItem(SuccBB, false)); } } From fvbommel at gmail.com Sat Jan 8 10:05:27 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sat, 8 Jan 2011 17:05:27 +0100 Subject: [llvm-commits] [llvm] r123062 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp In-Reply-To: <20110108155222.D90342A6C12C@llvm.org> References: <20110108155222.D90342A6C12C@llvm.org> Message-ID: On Sat, Jan 8, 2011 at 4:52 PM, Cameron Zwarich wrote: > - ? ? ?BasicBlock *BB = VisitStack.pop_back_val(); > + ? ? ?WorklistItem Item = VisitStack.pop_back_val(); > + ? ? ?BasicBlock* BB = Item.getPointer(); The usual LLVM style is to have the '*' attached to the identifier instead of the pointee type, so 'BasicBlock* BB' --> 'BasicBlock *BB' (like it was before). From zwarich at apple.com Sat Jan 8 10:23:19 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sat, 8 Jan 2011 08:23:19 -0800 Subject: [llvm-commits] [llvm] r123062 - /llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp In-Reply-To: References: <20110108155222.D90342A6C12C@llvm.org> Message-ID: <1B45A381-A70F-4780-9141-090EE0D2088B@apple.com> On Jan 8, 2011, at 8:05 AM, Frits van Bommel wrote: > On Sat, Jan 8, 2011 at 4:52 PM, Cameron Zwarich wrote: >> - BasicBlock *BB = VisitStack.pop_back_val(); >> + WorklistItem Item = VisitStack.pop_back_val(); >> + BasicBlock* BB = Item.getPointer(); > > The usual LLVM style is to have the '*' attached to the identifier > instead of the pointee type, so 'BasicBlock* BB' --> 'BasicBlock *BB' > (like it was before). Thanks. I changed this file to match that style, but I must have had this patch in motion. Cameron From rafael.espindola at gmail.com Sat Jan 8 10:42:37 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Sat, 08 Jan 2011 16:42:37 -0000 Subject: [llvm-commits] [llvm] r123063 - in /llvm/trunk: docs/BitCodeFormat.html docs/LangRef.html include/llvm/GlobalValue.h lib/AsmParser/LLLexer.cpp lib/AsmParser/LLParser.cpp lib/AsmParser/LLToken.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Writer/BitcodeWriter.cpp lib/VMCore/AsmWriter.cpp lib/VMCore/Verifier.cpp test/Assembler/unnamed-addr.ll unittests/VMCore/VerifierTest.cpp Message-ID: <20110108164237.9B46E2A6C12C@llvm.org> Author: rafael Date: Sat Jan 8 10:42:36 2011 New Revision: 123063 URL: http://llvm.org/viewvc/llvm-project?rev=123063&view=rev Log: First step in fixing PR8927: Add a unnamed_addr bit to global variables and functions. This will be used to indicate that the address is not significant and therefore the constant or function can be merged with others. If an optimization pass can show that an address is not used, it can set this. Examples of things that can have this set by the FE are globals created to hold string literals and C++ constructors. Adding unnamed_addr to a non-const global should have no effect unless an optimization can transform that global into a constant. Aliases are not allowed to have unnamed_addr since I couldn't figure out any use for it. Added: llvm/trunk/test/Assembler/unnamed-addr.ll Modified: llvm/trunk/docs/BitCodeFormat.html llvm/trunk/docs/LangRef.html llvm/trunk/include/llvm/GlobalValue.h llvm/trunk/lib/AsmParser/LLLexer.cpp llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/AsmParser/LLToken.h llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/VMCore/AsmWriter.cpp llvm/trunk/lib/VMCore/Verifier.cpp llvm/trunk/unittests/VMCore/VerifierTest.cpp Modified: llvm/trunk/docs/BitCodeFormat.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/BitCodeFormat.html?rev=123063&r1=123062&r2=123063&view=diff ============================================================================== --- llvm/trunk/docs/BitCodeFormat.html (original) +++ llvm/trunk/docs/BitCodeFormat.html Sat Jan 8 10:42:36 2011 @@ -922,6 +922,9 @@
  12. threadlocal: If present and non-zero, indicates that the variable is thread_local
  13. +
  14. unnamed_addr: If present and non-zero, indicates that the variable +has unnamed_addr
  15. +
  16. @@ -975,6 +978,10 @@
  17. gc: If present and nonzero, the 1-based garbage collector index in the table of MODULE_CODE_GCNAME entries.
  18. + +
  19. unnamed_addr: If present and non-zero, indicates that the function +has unnamed_addr
  20. + Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=123063&r1=123062&r2=123063&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Sat Jan 8 10:42:36 2011 @@ -846,6 +846,10 @@ region of memory, and all memory objects in LLVM are accessed through pointers.

    +

    Global variables can be marked with unnamed_addr which indicates + that the address is not significant, only the content. Constants marked + like this can be merged if they have the same content.

    +

    A global variable may be declared to reside in a target-specific numbered address space. For targets that support them, address spaces may affect how optimizations are performed and/or what target instructions are used to @@ -885,7 +889,8 @@

    LLVM function definitions consist of the "define" keyword, an optional linkage type, an optional visibility style, an optional - calling convention, a return type, an optional + calling convention, + an optional unnamed_addr attribute, a return type, an optional parameter attribute for the return type, a function name, a (possibly empty) argument list (each with optional parameter attributes), optional @@ -896,7 +901,8 @@

    LLVM function declarations consist of the "declare" keyword, an optional linkage type, an optional visibility style, an optional - calling convention, a return type, an optional + calling convention, + an optional unnamed_addr attribute, a return type, an optional parameter attribute for the return type, a function name, a possibly empty list of arguments, an optional alignment, and an optional garbage collector name.

    @@ -922,6 +928,9 @@ specified, the function is forced to have at least that much alignment. All alignments must be a power of 2.

    +

    If the unnamed_addr attribute is given, the address is know to not + be significant and two identical functions can be merged

    . +
    Syntax:
     define [linkage] [visibility]
    
    Modified: llvm/trunk/include/llvm/GlobalValue.h
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/GlobalValue.h?rev=123063&r1=123062&r2=123063&view=diff
    ==============================================================================
    --- llvm/trunk/include/llvm/GlobalValue.h (original)
    +++ llvm/trunk/include/llvm/GlobalValue.h Sat Jan  8 10:42:36 2011
    @@ -60,7 +60,8 @@
       GlobalValue(const Type *ty, ValueTy vty, Use *Ops, unsigned NumOps,
                   LinkageTypes linkage, const Twine &Name)
         : Constant(ty, vty, Ops, NumOps), Parent(0),
    -      Linkage(linkage), Visibility(DefaultVisibility), Alignment(0) {
    +      Linkage(linkage), Visibility(DefaultVisibility), Alignment(0),
    +      UnnamedAddr(0) {
         setName(Name);
       }
     
    @@ -70,6 +71,7 @@
       LinkageTypes Linkage : 5;   // The linkage of this global
       unsigned Visibility : 2;    // The visibility style of this global
       unsigned Alignment : 16;    // Alignment of this symbol, must be power of two
    +  unsigned UnnamedAddr : 1;   // This value's address is not significant
       std::string Section;        // Section to emit this into, empty mean default
     public:
       ~GlobalValue() {
    @@ -81,6 +83,9 @@
       }
       void setAlignment(unsigned Align);
     
    +  bool hasUnnamedAddr() const { return UnnamedAddr; }
    +  void setUnnamedAddr(bool Val) { UnnamedAddr = Val; }
    +
       VisibilityTypes getVisibility() const { return VisibilityTypes(Visibility); }
       bool hasDefaultVisibility() const { return Visibility == DefaultVisibility; }
       bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; }
    
    Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=123063&r1=123062&r2=123063&view=diff
    ==============================================================================
    --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
    +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Sat Jan  8 10:42:36 2011
    @@ -509,6 +509,7 @@
       KEYWORD(default);
       KEYWORD(hidden);
       KEYWORD(protected);
    +  KEYWORD(unnamed_addr);
       KEYWORD(extern_weak);
       KEYWORD(external);
       KEYWORD(thread_local);
    
    Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=123063&r1=123062&r2=123063&view=diff
    ==============================================================================
    --- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
    +++ llvm/trunk/lib/AsmParser/LLParser.cpp Sat Jan  8 10:42:36 2011
    @@ -194,7 +194,8 @@
         // The Global variable production with no name can have many different
         // optional leading prefixes, the production is:
         // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
    -    //               OptionalAddrSpace ('constant'|'global') ...
    +    //               OptionalAddrSpace OptionalUnNammedAddr
    +    //               ('constant'|'global') ...
         case lltok::kw_private:             // OptionalLinkage
         case lltok::kw_linker_private:      // OptionalLinkage
         case lltok::kw_linker_private_weak: // OptionalLinkage
    @@ -682,9 +683,9 @@
     
     /// ParseGlobal
     ///   ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalThreadLocal
    -///       OptionalAddrSpace GlobalType Type Const
    +///       OptionalAddrSpace OptionalUnNammedAddr GlobalType Type Const
     ///   ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
    -///       OptionalAddrSpace GlobalType Type Const
    +///       OptionalAddrSpace OptionalUnNammedAddr GlobalType Type Const
     ///
     /// Everything through visibility has been parsed already.
     ///
    @@ -692,12 +693,13 @@
                                unsigned Linkage, bool HasLinkage,
                                unsigned Visibility) {
       unsigned AddrSpace;
    -  bool ThreadLocal, IsConstant;
    +  bool ThreadLocal, IsConstant, UnnamedAddr;
       LocTy TyLoc;
     
       PATypeHolder Ty(Type::getVoidTy(Context));
       if (ParseOptionalToken(lltok::kw_thread_local, ThreadLocal) ||
           ParseOptionalAddrSpace(AddrSpace) ||
    +      ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr) ||
           ParseGlobalType(IsConstant) ||
           ParseType(Ty, TyLoc))
         return true;
    @@ -755,6 +757,7 @@
       GV->setLinkage((GlobalValue::LinkageTypes)Linkage);
       GV->setVisibility((GlobalValue::VisibilityTypes)Visibility);
       GV->setThreadLocal(ThreadLocal);
    +  GV->setUnnamedAddr(UnnamedAddr);
     
       // Parse attributes on the global.
       while (Lex.getKind() == lltok::comma) {
    @@ -2657,7 +2660,7 @@
     
     /// FunctionHeader
     ///   ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs
    -///       Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection
    +///       OptUnnamedAddr Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection
     ///       OptionalAlign OptGC
     bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
       // Parse the linkage.
    @@ -2665,6 +2668,7 @@
       unsigned Linkage;
     
       unsigned Visibility, RetAttrs;
    +  bool UnnamedAddr;
       CallingConv::ID CC;
       PATypeHolder RetType(Type::getVoidTy(Context));
       LocTy RetTypeLoc = Lex.getLoc();
    @@ -2672,6 +2676,7 @@
           ParseOptionalVisibility(Visibility) ||
           ParseOptionalCallingConv(CC) ||
           ParseOptionalAttrs(RetAttrs, 1) ||
    +      ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr) ||
           ParseType(RetType, RetTypeLoc, true /*void allowed*/))
         return true;
     
    @@ -2841,6 +2846,7 @@
       Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility);
       Fn->setCallingConv(CC);
       Fn->setAttributes(PAL);
    +  Fn->setUnnamedAddr(UnnamedAddr);
       Fn->setAlignment(Alignment);
       Fn->setSection(Section);
       if (!GC.empty()) Fn->setGC(GC.c_str());
    
    Modified: llvm/trunk/lib/AsmParser/LLToken.h
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=123063&r1=123062&r2=123063&view=diff
    ==============================================================================
    --- llvm/trunk/lib/AsmParser/LLToken.h (original)
    +++ llvm/trunk/lib/AsmParser/LLToken.h Sat Jan  8 10:42:36 2011
    @@ -42,6 +42,7 @@
         kw_linkonce, kw_linkonce_odr, kw_weak, kw_weak_odr, kw_appending,
         kw_dllimport, kw_dllexport, kw_common, kw_available_externally,
         kw_default, kw_hidden, kw_protected,
    +    kw_unnamed_addr,
         kw_extern_weak,
         kw_external, kw_thread_local,
         kw_zeroinitializer,
    
    Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=123063&r1=123062&r2=123063&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
    +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Sat Jan  8 10:42:36 2011
    @@ -1422,7 +1422,8 @@
           break;
         }
         // GLOBALVAR: [pointer type, isconst, initid,
    -    //             linkage, alignment, section, visibility, threadlocal]
    +    //             linkage, alignment, section, visibility, threadlocal,
    +    //             unnamed_addr]
         case bitc::MODULE_CODE_GLOBALVAR: {
           if (Record.size() < 6)
             return Error("Invalid MODULE_CODE_GLOBALVAR record");
    @@ -1449,6 +1450,10 @@
           if (Record.size() > 7)
             isThreadLocal = Record[7];
     
    +      bool UnnamedAddr = false;
    +      if (Record.size() > 8)
    +        UnnamedAddr = Record[8];
    +
           GlobalVariable *NewGV =
             new GlobalVariable(*TheModule, Ty, isConstant, Linkage, 0, "", 0,
                                isThreadLocal, AddressSpace);
    @@ -1457,6 +1462,7 @@
             NewGV->setSection(Section);
           NewGV->setVisibility(Visibility);
           NewGV->setThreadLocal(isThreadLocal);
    +      NewGV->setUnnamedAddr(UnnamedAddr);
     
           ValueList.push_back(NewGV);
     
    @@ -1466,7 +1472,7 @@
           break;
         }
         // FUNCTION:  [type, callingconv, isproto, linkage, paramattr,
    -    //             alignment, section, visibility, gc]
    +    //             alignment, section, visibility, gc, unnamed_addr]
         case bitc::MODULE_CODE_FUNCTION: {
           if (Record.size() < 8)
             return Error("Invalid MODULE_CODE_FUNCTION record");
    @@ -1499,6 +1505,10 @@
               return Error("Invalid GC ID");
             Func->setGC(GCTable[Record[8]-1].c_str());
           }
    +      bool UnnamedAddr = false;
    +      if (Record.size() > 9)
    +        UnnamedAddr = Record[9];
    +      Func->setUnnamedAddr(UnnamedAddr);
           ValueList.push_back(Func);
     
           // If this is a function with a body, remember the prototype we are
    
    Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=123063&r1=123062&r2=123063&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
    +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Sat Jan  8 10:42:36 2011
    @@ -404,7 +404,8 @@
         unsigned AbbrevToUse = 0;
     
         // GLOBALVAR: [type, isconst, initid,
    -    //             linkage, alignment, section, visibility, threadlocal]
    +    //             linkage, alignment, section, visibility, threadlocal,
    +    //             unnamed_addr]
         Vals.push_back(VE.getTypeID(GV->getType()));
         Vals.push_back(GV->isConstant());
         Vals.push_back(GV->isDeclaration() ? 0 :
    @@ -413,9 +414,11 @@
         Vals.push_back(Log2_32(GV->getAlignment())+1);
         Vals.push_back(GV->hasSection() ? SectionMap[GV->getSection()] : 0);
         if (GV->isThreadLocal() ||
    -        GV->getVisibility() != GlobalValue::DefaultVisibility) {
    +        GV->getVisibility() != GlobalValue::DefaultVisibility ||
    +        GV->hasUnnamedAddr()) {
           Vals.push_back(getEncodedVisibility(GV));
           Vals.push_back(GV->isThreadLocal());
    +      Vals.push_back(GV->hasUnnamedAddr());
         } else {
           AbbrevToUse = SimpleGVarAbbrev;
         }
    @@ -427,7 +430,7 @@
       // Emit the function proto information.
       for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
         // FUNCTION:  [type, callingconv, isproto, paramattr,
    -    //             linkage, alignment, section, visibility, gc]
    +    //             linkage, alignment, section, visibility, gc, unnamed_addr]
         Vals.push_back(VE.getTypeID(F->getType()));
         Vals.push_back(F->getCallingConv());
         Vals.push_back(F->isDeclaration());
    @@ -437,6 +440,7 @@
         Vals.push_back(F->hasSection() ? SectionMap[F->getSection()] : 0);
         Vals.push_back(getEncodedVisibility(F));
         Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0);
    +    Vals.push_back(F->hasUnnamedAddr());
     
         unsigned AbbrevToUse = 0;
         Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
    
    Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=123063&r1=123062&r2=123063&view=diff
    ==============================================================================
    --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original)
    +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Sat Jan  8 10:42:36 2011
    @@ -1459,6 +1459,7 @@
       if (GV->isThreadLocal()) Out << "thread_local ";
       if (unsigned AddressSpace = GV->getType()->getAddressSpace())
         Out << "addrspace(" << AddressSpace << ") ";
    +  if (GV->hasUnnamedAddr()) Out << "unnamed_addr ";
       Out << (GV->isConstant() ? "constant " : "global ");
       TypePrinter.print(GV->getType()->getElementType(), Out);
     
    @@ -1589,6 +1590,8 @@
       Attributes RetAttrs = Attrs.getRetAttributes();
       if (RetAttrs != Attribute::None)
         Out <<  Attribute::getAsString(Attrs.getRetAttributes()) << ' ';
    +  if (F->hasUnnamedAddr())
    +    Out << "unnamed_addr ";
       TypePrinter.print(F->getReturnType(), Out);
       Out << ' ';
       WriteAsOperandInternal(Out, F, &TypePrinter, &Machine, F->getParent());
    
    Modified: llvm/trunk/lib/VMCore/Verifier.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=123063&r1=123062&r2=123063&view=diff
    ==============================================================================
    --- llvm/trunk/lib/VMCore/Verifier.cpp (original)
    +++ llvm/trunk/lib/VMCore/Verifier.cpp Sat Jan  8 10:42:36 2011
    @@ -484,6 +484,7 @@
               "Aliasee cannot be NULL!", &GA);
       Assert1(GA.getType() == GA.getAliasee()->getType(),
               "Alias and aliasee types should match!", &GA);
    +  Assert1(!GA.hasUnnamedAddr(), "Alias cannot have unnamed_addr!", &GA);
     
       if (!isa(GA.getAliasee())) {
         const ConstantExpr *CE = dyn_cast(GA.getAliasee());
    
    Added: llvm/trunk/test/Assembler/unnamed-addr.ll
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/unnamed-addr.ll?rev=123063&view=auto
    ==============================================================================
    --- llvm/trunk/test/Assembler/unnamed-addr.ll (added)
    +++ llvm/trunk/test/Assembler/unnamed-addr.ll Sat Jan  8 10:42:36 2011
    @@ -0,0 +1,18 @@
    +; RUN: llvm-as < %s | llvm-dis | FileCheck %s
    +
    +%struct.foobar = type { i32 }
    +
    + at bar.d = internal unnamed_addr constant %struct.foobar zeroinitializer, align 4
    + at foo.d = internal constant %struct.foobar zeroinitializer, align 4
    +
    +define unnamed_addr i32 @main() nounwind ssp {
    +entry:
    +  %call2 = tail call i32 @zed(%struct.foobar* @foo.d, %struct.foobar* @bar.d) nounwind
    +  ret i32 0
    +}
    +
    +declare i32 @zed(%struct.foobar*, %struct.foobar*)
    +
    +; CHECK: @bar.d = internal unnamed_addr constant %struct.foobar zeroinitializer, align 4
    +; CHECK: @foo.d = internal constant %struct.foobar zeroinitializer, align 4
    +; CHECK: define unnamed_addr i32 @main() nounwind ssp {
    
    Modified: llvm/trunk/unittests/VMCore/VerifierTest.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/VMCore/VerifierTest.cpp?rev=123063&r1=123062&r2=123063&view=diff
    ==============================================================================
    --- llvm/trunk/unittests/VMCore/VerifierTest.cpp (original)
    +++ llvm/trunk/unittests/VMCore/VerifierTest.cpp Sat Jan  8 10:42:36 2011
    @@ -10,8 +10,11 @@
     #include "llvm/Constants.h"
     #include "llvm/DerivedTypes.h"
     #include "llvm/Function.h"
    +#include "llvm/GlobalAlias.h"
    +#include "llvm/GlobalVariable.h"
     #include "llvm/Instructions.h"
     #include "llvm/LLVMContext.h"
    +#include "llvm/Module.h"
     #include "llvm/ADT/OwningPtr.h"
     #include "llvm/Analysis/Verifier.h"
     #include "gtest/gtest.h"
    @@ -41,5 +44,22 @@
       EXPECT_TRUE(verifyFunction(*F, ReturnStatusAction));
     }
     
    +TEST(VerifierTest, AliasUnnamedAddr) {
    +  LLVMContext &C = getGlobalContext();
    +  Module M("M", C);
    +  const Type *Ty = Type::getInt8Ty(C);
    +  Constant *Init = Constant::getNullValue(Ty);
    +  GlobalVariable *Aliasee = new GlobalVariable(M, Ty, true,
    +                                               GlobalValue::ExternalLinkage,
    +                                               Init, "foo");
    +  GlobalAlias *GA = new GlobalAlias(Type::getInt8PtrTy(C),
    +                                    GlobalValue::ExternalLinkage,
    +                                    "bar", Aliasee, &M);
    +  GA->setUnnamedAddr(true);
    +  std::string Error;
    +  EXPECT_TRUE(verifyModule(M, ReturnStatusAction, &Error));
    +  EXPECT_TRUE(StringRef(Error).startswith("Alias cannot have unnamed_addr"));
    +}
    +
     }
     }
    
    
    
    From rafael.espindola at gmail.com  Sat Jan  8 10:55:01 2011
    From: rafael.espindola at gmail.com (=?ISO-8859-1?Q?Rafael_=C1vila_de_Esp=EDndola?=)
    Date: Sat, 08 Jan 2011 11:55:01 -0500
    Subject: [llvm-commits] [patch][8927] Add an unnamed_addr attribute
    In-Reply-To: <7F35CC51-49B3-4DF4-8921-FAB062D6B8DD@apple.com>
    References: <4D27E063.6060605@gmail.com>
    	<7F35CC51-49B3-4DF4-8921-FAB062D6B8DD@apple.com>
    Message-ID: <4D2896E5.8060406@gmail.com>
    
    > This patch looks great except for:
    > 
    >> non constant globals are not allowed to have unnamed_addr since I couldn't figure out any use for it.
    > 
    > I also can't figure out any use for it in C, but I don't think that the verifier should reject this.  The property is orthogonal from immutability.
    > 
    > Here's a contrived example where it could be useful: imagine a language that doesn't have pointer comparisons: in that language the frontend could mark all globals as unnamed_addr, regardless of whether they are const or not.  If the optimizer realizes later that there are no stores to a global, it could be marked const, and then (because it has the attr) merged with other constant globals.
    > 
    > Does that make any sense?
    
    Yes, it is a very good point. I changed the patch to accept regular
    globals with the unnamed_addr attribute, updated the documentation and
    committed it.
    
    Having clang produce it in simple cases is next.
    
    > -Chris
    
    Thanks,
    Rafael
    
    From zwarich at apple.com  Sat Jan  8 11:01:52 2011
    From: zwarich at apple.com (Cameron Zwarich)
    Date: Sat, 08 Jan 2011 17:01:52 -0000
    Subject: [llvm-commits] [llvm] r123064 - in /llvm/trunk/lib:
     CodeGen/GCStrategy.cpp CodeGen/StackProtector.cpp
     CodeGen/UnreachableBlockElim.cpp Transforms/Scalar/CodeGenPrepare.cpp
     Transforms/Utils/Local.cpp
    Message-ID: <20110108170152.62B252A6C12C@llvm.org>
    
    Author: zwarich
    Date: Sat Jan  8 11:01:52 2011
    New Revision: 123064
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123064&view=rev
    Log:
    Make more passes preserve dominators (or state that they preserve dominators if
    they all ready do). This removes two dominator recomputations prior to isel,
    which is a 1% improvement in total llc time for 403.gcc.
    
    The only potentially suspect thing is making GCStrategy recompute dominators if
    it used a custom lowering strategy.
    
    Modified:
        llvm/trunk/lib/CodeGen/GCStrategy.cpp
        llvm/trunk/lib/CodeGen/StackProtector.cpp
        llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp
        llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp
        llvm/trunk/lib/Transforms/Utils/Local.cpp
    
    Modified: llvm/trunk/lib/CodeGen/GCStrategy.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GCStrategy.cpp?rev=123064&r1=123063&r2=123064&view=diff
    ==============================================================================
    --- llvm/trunk/lib/CodeGen/GCStrategy.cpp (original)
    +++ llvm/trunk/lib/CodeGen/GCStrategy.cpp Sat Jan  8 11:01:52 2011
    @@ -19,6 +19,7 @@
     #include "llvm/CodeGen/Passes.h"
     #include "llvm/IntrinsicInst.h"
     #include "llvm/Module.h"
    +#include "llvm/Analysis/Dominators.h"
     #include "llvm/CodeGen/MachineFrameInfo.h"
     #include "llvm/CodeGen/MachineFunctionPass.h"
     #include "llvm/CodeGen/MachineInstrBuilder.h"
    @@ -146,6 +147,7 @@
     void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const {
       FunctionPass::getAnalysisUsage(AU);
       AU.addRequired();
    +  AU.addPreserved();
     }
     
     /// doInitialization - If this module uses the GC intrinsics, find them now.
    @@ -256,9 +258,16 @@
       if (NeedsDefaultLoweringPass(S))
         MadeChange |= PerformDefaultLowering(F, S);
       
    -  if (NeedsCustomLoweringPass(S))
    +  bool UseCustomLoweringPass = NeedsCustomLoweringPass(S);
    +  if (UseCustomLoweringPass)
         MadeChange |= S.performCustomLowering(F);
    -  
    +
    +  // Custom lowering may modify the CFG, so dominators must be recomputed.
    +  if (UseCustomLoweringPass) {
    +    if (DominatorTree *DT = getAnalysisIfAvailable())
    +      DT->DT->recalculate(F);
    +  }
    +
       return MadeChange;
     }
     
    
    Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=123064&r1=123063&r2=123064&view=diff
    ==============================================================================
    --- llvm/trunk/lib/CodeGen/StackProtector.cpp (original)
    +++ llvm/trunk/lib/CodeGen/StackProtector.cpp Sat Jan  8 11:01:52 2011
    @@ -16,6 +16,7 @@
     
     #define DEBUG_TYPE "stack-protector"
     #include "llvm/CodeGen/Passes.h"
    +#include "llvm/Analysis/Dominators.h"
     #include "llvm/Attributes.h"
     #include "llvm/Constants.h"
     #include "llvm/DerivedTypes.h"
    @@ -45,6 +46,8 @@
         Function *F;
         Module *M;
     
    +    DominatorTree* DT;
    +
         /// InsertStackProtectors - Insert code into the prologue and epilogue of
         /// the function.
         ///
    @@ -70,6 +73,10 @@
             initializeStackProtectorPass(*PassRegistry::getPassRegistry());
           }
     
    +    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
    +      AU.addPreserved();
    +    }
    +
         virtual bool runOnFunction(Function &Fn);
       };
     } // end anonymous namespace
    @@ -85,6 +92,7 @@
     bool StackProtector::runOnFunction(Function &Fn) {
       F = &Fn;
       M = F->getParent();
    +  DT = getAnalysisIfAvailable();
     
       if (!RequiresStackProtector()) return false;
       
    @@ -139,6 +147,7 @@
     ///    value. It calls __stack_chk_fail if they differ.
     bool StackProtector::InsertStackProtectors() {
       BasicBlock *FailBB = 0;       // The basic block to jump to if check fails.
    +  BasicBlock *FailBBDom = 0;    // FailBB's dominator.
       AllocaInst *AI = 0;           // Place on stack that stores the stack guard.
       Value *StackGuardVar = 0;  // The stack guard variable.
     
    @@ -182,6 +191,8 @@
     
           // Create the basic block to jump to when the guard check fails.
           FailBB = CreateFailBB();
    +      if (DT)
    +        FailBBDom = DT->isReachableFromEntry(BB) ? BB : 0;
         }
     
         // For each block with a return instruction, convert this:
    @@ -208,6 +219,10 @@
     
         // Split the basic block before the return instruction.
         BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return");
    +    if (DT) {
    +      DT->addNewBlock(NewBB, DT->isReachableFromEntry(BB) ? BB : 0);
    +      FailBBDom = DT->findNearestCommonDominator(FailBBDom, BB);
    +    }
     
         // Remove default branch instruction to the new BB.
         BB->getTerminator()->eraseFromParent();
    @@ -227,6 +242,9 @@
       // statements in the function.
       if (!FailBB) return false;
     
    +  if (DT)
    +    DT->addNewBlock(FailBB, FailBBDom);
    +
       return true;
     }
     
    
    Modified: llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp?rev=123064&r1=123063&r2=123064&view=diff
    ==============================================================================
    --- llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp (original)
    +++ llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp Sat Jan  8 11:01:52 2011
    @@ -26,6 +26,7 @@
     #include "llvm/Function.h"
     #include "llvm/Pass.h"
     #include "llvm/Type.h"
    +#include "llvm/Analysis/Dominators.h"
     #include "llvm/Analysis/ProfileInfo.h"
     #include "llvm/CodeGen/MachineDominators.h"
     #include "llvm/CodeGen/MachineFunctionPass.h"
    @@ -48,6 +49,7 @@
         }
     
         virtual void getAnalysisUsage(AnalysisUsage &AU) const {
    +      AU.addPreserved();
           AU.addPreserved();
         }
       };
    
    Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=123064&r1=123063&r2=123064&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original)
    +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Sat Jan  8 11:01:52 2011
    @@ -22,6 +22,7 @@
     #include "llvm/Instructions.h"
     #include "llvm/IntrinsicInst.h"
     #include "llvm/Pass.h"
    +#include "llvm/Analysis/Dominators.h"
     #include "llvm/Analysis/InstructionSimplify.h"
     #include "llvm/Analysis/ProfileInfo.h"
     #include "llvm/Target/TargetData.h"
    @@ -66,6 +67,7 @@
         /// TLI - Keep a pointer of a TargetLowering to consult for determining
         /// transformation profitability.
         const TargetLowering *TLI;
    +    DominatorTree *DT;
         ProfileInfo *PFI;
     
         /// BackEdges - Keep a set of all the loop back edges.
    @@ -86,6 +88,7 @@
         bool runOnFunction(Function &F);
     
         virtual void getAnalysisUsage(AnalysisUsage &AU) const {
    +      AU.addPreserved();
           AU.addPreserved();
         }
     
    @@ -131,6 +134,7 @@
     bool CodeGenPrepare::runOnFunction(Function &F) {
       bool EverMadeChange = false;
     
    +  DT = getAnalysisIfAvailable();
       PFI = getAnalysisIfAvailable();
       // First pass, eliminate blocks that contain only PHI nodes and an
       // unconditional branch.
    @@ -325,6 +329,13 @@
       // The PHIs are now updated, change everything that refers to BB to use
       // DestBB and remove BB.
       BB->replaceAllUsesWith(DestBB);
    +  if (DT) {
    +    BasicBlock *BBIDom  = DT->getNode(BB)->getIDom()->getBlock();
    +    BasicBlock *DestBBIDom = DT->getNode(DestBB)->getIDom()->getBlock();
    +    BasicBlock *NewIDom = DT->findNearestCommonDominator(BBIDom, DestBBIDom);
    +    DT->changeImmediateDominator(DestBB, NewIDom);
    +    DT->eraseNode(BB);
    +  }
       if (PFI) {
         PFI->replaceAllUses(BB, DestBB);
         PFI->removeEdge(ProfileInfo::getEdge(BB, DestBB));
    
    Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=123064&r1=123063&r2=123064&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
    +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Sat Jan  8 11:01:52 2011
    @@ -22,6 +22,7 @@
     #include "llvm/IntrinsicInst.h"
     #include "llvm/ADT/DenseMap.h"
     #include "llvm/ADT/SmallPtrSet.h"
    +#include "llvm/Analysis/Dominators.h"
     #include "llvm/Analysis/ConstantFolding.h"
     #include "llvm/Analysis/InstructionSimplify.h"
     #include "llvm/Analysis/ProfileInfo.h"
    @@ -401,6 +402,12 @@
       PredBB->replaceAllUsesWith(DestBB);
       
       if (P) {
    +    DominatorTree *DT = P->getAnalysisIfAvailable();
    +    if (DT) {
    +      BasicBlock *PredBBIDom = DT->getNode(PredBB)->getIDom()->getBlock();
    +      DT->changeImmediateDominator(DestBB, PredBBIDom);
    +      DT->eraseNode(PredBB);
    +    }
         ProfileInfo *PI = P->getAnalysisIfAvailable();
         if (PI) {
           PI->replaceAllUses(PredBB, DestBB);
    
    
    
    From zwarich at apple.com  Sat Jan  8 11:07:11 2011
    From: zwarich at apple.com (Cameron Zwarich)
    Date: Sat, 08 Jan 2011 17:07:11 -0000
    Subject: [llvm-commits] [llvm] r123065 -
    	/llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp
    Message-ID: <20110108170711.EF3652A6C12C@llvm.org>
    
    Author: zwarich
    Date: Sat Jan  8 11:07:11 2011
    New Revision: 123065
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123065&view=rev
    Log:
    Fix coding style issues.
    
    Modified:
        llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp
    
    Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp?rev=123065&r1=123064&r2=123065&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp (original)
    +++ llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Sat Jan  8 11:07:11 2011
    @@ -54,7 +54,7 @@
     INITIALIZE_PASS_END(LoopInstSimplify, "loop-instsimplify",
                     "Simplify instructions in loops", false, false)
     
    -Pass* llvm::createLoopInstSimplifyPass() {
    +Pass *llvm::createLoopInstSimplifyPass() {
       return new LoopInstSimplify();
     }
     
    @@ -87,7 +87,7 @@
     
         while (!VisitStack.empty()) {
           WorklistItem Item = VisitStack.pop_back_val();
    -      BasicBlock* BB = Item.getPointer();
    +      BasicBlock *BB = Item.getPointer();
           bool IsSubloopHeader = Item.getInt();
     
           // Simplify instructions in the current basic block.
    
    
    
    From sabre at nondot.org  Sat Jan  8 11:38:45 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 17:38:45 -0000
    Subject: [llvm-commits] [llvm] r123066 -
    	/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    Message-ID: <20110108173845.EB9FA2A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 11:38:45 2011
    New Revision: 123066
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123066&view=rev
    Log:
    fix an issue duncan pointed out, which could cause loop rotate
    to violate LCSSA form
    
    Modified:
        llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    
    Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=123066&r1=123065&r2=123066&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
    +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sat Jan  8 11:38:45 2011
    @@ -70,6 +70,7 @@
         void preserveCanonicalLoopForm(LPPassManager &LPM);
     
       private:
    +    LoopInfo *LI;
         Loop *L;
         BasicBlock *OrigHeader;
         BasicBlock *OrigPreHeader;
    @@ -89,21 +90,31 @@
     
     Pass *llvm::createLoopRotatePass() { return new LoopRotate(); }
     
    +/// Initialize local data
    +void LoopRotate::initialize() {
    +  L = NULL;
    +  OrigHeader = NULL;
    +  OrigPreHeader = NULL;
    +  NewHeader = NULL;
    +  Exit = NULL;
    +}
    +
     /// Rotate Loop L as many times as possible. Return true if
     /// the loop is rotated at least once.
     bool LoopRotate::runOnLoop(Loop *Lp, LPPassManager &LPM) {
    +  LI = &getAnalysis();
     
    -  bool RotatedOneLoop = false;
       initialize();
       LPM_Ptr = &LPM;
     
       // One loop can be rotated multiple times.
    +  bool MadeChange = false;
       while (rotateLoop(Lp,LPM)) {
    -    RotatedOneLoop = true;
    +    MadeChange = true;
         initialize();
       }
     
    -  return RotatedOneLoop;
    +  return MadeChange;
     }
     
     /// Rotate loop LP. Return true if the loop is rotated.
    @@ -213,7 +224,8 @@
         // With the operands remapped, see if the instruction constant folds or is
         // otherwise simplifyable.  This commonly occurs because the entry from PHI
         // nodes allows icmps and other instructions to fold.
    -    if (Value *V = SimplifyInstruction(C)) {
    +    Value *V = SimplifyInstruction(C);
    +    if (V && LI->replacementPreservesLCSSAForm(C, V)) {
           // If so, then delete the temporary instruction and stick the folded value
           // in the map.
           delete C;
    @@ -322,14 +334,6 @@
       return true;
     }
     
    -/// Initialize local data
    -void LoopRotate::initialize() {
    -  L = NULL;
    -  OrigHeader = NULL;
    -  OrigPreHeader = NULL;
    -  NewHeader = NULL;
    -  Exit = NULL;
    -}
     
     /// After loop rotation, loop pre-header has multiple sucessors.
     /// Insert one forwarding basic block to ensure that loop pre-header
    
    
    
    From clattner at apple.com  Sat Jan  8 11:41:54 2011
    From: clattner at apple.com (Chris Lattner)
    Date: Sat, 8 Jan 2011 09:41:54 -0800
    Subject: [llvm-commits] [llvm] r123060 - in /llvm/trunk:
    	lib/Transforms/Scalar/LoopRotation.cpp
    	test/Transforms/LoopRotate/phi-duplicate.ll
    In-Reply-To: <4D286867.2060406@free.fr>
    References: <20110108082446.945E22A6C12C@llvm.org> <4D286867.2060406@free.fr>
    Message-ID: <4AC15431-A051-49E2-BDDE-B784C326F48E@apple.com>
    
    
    On Jan 8, 2011, at 5:36 AM, Duncan Sands wrote:
    
    >>       delete C;
    >> +      ValueMap[Inst] = V;
    >> +    } else {
    > 
    > since instsimplify can look through phi nodes, it doesn't automatically preserve
    > LCSSA form.  Passes like loop-rotate that need to preserve LCSSA form should do
    > something like this:
    > 
    >   if (Value *V = SimplifyInstruction(C))
    >     if (LI->replacementPreservesLCSSAForm(C, V)) {
    >       .. use the simplification ...
    >     }
    
    Great catch, fixed in r123066, thanks!
    
    -Chris
    
    From clattner at apple.com  Sat Jan  8 11:43:39 2011
    From: clattner at apple.com (Chris Lattner)
    Date: Sat, 8 Jan 2011 09:43:39 -0800
    Subject: [llvm-commits] [llvm] r123064 - in /llvm/trunk/lib:
    	CodeGen/GCStrategy.cpp CodeGen/StackProtector.cpp
    	CodeGen/UnreachableBlockElim.cpp
    	Transforms/Scalar/CodeGenPrepare.cpp Transforms/Utils/Local.cpp
    In-Reply-To: <20110108170152.62B252A6C12C@llvm.org>
    References: <20110108170152.62B252A6C12C@llvm.org>
    Message-ID: <1974C6B8-B011-42FA-BA2F-DAE5466A59B6@apple.com>
    
    
    On Jan 8, 2011, at 9:01 AM, Cameron Zwarich wrote:
    
    > Author: zwarich
    > Date: Sat Jan  8 11:01:52 2011
    > New Revision: 123064
    > 
    > URL: http://llvm.org/viewvc/llvm-project?rev=123064&view=rev
    > Log:
    > Make more passes preserve dominators (or state that they preserve dominators if
    > they all ready do). This removes two dominator recomputations prior to isel,
    > which is a 1% improvement in total llc time for 403.gcc.
    
    Very nice.
    
    > The only potentially suspect thing is making GCStrategy recompute dominators if
    > it used a custom lowering strategy.
    
    This is definitely the right way to go.  Someone who cares about the compile time of the GC logic can improve it to update whenever they care enough. :)
    
    -Chris
     
    
    From sabre at nondot.org  Sat Jan  8 11:48:34 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 17:48:34 -0000
    Subject: [llvm-commits] [llvm] r123067 -
    	/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    Message-ID: <20110108174834.25CBB2A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 11:48:33 2011
    New Revision: 123067
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123067&view=rev
    Log:
    some cleanups: remove dead arguments and eliminate ivars
    that are just passed to one function.
    
    Modified:
        llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    
    Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=123067&r1=123066&r2=123067&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
    +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sat Jan  8 11:48:33 2011
    @@ -59,25 +59,18 @@
         // Helper functions
     
         /// Do actual work
    -    bool rotateLoop(Loop *L, LPPassManager &LPM);
    +    bool rotateLoop(Loop *L);
         
    -    /// Initialize local data
    -    void initialize();
    -
         /// After loop rotation, loop pre-header has multiple sucessors.
         /// Insert one forwarding basic block to ensure that loop pre-header
         /// has only one successor.
    -    void preserveCanonicalLoopForm(LPPassManager &LPM);
    +    void preserveCanonicalLoopForm(Loop *L, BasicBlock *OrigHeader,
    +                                   BasicBlock *OrigPreHeader,
    +                                   BasicBlock *OrigLatch, BasicBlock *NewHeader,
    +                                   BasicBlock *Exit);
     
       private:
         LoopInfo *LI;
    -    Loop *L;
    -    BasicBlock *OrigHeader;
    -    BasicBlock *OrigPreHeader;
    -    BasicBlock *OrigLatch;
    -    BasicBlock *NewHeader;
    -    BasicBlock *Exit;
    -    LPPassManager *LPM_Ptr;
       };
     }
       
    @@ -90,44 +83,28 @@
     
     Pass *llvm::createLoopRotatePass() { return new LoopRotate(); }
     
    -/// Initialize local data
    -void LoopRotate::initialize() {
    -  L = NULL;
    -  OrigHeader = NULL;
    -  OrigPreHeader = NULL;
    -  NewHeader = NULL;
    -  Exit = NULL;
    -}
    -
     /// Rotate Loop L as many times as possible. Return true if
     /// the loop is rotated at least once.
    -bool LoopRotate::runOnLoop(Loop *Lp, LPPassManager &LPM) {
    +bool LoopRotate::runOnLoop(Loop *L, LPPassManager &LPM) {
       LI = &getAnalysis();
     
    -  initialize();
    -  LPM_Ptr = &LPM;
    -
       // One loop can be rotated multiple times.
       bool MadeChange = false;
    -  while (rotateLoop(Lp,LPM)) {
    +  while (rotateLoop(L))
         MadeChange = true;
    -    initialize();
    -  }
     
       return MadeChange;
     }
     
     /// Rotate loop LP. Return true if the loop is rotated.
    -bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
    -  L = Lp;
    -
    -  OrigPreHeader = L->getLoopPreheader();
    +bool LoopRotate::rotateLoop(Loop *L) {
    +  BasicBlock *OrigPreHeader = L->getLoopPreheader();
       if (!OrigPreHeader) return false;
     
    -  OrigLatch = L->getLoopLatch();
    +  BasicBlock *OrigLatch = L->getLoopLatch();
       if (!OrigLatch) return false;
     
    -  OrigHeader =  L->getHeader();
    +  BasicBlock *OrigHeader =  L->getHeader();
     
       // If the loop has only one block then there is not much to rotate.
       if (L->getBlocks().size() == 1)
    @@ -171,8 +148,8 @@
       // Find new Loop header. NewHeader is a Header's one and only successor
       // that is inside loop.  Header's other successor is outside the
       // loop.  Otherwise loop is not suitable for rotation.
    -  Exit = BI->getSuccessor(0);
    -  NewHeader = BI->getSuccessor(1);
    +  BasicBlock *Exit = BI->getSuccessor(0);
    +  BasicBlock *NewHeader = BI->getSuccessor(1);
       if (L->contains(Exit))
         std::swap(Exit, NewHeader);
       assert(NewHeader && "Unable to determine new loop header");
    @@ -328,7 +305,8 @@
       // at this point, if we don't mind updating dominator info.
     
       // Establish a new preheader, update dominators, etc.
    -  preserveCanonicalLoopForm(LPM);
    +  preserveCanonicalLoopForm(L, OrigHeader, OrigPreHeader, OrigLatch,
    +                            NewHeader, Exit);
     
       ++NumRotated;
       return true;
    @@ -338,15 +316,18 @@
     /// After loop rotation, loop pre-header has multiple sucessors.
     /// Insert one forwarding basic block to ensure that loop pre-header
     /// has only one successor.
    -void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) {
    +void LoopRotate::preserveCanonicalLoopForm(Loop *L, BasicBlock *OrigHeader,
    +                                           BasicBlock *OrigPreHeader,
    +                                           BasicBlock *OrigLatch,
    +                                           BasicBlock *NewHeader,
    +                                           BasicBlock *Exit) {
     
       // Right now original pre-header has two successors, new header and
       // exit block. Insert new block between original pre-header and
       // new header such that loop's new pre-header has only one successor.
    -  BasicBlock *NewPreHeader = BasicBlock::Create(OrigHeader->getContext(),
    -                                                "bb.nph",
    -                                                OrigHeader->getParent(), 
    -                                                NewHeader);
    +  BasicBlock *NewPreHeader =
    +    BasicBlock::Create(OrigHeader->getContext(), "bb.nph",
    +                       OrigHeader->getParent(), NewHeader);
       LoopInfo &LI = getAnalysis();
       if (Loop *PL = LI.getLoopFor(OrigPreHeader))
         PL->addBasicBlockToLoop(NewPreHeader, LI.getBase());
    @@ -431,19 +412,19 @@
           for (Loop::block_iterator BI = L->block_begin(), BE = L->block_end();
                BI != BE; ++BI) {
             BasicBlock *B = *BI;
    -        if (DT->dominates(B, NewLatch)) {
    -          DominanceFrontier::iterator BDFI = DF->find(B);
    -          if (BDFI != DF->end()) {
    -            DominanceFrontier::DomSetType &BSet = BDFI->second;
    -            BSet.erase(NewLatch);
    -            BSet.insert(L->getHeader());
    -            BSet.insert(Exit);
    -          } else {
    -            DominanceFrontier::DomSetType BSet;
    -            BSet.insert(L->getHeader());
    -            BSet.insert(Exit);
    -            DF->addBasicBlock(B, BSet);
    -          }
    +        if (!DT->dominates(B, NewLatch)) continue;
    +        
    +        DominanceFrontier::iterator BDFI = DF->find(B);
    +        if (BDFI != DF->end()) {
    +          DominanceFrontier::DomSetType &BSet = BDFI->second;
    +          BSet.erase(NewLatch);
    +          BSet.insert(L->getHeader());
    +          BSet.insert(Exit);
    +        } else {
    +          DominanceFrontier::DomSetType BSet;
    +          BSet.insert(L->getHeader());
    +          BSet.insert(Exit);
    +          DF->addBasicBlock(B, BSet);
             }
           }
         }
    
    
    
    From sabre at nondot.org  Sat Jan  8 11:49:51 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 17:49:51 -0000
    Subject: [llvm-commits] [llvm] r123068 -
    	/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    Message-ID: <20110108174951.363B52A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 11:49:51 2011
    New Revision: 123068
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123068&view=rev
    Log:
    use the LI ivar.
    
    Modified:
        llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    
    Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=123068&r1=123067&r2=123068&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
    +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sat Jan  8 11:49:51 2011
    @@ -328,9 +328,8 @@
       BasicBlock *NewPreHeader =
         BasicBlock::Create(OrigHeader->getContext(), "bb.nph",
                            OrigHeader->getParent(), NewHeader);
    -  LoopInfo &LI = getAnalysis();
    -  if (Loop *PL = LI.getLoopFor(OrigPreHeader))
    -    PL->addBasicBlockToLoop(NewPreHeader, LI.getBase());
    +  if (Loop *PL = LI->getLoopFor(OrigPreHeader))
    +    PL->addBasicBlockToLoop(NewPreHeader, LI->getBase());
       BranchInst::Create(NewHeader, NewPreHeader);
       
       BranchInst *OrigPH_BI = cast(OrigPreHeader->getTerminator());
    
    
    
    From sabre at nondot.org  Sat Jan  8 12:06:22 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 18:06:22 -0000
    Subject: [llvm-commits] [llvm] r123069 -
    	/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    Message-ID: <20110108180622.E6F042A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 12:06:22 2011
    New Revision: 123069
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123069&view=rev
    Log:
    LoopRotate requires canonical loop form, so it always has preheaders
    and latch blocks.  Reorder entry conditions to make hte pass faster
    and more logical.
    
    Modified:
        llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    
    Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=123069&r1=123068&r2=123069&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
    +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sat Jan  8 12:06:22 2011
    @@ -98,29 +98,22 @@
     
     /// Rotate loop LP. Return true if the loop is rotated.
     bool LoopRotate::rotateLoop(Loop *L) {
    -  BasicBlock *OrigPreHeader = L->getLoopPreheader();
    -  if (!OrigPreHeader) return false;
    -
    -  BasicBlock *OrigLatch = L->getLoopLatch();
    -  if (!OrigLatch) return false;
    -
    -  BasicBlock *OrigHeader =  L->getHeader();
    -
       // If the loop has only one block then there is not much to rotate.
       if (L->getBlocks().size() == 1)
         return false;
    -
    +  
    +  BasicBlock *OrigHeader = L->getHeader();
    +  
    +  BranchInst *BI = dyn_cast(OrigHeader->getTerminator());
    +  if (BI == 0 || BI->isUnconditional())
    +    return false;
    +  
       // If the loop header is not one of the loop exiting blocks then
       // either this loop is already rotated or it is not
       // suitable for loop rotation transformations.
       if (!L->isLoopExiting(OrigHeader))
         return false;
     
    -  BranchInst *BI = dyn_cast(OrigHeader->getTerminator());
    -  if (!BI)
    -    return false;
    -  assert(BI->isConditional() && "Branch Instruction is not conditional");
    -
       // Updating PHInodes in loops with multiple exits adds complexity. 
       // Keep it simple, and restrict loop rotation to loops with one exit only.
       // In future, lift this restriction and support for multiple exits if
    @@ -139,6 +132,9 @@
       }
     
       // Now, this loop is suitable for rotation.
    +  BasicBlock *OrigPreHeader = L->getLoopPreheader();
    +  BasicBlock *OrigLatch = L->getLoopLatch();
    +  assert(OrigPreHeader && OrigLatch && "Loop not in canonical form?");
     
       // Anything ScalarEvolution may know about this loop or the PHI nodes
       // in its header will soon be invalidated.
    @@ -300,7 +296,7 @@
       // Also, since this original header only has one predecessor, zap its
       // PHI nodes, which are now trivial.
       FoldSingleEntryPHINodes(OrigHeader);
    -
    +  
       // TODO: We could just go ahead and merge OrigHeader into its predecessor
       // at this point, if we don't mind updating dominator info.
     
    
    
    
    From pichet2000 at gmail.com  Sat Jan  8 12:09:48 2011
    From: pichet2000 at gmail.com (Francois Pichet)
    Date: Sat, 08 Jan 2011 18:09:48 -0000
    Subject: [llvm-commits] [llvm] r123070 -
    	/llvm/trunk/utils/lit/lit/TestRunner.py
    Message-ID: <20110108180948.9388F2A6C12C@llvm.org>
    
    Author: fpichet
    Date: Sat Jan  8 12:09:48 2011
    New Revision: 123070
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123070&view=rev
    Log:
    On Windows, replace each occurrence of '\' by '\\' on the replacement string. This is necessary to prevent re.sub from replacing escape sequences occurring in path.
    
    For example:
    
    llvm\tools\clang\test
    was replaced by
    llvm  ools\clang  est
    
    Modified:
        llvm/trunk/utils/lit/lit/TestRunner.py
    
    Modified: llvm/trunk/utils/lit/lit/TestRunner.py
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/TestRunner.py?rev=123070&r1=123069&r2=123070&view=diff
    ==============================================================================
    --- llvm/trunk/utils/lit/lit/TestRunner.py (original)
    +++ llvm/trunk/utils/lit/lit/TestRunner.py Sat Jan  8 12:09:48 2011
    @@ -451,12 +451,10 @@
         # expression pattern a with substitution b in line ln.
         def processLine(ln):
             # Apply substitutions
    -		# FIXME: Investigate why re.sub doesn't work on Windows
             for a,b in substitutions:
                 if kIsWindows:
    -                ln = ln.replace(a,b)
    -            else:
    -                ln = re.sub(a, b, ln)
    +                b = b.replace("\\","\\\\")
    +            ln = re.sub(a, b, ln)
     
             # Strip the trailing newline and any extra whitespace.
             return ln.strip()
    
    
    
    From sabre at nondot.org  Sat Jan  8 12:47:43 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 18:47:43 -0000
    Subject: [llvm-commits] [llvm] r123071 -
    	/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
    Message-ID: <20110108184743.611112A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 12:47:43 2011
    New Revision: 123071
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123071&view=rev
    Log:
    reduce nesting.
    
    Modified:
        llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
    
    Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=123071&r1=123070&r2=123071&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original)
    +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Sat Jan  8 12:47:43 2011
    @@ -254,13 +254,13 @@
         assert(SP == BB && "CFG broken");
         SP = NULL;
         return SplitBlock(Succ, Succ->begin(), P);
    -  } else {
    -    // Otherwise, if BB has a single successor, split it at the bottom of the
    -    // block.
    -    assert(BB->getTerminator()->getNumSuccessors() == 1 &&
    -           "Should have a single succ!"); 
    -    return SplitBlock(BB, BB->getTerminator(), P);
       }
    +  
    +  // Otherwise, if BB has a single successor, split it at the bottom of the
    +  // block.
    +  assert(BB->getTerminator()->getNumSuccessors() == 1 &&
    +         "Should have a single succ!"); 
    +  return SplitBlock(BB, BB->getTerminator(), P);
     }
     
     /// SplitBlock - Split the specified block at the specified instruction - every
    
    
    
    From sabre at nondot.org  Sat Jan  8 12:52:51 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 18:52:51 -0000
    Subject: [llvm-commits] [llvm] r123072 - in /llvm/trunk:
     lib/Transforms/Scalar/LoopRotation.cpp
     test/Transforms/LoopRotate/phi-duplicate.ll
    Message-ID: <20110108185251.B5E862A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 12:52:51 2011
    New Revision: 123072
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123072&view=rev
    Log:
    Three major changes:
    1. Rip out LoopRotate's domfrontier updating code.  It isn't
       needed now that LICM doesn't use DF and it is super complex
       and gross.
    2. Make DomTree updating code a lot simpler and faster.  The 
       old loop over all the blocks was just to find a block??
    3. Change the code that inserts the new preheader to just use
       SplitCriticalEdge instead of doing an overcomplex 
       reimplementation of it.
    
    No behavior change, except for the name of the inserted preheader.
    
    Modified:
        llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
        llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll
    
    Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=123072&r1=123071&r2=123072&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
    +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sat Jan  8 12:52:51 2011
    @@ -15,7 +15,6 @@
     #include "llvm/Transforms/Scalar.h"
     #include "llvm/Function.h"
     #include "llvm/Analysis/CodeMetrics.h"
    -#include "llvm/Analysis/DominanceFrontier.h"
     #include "llvm/Analysis/LoopPass.h"
     #include "llvm/Analysis/InstructionSimplify.h"
     #include "llvm/Analysis/ScalarEvolution.h"
    @@ -46,7 +45,6 @@
         // LCSSA form makes instruction renaming easier.
         virtual void getAnalysisUsage(AnalysisUsage &AU) const {
           AU.addPreserved();
    -      AU.addPreserved();
           AU.addRequired();
           AU.addPreserved();
           AU.addRequiredID(LoopSimplifyID);
    @@ -296,7 +294,7 @@
       // Also, since this original header only has one predecessor, zap its
       // PHI nodes, which are now trivial.
       FoldSingleEntryPHINodes(OrigHeader);
    -  
    +
       // TODO: We could just go ahead and merge OrigHeader into its predecessor
       // at this point, if we don't mind updating dominator info.
     
    @@ -309,130 +307,37 @@
     }
     
     
    -/// After loop rotation, loop pre-header has multiple sucessors.
    -/// Insert one forwarding basic block to ensure that loop pre-header
    -/// has only one successor.
    +/// Update LoopInfo, DominatorTree, and DomFrontiers to reflect the CFG change
    +/// we just made.  Then split edges as necessary to preserve LoopSimplify form.
     void LoopRotate::preserveCanonicalLoopForm(Loop *L, BasicBlock *OrigHeader,
                                                BasicBlock *OrigPreHeader,
                                                BasicBlock *OrigLatch,
                                                BasicBlock *NewHeader,
                                                BasicBlock *Exit) {
    -
    -  // Right now original pre-header has two successors, new header and
    -  // exit block. Insert new block between original pre-header and
    -  // new header such that loop's new pre-header has only one successor.
    -  BasicBlock *NewPreHeader =
    -    BasicBlock::Create(OrigHeader->getContext(), "bb.nph",
    -                       OrigHeader->getParent(), NewHeader);
    -  if (Loop *PL = LI->getLoopFor(OrigPreHeader))
    -    PL->addBasicBlockToLoop(NewPreHeader, LI->getBase());
    -  BranchInst::Create(NewHeader, NewPreHeader);
    -  
    -  BranchInst *OrigPH_BI = cast(OrigPreHeader->getTerminator());
    -  if (OrigPH_BI->getSuccessor(0) == NewHeader)
    -    OrigPH_BI->setSuccessor(0, NewPreHeader);
    -  else {
    -    assert(OrigPH_BI->getSuccessor(1) == NewHeader &&
    -           "Unexpected original pre-header terminator");
    -    OrigPH_BI->setSuccessor(1, NewPreHeader);
    -  }
    -
    -  PHINode *PN;
    -  for (BasicBlock::iterator I = NewHeader->begin();
    -       (PN = dyn_cast(I)); ++I) {
    -    int index = PN->getBasicBlockIndex(OrigPreHeader);
    -    assert(index != -1 && "Expected incoming value from Original PreHeader");
    -    PN->setIncomingBlock(index, NewPreHeader);
    -    assert(PN->getBasicBlockIndex(OrigPreHeader) == -1 && 
    -           "Expected only one incoming value from Original PreHeader");
    -  }
    +  assert(L->getHeader() == NewHeader && "Latch block is our new header");
     
       if (DominatorTree *DT = getAnalysisIfAvailable()) {
    -    DT->addNewBlock(NewPreHeader, OrigPreHeader);
    -    DT->changeImmediateDominator(L->getHeader(), NewPreHeader);
    +    // Since OrigPreheader now has the conditional branch to Exit block, it is
    +    // the dominator of Exit.
         DT->changeImmediateDominator(Exit, OrigPreHeader);
    -    for (Loop::block_iterator BI = L->block_begin(), BE = L->block_end();
    -         BI != BE; ++BI) {
    -      BasicBlock *B = *BI;
    -      if (L->getHeader() != B) {
    -        DomTreeNode *Node = DT->getNode(B);
    -        if (Node && Node->getBlock() == OrigHeader)
    -          DT->changeImmediateDominator(*BI, L->getHeader());
    -      }
    -    }
    +    DT->changeImmediateDominator(NewHeader, OrigPreHeader);
    +    
    +    // Update OrigHeader to be dominated by the new header block.
         DT->changeImmediateDominator(OrigHeader, OrigLatch);
       }
    -
    -  if (DominanceFrontier *DF = getAnalysisIfAvailable()) {
    -    // New Preheader's dominance frontier is Exit block.
    -    DominanceFrontier::DomSetType NewPHSet;
    -    NewPHSet.insert(Exit);
    -    DF->addBasicBlock(NewPreHeader, NewPHSet);
    -
    -    // New Header's dominance frontier now includes itself and Exit block
    -    DominanceFrontier::iterator HeadI = DF->find(L->getHeader());
    -    if (HeadI != DF->end()) {
    -      DominanceFrontier::DomSetType & HeaderSet = HeadI->second;
    -      HeaderSet.clear();
    -      HeaderSet.insert(L->getHeader());
    -      HeaderSet.insert(Exit);
    -    } else {
    -      DominanceFrontier::DomSetType HeaderSet;
    -      HeaderSet.insert(L->getHeader());
    -      HeaderSet.insert(Exit);
    -      DF->addBasicBlock(L->getHeader(), HeaderSet);
    -    }
    -
    -    // Original header (new Loop Latch)'s dominance frontier is Exit.
    -    DominanceFrontier::iterator LatchI = DF->find(L->getLoopLatch());
    -    if (LatchI != DF->end()) {
    -      DominanceFrontier::DomSetType &LatchSet = LatchI->second;
    -      LatchSet = LatchI->second;
    -      LatchSet.clear();
    -      LatchSet.insert(Exit);
    -    } else {
    -      DominanceFrontier::DomSetType LatchSet;
    -      LatchSet.insert(Exit);
    -      DF->addBasicBlock(L->getHeader(), LatchSet);
    -    }
    -
    -    // If a loop block dominates new loop latch then add to its frontiers
    -    // new header and Exit and remove new latch (which is equal to original
    -    // header).
    -    BasicBlock *NewLatch = L->getLoopLatch();
    -
    -    assert(NewLatch == OrigHeader && "NewLatch is inequal to OrigHeader");
    -
    -    if (DominatorTree *DT = getAnalysisIfAvailable()) {
    -      for (Loop::block_iterator BI = L->block_begin(), BE = L->block_end();
    -           BI != BE; ++BI) {
    -        BasicBlock *B = *BI;
    -        if (!DT->dominates(B, NewLatch)) continue;
    -        
    -        DominanceFrontier::iterator BDFI = DF->find(B);
    -        if (BDFI != DF->end()) {
    -          DominanceFrontier::DomSetType &BSet = BDFI->second;
    -          BSet.erase(NewLatch);
    -          BSet.insert(L->getHeader());
    -          BSet.insert(Exit);
    -        } else {
    -          DominanceFrontier::DomSetType BSet;
    -          BSet.insert(L->getHeader());
    -          BSet.insert(Exit);
    -          DF->addBasicBlock(B, BSet);
    -        }
    -      }
    -    }
    -  }
    -
    -  // Preserve canonical loop form, which means Exit block should
    -  // have only one predecessor.
    -  SplitEdge(L->getLoopLatch(), Exit, this);
    +  
    +  // Right now OrigPreHeader has two successors, NewHeader and ExitBlock, and
    +  // thus is not a preheader anymore.  Split the edge to form a real preheader.
    +  BasicBlock *NewPH = SplitCriticalEdge(OrigPreHeader, NewHeader, this);
    +  NewPH->setName(NewHeader->getName() + ".lr.ph");
    +  
    +  // Preserve canonical loop form, which means Exit block should have only one
    +  // predecessor.
    +  SplitCriticalEdge(L->getLoopLatch(), Exit, this);
     
       assert(NewHeader && L->getHeader() == NewHeader &&
              "Invalid loop header after loop rotation");
    -  assert(NewPreHeader && L->getLoopPreheader() == NewPreHeader &&
    +  assert(L->getLoopPreheader() == NewPH &&
              "Invalid loop preheader after loop rotation");
    -  assert(L->getLoopLatch() &&
    -         "Invalid loop latch after loop rotation");
    +  assert(L->getLoopLatch() && "Invalid loop latch after loop rotation");
     }
    
    Modified: llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll?rev=123072&r1=123071&r2=123072&view=diff
    ==============================================================================
    --- llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll (original)
    +++ llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll Sat Jan  8 12:52:51 2011
    @@ -34,9 +34,9 @@
     
     ; CHECK:      define void @test
     ; CHECK-NEXT: entry:
    -; CHECK-NEXT:   br i1 true, label %bb.nph, label %for.end
    +; CHECK-NEXT:   br i1 true, label %for.body.lr.ph, label %for.end
     ; CHECK-NOT:  :
    -; CHECK:      bb.nph:
    +; CHECK:      for.body.lr.ph:
     ; CHECK-NEXT:   br label %for.body
     ; CHECK-NOT:  :
     ; CHECK:      for.body:
    
    
    
    From sabre at nondot.org  Sat Jan  8 12:55:50 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 18:55:50 -0000
    Subject: [llvm-commits] [llvm] r123073 -
    	/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    Message-ID: <20110108185550.5C2FC2A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 12:55:50 2011
    New Revision: 123073
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123073&view=rev
    Log:
    inline preserveCanonicalLoopForm now that it is simple.
    
    Modified:
        llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    
    Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=123073&r1=123072&r2=123073&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
    +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sat Jan  8 12:55:50 2011
    @@ -38,10 +38,6 @@
           initializeLoopRotatePass(*PassRegistry::getPassRegistry());
         }
     
    -    // Rotate Loop L as many times as possible. Return true if
    -    // loop is rotated at least once.
    -    bool runOnLoop(Loop *L, LPPassManager &LPM);
    -
         // LCSSA form makes instruction renaming easier.
         virtual void getAnalysisUsage(AnalysisUsage &AU) const {
           AU.addPreserved();
    @@ -54,19 +50,9 @@
           AU.addPreserved();
         }
     
    -    // Helper functions
    -
    -    /// Do actual work
    +    bool runOnLoop(Loop *L, LPPassManager &LPM);
         bool rotateLoop(Loop *L);
         
    -    /// After loop rotation, loop pre-header has multiple sucessors.
    -    /// Insert one forwarding basic block to ensure that loop pre-header
    -    /// has only one successor.
    -    void preserveCanonicalLoopForm(Loop *L, BasicBlock *OrigHeader,
    -                                   BasicBlock *OrigPreHeader,
    -                                   BasicBlock *OrigLatch, BasicBlock *NewHeader,
    -                                   BasicBlock *Exit);
    -
       private:
         LoopInfo *LI;
       };
    @@ -295,27 +281,12 @@
       // PHI nodes, which are now trivial.
       FoldSingleEntryPHINodes(OrigHeader);
     
    -  // TODO: We could just go ahead and merge OrigHeader into its predecessor
    -  // at this point, if we don't mind updating dominator info.
    -
    -  // Establish a new preheader, update dominators, etc.
    -  preserveCanonicalLoopForm(L, OrigHeader, OrigPreHeader, OrigLatch,
    -                            NewHeader, Exit);
    -
    -  ++NumRotated;
    -  return true;
    -}
    -
    -
    -/// Update LoopInfo, DominatorTree, and DomFrontiers to reflect the CFG change
    -/// we just made.  Then split edges as necessary to preserve LoopSimplify form.
    -void LoopRotate::preserveCanonicalLoopForm(Loop *L, BasicBlock *OrigHeader,
    -                                           BasicBlock *OrigPreHeader,
    -                                           BasicBlock *OrigLatch,
    -                                           BasicBlock *NewHeader,
    -                                           BasicBlock *Exit) {
    +  
    +  
    +  // Update DominatorTree to reflect the CFG change we just made.  Then split
    +  // edges as necessary to preserve LoopSimplify form.
       assert(L->getHeader() == NewHeader && "Latch block is our new header");
    -
    +  
       if (DominatorTree *DT = getAnalysisIfAvailable()) {
         // Since OrigPreheader now has the conditional branch to Exit block, it is
         // the dominator of Exit.
    @@ -331,13 +302,20 @@
       BasicBlock *NewPH = SplitCriticalEdge(OrigPreHeader, NewHeader, this);
       NewPH->setName(NewHeader->getName() + ".lr.ph");
       
    -  // Preserve canonical loop form, which means Exit block should have only one
    +  // Preserve canonical loop form, which means that 'Exit' should have only one
       // predecessor.
       SplitCriticalEdge(L->getLoopLatch(), Exit, this);
    -
    -  assert(NewHeader && L->getHeader() == NewHeader &&
    -         "Invalid loop header after loop rotation");
    +  
       assert(L->getLoopPreheader() == NewPH &&
              "Invalid loop preheader after loop rotation");
       assert(L->getLoopLatch() && "Invalid loop latch after loop rotation");
    +
    +  
    +  // TODO: We could just go ahead and merge OrigHeader into its predecessor
    +  // at this point, if we don't mind updating dominator info.
    +  
    +  ++NumRotated;
    +  return true;
     }
    +
    +
    
    
    
    From sabre at nondot.org  Sat Jan  8 13:08:40 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 19:08:40 -0000
    Subject: [llvm-commits] [llvm] r123074 -
    	/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
    Message-ID: <20110108190840.651922A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 13:08:40 2011
    New Revision: 123074
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123074&view=rev
    Log:
    various code cleanups, enhance MergeBlockIntoPredecessor to preserve
    loop info.
    
    Modified:
        llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
    
    Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=123074&r1=123073&r2=123074&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original)
    +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Sat Jan  8 13:08:40 2011
    @@ -110,7 +110,7 @@
       if (isa(PredBB->getTerminator())) return false;
       
       succ_iterator SI(succ_begin(PredBB)), SE(succ_end(PredBB));
    -  BasicBlock* OnlySucc = BB;
    +  BasicBlock *OnlySucc = BB;
       for (; SI != SE; ++SI)
         if (*SI != OnlySucc) {
           OnlySucc = 0;     // There are multiple distinct successors!
    @@ -131,10 +131,8 @@
       }
     
       // Begin by getting rid of unneeded PHIs.
    -  while (PHINode *PN = dyn_cast(&BB->front())) {
    -    PN->replaceAllUsesWith(PN->getIncomingValue(0));
    -    BB->getInstList().pop_front();  // Delete the phi node...
    -  }
    +  if (isa(BB->front()))
    +    FoldSingleEntryPHINodes(BB);
       
       // Delete the unconditional branch from the predecessor...
       PredBB->getInstList().pop_back();
    @@ -152,11 +150,9 @@
       
       // Finally, erase the old block and update dominator info.
       if (P) {
    -    if (DominatorTree* DT = P->getAnalysisIfAvailable()) {
    -      DomTreeNode* DTN = DT->getNode(BB);
    -      DomTreeNode* PredDTN = DT->getNode(PredBB);
    -  
    -      if (DTN) {
    +    if (DominatorTree *DT = P->getAnalysisIfAvailable()) {
    +      if (DomTreeNode *DTN = DT->getNode(BB)) {
    +        DomTreeNode *PredDTN = DT->getNode(PredBB);
             SmallPtrSet Children(DTN->begin(), DTN->end());
             for (SmallPtrSet::iterator DI = Children.begin(),
                  DE = Children.end(); DI != DE; ++DI)
    @@ -164,12 +160,13 @@
     
             DT->eraseNode(BB);
           }
    +      
    +      if (LoopInfo *LI = P->getAnalysisIfAvailable())
    +        LI->removeBlock(BB);
         }
       }
       
       BB->eraseFromParent();
    -  
    -  
       return true;
     }
     
    @@ -276,7 +273,7 @@
     
       // The new block lives in whichever loop the old one did. This preserves
       // LCSSA as well, because we force the split point to be after any PHI nodes.
    -  if (LoopInfo* LI = P->getAnalysisIfAvailable())
    +  if (LoopInfo *LI = P->getAnalysisIfAvailable())
         if (Loop *L = LI->getLoopFor(Old))
           L->addBasicBlockToLoop(New, LI->getBase());
     
    
    
    
    From sabre at nondot.org  Sat Jan  8 13:10:28 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 19:10:28 -0000
    Subject: [llvm-commits] [llvm] r123075 -
    	/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    Message-ID: <20110108191028.87DF22A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 13:10:28 2011
    New Revision: 123075
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123075&view=rev
    Log:
    Implement a TODO: Enhance loopinfo to merge away the unconditional branch
    that it was leaving in loops after rotation (between the original latch
    block and the original header.
    
    With this change, it is possible for rotated loops to have just a single
    basic block, which is useful.
    
    Modified:
        llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    
    Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=123075&r1=123074&r2=123075&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
    +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sat Jan  8 13:10:28 2011
    @@ -264,6 +264,7 @@
     
       // NewHeader is now the header of the loop.
       L->moveToHeader(NewHeader);
    +  assert(L->getHeader() == NewHeader && "Latch block is our new header");
     
       // Move the original header to the bottom of the loop, where it now more
       // naturally belongs. This isn't necessary for correctness, and CodeGen can
    @@ -277,16 +278,9 @@
              "Original loop header has too many predecessors after loop rotation!");
       OrigHeader->moveAfter(OrigHeader->getSinglePredecessor());
     
    -  // Also, since this original header only has one predecessor, zap its
    -  // PHI nodes, which are now trivial.
    -  FoldSingleEntryPHINodes(OrigHeader);
    -
    -  
       
       // Update DominatorTree to reflect the CFG change we just made.  Then split
       // edges as necessary to preserve LoopSimplify form.
    -  assert(L->getHeader() == NewHeader && "Latch block is our new header");
    -  
       if (DominatorTree *DT = getAnalysisIfAvailable()) {
         // Since OrigPreheader now has the conditional branch to Exit block, it is
         // the dominator of Exit.
    @@ -310,12 +304,14 @@
              "Invalid loop preheader after loop rotation");
       assert(L->getLoopLatch() && "Invalid loop latch after loop rotation");
     
    -  
    -  // TODO: We could just go ahead and merge OrigHeader into its predecessor
    -  // at this point, if we don't mind updating dominator info.
    +  // Now that the CFG and DomTree are in a consistent state again, merge the
    +  // OrigHeader block into OrigLatch.  We know that they are joined by an
    +  // unconditional branch.  This is just a cleanup so the emitted code isn't
    +  // too gross.
    +  bool DidIt = MergeBlockIntoPredecessor(OrigHeader, this);
    +  assert(DidIt && "Block merge failed??"); (void)DidIt;
       
       ++NumRotated;
       return true;
     }
     
    -
    
    
    
    From sabre at nondot.org  Sat Jan  8 13:26:33 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 19:26:33 -0000
    Subject: [llvm-commits] [llvm] r123077 -
    	/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    Message-ID: <20110108192633.8B2B62A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 13:26:33 2011
    New Revision: 123077
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123077&view=rev
    Log:
    split ssa updating code out to its own helper function.  Don't bother
    moving the OrigHeader block anymore: we just merge it away anyway so
    its code layout doesn't matter.
    
    Modified:
        llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    
    Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=123077&r1=123076&r2=123077&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
    +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sat Jan  8 13:26:33 2011
    @@ -80,6 +80,71 @@
       return MadeChange;
     }
     
    +/// RewriteUsesOfClonedInstructions - We just cloned the instructions from the
    +/// old header into the preheader.  If there were uses of the values produced by
    +/// these instruction that were outside of the loop, we have to insert PHI nodes
    +/// to merge the two values.  Do this now.
    +static void RewriteUsesOfClonedInstructions(BasicBlock *OrigHeader,
    +                                            BasicBlock *OrigPreheader,
    +                                            ValueToValueMapTy &ValueMap) {
    +  // Remove PHI node entries that are no longer live.
    +  BasicBlock::iterator I, E = OrigHeader->end();
    +  for (I = OrigHeader->begin(); PHINode *PN = dyn_cast(I); ++I)
    +    PN->removeIncomingValue(PN->getBasicBlockIndex(OrigPreheader));
    +    
    +  // Now fix up users of the instructions in OrigHeader, inserting PHI nodes
    +  // as necessary.
    +  SSAUpdater SSA;
    +  for (I = OrigHeader->begin(); I != E; ++I) {
    +    Value *OrigHeaderVal = I;
    +    
    +    // If there are no uses of the value (e.g. because it returns void), there
    +    // is nothing to rewrite.
    +    if (OrigHeaderVal->use_empty())
    +      continue;
    +    
    +    Value *OrigPreHeaderVal = ValueMap[OrigHeaderVal];
    +
    +    // The value now exits in two versions: the initial value in the preheader
    +    // and the loop "next" value in the original header.
    +    SSA.Initialize(OrigHeaderVal->getType(), OrigHeaderVal->getName());
    +    SSA.AddAvailableValue(OrigHeader, OrigHeaderVal);
    +    SSA.AddAvailableValue(OrigPreheader, OrigPreHeaderVal);
    +    
    +    // Visit each use of the OrigHeader instruction.
    +    for (Value::use_iterator UI = OrigHeaderVal->use_begin(),
    +         UE = OrigHeaderVal->use_end(); UI != UE; ) {
    +      // Grab the use before incrementing the iterator.
    +      Use &U = UI.getUse();
    +      
    +      // Increment the iterator before removing the use from the list.
    +      ++UI;
    +      
    +      // SSAUpdater can't handle a non-PHI use in the same block as an
    +      // earlier def. We can easily handle those cases manually.
    +      Instruction *UserInst = cast(U.getUser());
    +      if (!isa(UserInst)) {
    +        BasicBlock *UserBB = UserInst->getParent();
    +        
    +        // The original users in the OrigHeader are already using the
    +        // original definitions.
    +        if (UserBB == OrigHeader)
    +          continue;
    +        
    +        // Users in the OrigPreHeader need to use the value to which the
    +        // original definitions are mapped.
    +        if (UserBB == OrigPreheader) {
    +          U = OrigPreHeaderVal;
    +          continue;
    +        }
    +      }
    +      
    +      // Anything else can be handled by SSAUpdater.
    +      SSA.RewriteUse(U);
    +    }
    +  }
    +}  
    +
     /// Rotate loop LP. Return true if the loop is rotated.
     bool LoopRotate::rotateLoop(Loop *L) {
       // If the loop has only one block then there is not much to rotate.
    @@ -116,9 +181,9 @@
       }
     
       // Now, this loop is suitable for rotation.
    -  BasicBlock *OrigPreHeader = L->getLoopPreheader();
    +  BasicBlock *OrigPreheader = L->getLoopPreheader();
       BasicBlock *OrigLatch = L->getLoopLatch();
    -  assert(OrigPreHeader && OrigLatch && "Loop not in canonical form?");
    +  assert(OrigPreheader && OrigLatch && "Loop not in canonical form?");
     
       // Anything ScalarEvolution may know about this loop or the PHI nodes
       // in its header will soon be invalidated.
    @@ -150,11 +215,11 @@
       // For PHI nodes, the value available in OldPreHeader is just the
       // incoming value from OldPreHeader.
       for (; PHINode *PN = dyn_cast(I); ++I)
    -    ValueMap[PN] = PN->getIncomingValue(PN->getBasicBlockIndex(OrigPreHeader));
    +    ValueMap[PN] = PN->getIncomingValue(PN->getBasicBlockIndex(OrigPreheader));
     
       // For the rest of the instructions, either hoist to the OrigPreheader if
       // possible or create a clone in the OldPreHeader if not.
    -  TerminatorInst *LoopEntryBranch = OrigPreHeader->getTerminator();
    +  TerminatorInst *LoopEntryBranch = OrigPreheader->getTerminator();
       while (I != E) {
         Instruction *Inst = I++;
         
    @@ -202,90 +267,28 @@
       for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
         for (BasicBlock::iterator BI = TI->getSuccessor(i)->begin();
              PHINode *PN = dyn_cast(BI); ++BI)
    -      PN->addIncoming(PN->getIncomingValueForBlock(OrigHeader), OrigPreHeader);
    +      PN->addIncoming(PN->getIncomingValueForBlock(OrigHeader), OrigPreheader);
     
       // Now that OrigPreHeader has a clone of OrigHeader's terminator, remove
       // OrigPreHeader's old terminator (the original branch into the loop), and
       // remove the corresponding incoming values from the PHI nodes in OrigHeader.
       LoopEntryBranch->eraseFromParent();
    -  for (I = OrigHeader->begin(); PHINode *PN = dyn_cast(I); ++I)
    -    PN->removeIncomingValue(PN->getBasicBlockIndex(OrigPreHeader));
    -
    -  // Now fix up users of the instructions in OrigHeader, inserting PHI nodes
    -  // as necessary.
    -  SSAUpdater SSA;
    -  for (I = OrigHeader->begin(); I != E; ++I) {
    -    Value *OrigHeaderVal = I;
    -    Value *OrigPreHeaderVal = ValueMap[OrigHeaderVal];
    -
    -    // If there are no uses of the value (e.g. because it returns void), there
    -    // is nothing to rewrite.
    -    if (OrigHeaderVal->use_empty() && OrigPreHeaderVal->use_empty())
    -      continue;
    -    
    -    // The value now exits in two versions: the initial value in the preheader
    -    // and the loop "next" value in the original header.
    -    SSA.Initialize(OrigHeaderVal->getType(), OrigHeaderVal->getName());
    -    SSA.AddAvailableValue(OrigHeader, OrigHeaderVal);
    -    SSA.AddAvailableValue(OrigPreHeader, OrigPreHeaderVal);
    -
    -    // Visit each use of the OrigHeader instruction.
    -    for (Value::use_iterator UI = OrigHeaderVal->use_begin(),
    -         UE = OrigHeaderVal->use_end(); UI != UE; ) {
    -      // Grab the use before incrementing the iterator.
    -      Use &U = UI.getUse();
    -
    -      // Increment the iterator before removing the use from the list.
    -      ++UI;
     
    -      // SSAUpdater can't handle a non-PHI use in the same block as an
    -      // earlier def. We can easily handle those cases manually.
    -      Instruction *UserInst = cast(U.getUser());
    -      if (!isa(UserInst)) {
    -        BasicBlock *UserBB = UserInst->getParent();
    -
    -        // The original users in the OrigHeader are already using the
    -        // original definitions.
    -        if (UserBB == OrigHeader)
    -          continue;
    -
    -        // Users in the OrigPreHeader need to use the value to which the
    -        // original definitions are mapped.
    -        if (UserBB == OrigPreHeader) {
    -          U = OrigPreHeaderVal;
    -          continue;
    -        }
    -      }
    -
    -      // Anything else can be handled by SSAUpdater.
    -      SSA.RewriteUse(U);
    -    }
    -  }
    +  // If there were any uses of instructions in the duplicated block outside the
    +  // loop, update them, inserting PHI nodes as required
    +  RewriteUsesOfClonedInstructions(OrigHeader, OrigPreheader, ValueMap);
     
       // NewHeader is now the header of the loop.
       L->moveToHeader(NewHeader);
       assert(L->getHeader() == NewHeader && "Latch block is our new header");
     
    -  // Move the original header to the bottom of the loop, where it now more
    -  // naturally belongs. This isn't necessary for correctness, and CodeGen can
    -  // usually reorder blocks on its own to fix things like this up, but it's
    -  // still nice to keep the IR readable.
    -  //
    -  // The original header should have only one predecessor at this point, since
    -  // we checked that the loop had a proper preheader and unique backedge before
    -  // we started.
    -  assert(OrigHeader->getSinglePredecessor() &&
    -         "Original loop header has too many predecessors after loop rotation!");
    -  OrigHeader->moveAfter(OrigHeader->getSinglePredecessor());
    -
    -  
       // Update DominatorTree to reflect the CFG change we just made.  Then split
       // edges as necessary to preserve LoopSimplify form.
       if (DominatorTree *DT = getAnalysisIfAvailable()) {
         // Since OrigPreheader now has the conditional branch to Exit block, it is
         // the dominator of Exit.
    -    DT->changeImmediateDominator(Exit, OrigPreHeader);
    -    DT->changeImmediateDominator(NewHeader, OrigPreHeader);
    +    DT->changeImmediateDominator(Exit, OrigPreheader);
    +    DT->changeImmediateDominator(NewHeader, OrigPreheader);
         
         // Update OrigHeader to be dominated by the new header block.
         DT->changeImmediateDominator(OrigHeader, OrigLatch);
    @@ -293,12 +296,13 @@
       
       // Right now OrigPreHeader has two successors, NewHeader and ExitBlock, and
       // thus is not a preheader anymore.  Split the edge to form a real preheader.
    -  BasicBlock *NewPH = SplitCriticalEdge(OrigPreHeader, NewHeader, this);
    +  BasicBlock *NewPH = SplitCriticalEdge(OrigPreheader, NewHeader, this);
       NewPH->setName(NewHeader->getName() + ".lr.ph");
       
       // Preserve canonical loop form, which means that 'Exit' should have only one
       // predecessor.
    -  SplitCriticalEdge(L->getLoopLatch(), Exit, this);
    +  BasicBlock *ExitSplit = SplitCriticalEdge(L->getLoopLatch(), Exit, this);
    +  ExitSplit->moveBefore(Exit);
       
       assert(L->getLoopPreheader() == NewPH &&
              "Invalid loop preheader after loop rotation");
    
    
    
    From sabre at nondot.org  Sat Jan  8 13:55:55 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 19:55:55 -0000
    Subject: [llvm-commits] [llvm] r123078 -
    	/llvm/trunk/lib/VMCore/Dominators.cpp
    Message-ID: <20110108195555.C73722A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 13:55:55 2011
    New Revision: 123078
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123078&view=rev
    Log:
    make domtree verification print something useful on failure.
    
    Modified:
        llvm/trunk/lib/VMCore/Dominators.cpp
    
    Modified: llvm/trunk/lib/VMCore/Dominators.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Dominators.cpp?rev=123078&r1=123077&r2=123078&view=diff
    ==============================================================================
    --- llvm/trunk/lib/VMCore/Dominators.cpp (original)
    +++ llvm/trunk/lib/VMCore/Dominators.cpp Sat Jan  8 13:55:55 2011
    @@ -68,7 +68,14 @@
     
       DominatorTree OtherDT;
       OtherDT.getBase().recalculate(F);
    -  assert(!compare(OtherDT) && "Invalid DominatorTree info!");
    +  if (compare(OtherDT)) {
    +    errs() << "DominatorTree is not up to date!  Computed:\n";
    +    print(errs());
    +    
    +    errs() << "\nActual:\n";
    +    OtherDT.print(errs());
    +    abort();
    +  }
     }
     
     void DominatorTree::print(raw_ostream &OS, const Module *) const {
    
    
    
    From sabre at nondot.org  Sat Jan  8 13:59:06 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 19:59:06 -0000
    Subject: [llvm-commits] [llvm] r123079 - in /llvm/trunk:
     lib/Transforms/Scalar/LoopRotation.cpp
     test/Transforms/LoopRotate/phi-duplicate.ll
    Message-ID: <20110108195906.5789F2A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 13:59:06 2011
    New Revision: 123079
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123079&view=rev
    Log:
    When loop rotation happens, it is *very* common for the duplicated condbr
    to be foldable into an uncond branch.  When this happens, we can make a
    much simpler CFG for the loop, which is important for nested loop cases
    where we want the outer loop to be aggressively optimized.
    
    Handle this case more aggressively.  For example, previously on
    phi-duplicate.ll we would get this:
    
    
    define void @test(i32 %N, double* %G) nounwind ssp {
    entry:
      %cmp1 = icmp slt i64 1, 1000
      br i1 %cmp1, label %bb.nph, label %for.end
    
    bb.nph:                                           ; preds = %entry
      br label %for.body
    
    for.body:                                         ; preds = %bb.nph, %for.cond
      %j.02 = phi i64 [ 1, %bb.nph ], [ %inc, %for.cond ]
      %arrayidx = getelementptr inbounds double* %G, i64 %j.02
      %tmp3 = load double* %arrayidx
      %sub = sub i64 %j.02, 1
      %arrayidx6 = getelementptr inbounds double* %G, i64 %sub
      %tmp7 = load double* %arrayidx6
      %add = fadd double %tmp3, %tmp7
      %arrayidx10 = getelementptr inbounds double* %G, i64 %j.02
      store double %add, double* %arrayidx10
      %inc = add nsw i64 %j.02, 1
      br label %for.cond
    
    for.cond:                                         ; preds = %for.body
      %cmp = icmp slt i64 %inc, 1000
      br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
    
    for.cond.for.end_crit_edge:                       ; preds = %for.cond
      br label %for.end
    
    for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry
      ret void
    }
    
    Now we get the much nicer:
    
    define void @test(i32 %N, double* %G) nounwind ssp {
    entry:
      br label %for.body
    
    for.body:                                         ; preds = %entry, %for.body
      %j.01 = phi i64 [ 1, %entry ], [ %inc, %for.body ]
      %arrayidx = getelementptr inbounds double* %G, i64 %j.01
      %tmp3 = load double* %arrayidx
      %sub = sub i64 %j.01, 1
      %arrayidx6 = getelementptr inbounds double* %G, i64 %sub
      %tmp7 = load double* %arrayidx6
      %add = fadd double %tmp3, %tmp7
      %arrayidx10 = getelementptr inbounds double* %G, i64 %j.01
      store double %add, double* %arrayidx10
      %inc = add nsw i64 %j.01, 1
      %cmp = icmp slt i64 %inc, 1000
      br i1 %cmp, label %for.body, label %for.end
    
    for.end:                                          ; preds = %for.body
      ret void
    }
    
    With all of these recent changes, we are now able to compile:
    
    void foo(char *X) {
     for (int i = 0; i != 100; ++i) 
       for (int j = 0; j != 100; ++j)
         X[j+i*100] = 0;
    }
    
    into a single memset of 10000 bytes.  This series of changes
    should also be helpful for other nested loop scenarios as well.
    
    
    Modified:
        llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
        llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll
    
    Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=123079&r1=123078&r2=123079&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
    +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Sat Jan  8 13:59:06 2011
    @@ -282,30 +282,57 @@
       L->moveToHeader(NewHeader);
       assert(L->getHeader() == NewHeader && "Latch block is our new header");
     
    -  // Update DominatorTree to reflect the CFG change we just made.  Then split
    -  // edges as necessary to preserve LoopSimplify form.
    -  if (DominatorTree *DT = getAnalysisIfAvailable()) {
    -    // Since OrigPreheader now has the conditional branch to Exit block, it is
    -    // the dominator of Exit.
    -    DT->changeImmediateDominator(Exit, OrigPreheader);
    -    DT->changeImmediateDominator(NewHeader, OrigPreheader);
    +  
    +  // At this point, we've finished our major CFG changes.  As part of cloning
    +  // the loop into the preheader we've simplified instructions and the
    +  // duplicated conditional branch may now be branching on a constant.  If it is
    +  // branching on a constant and if that constant means that we enter the loop,
    +  // then we fold away the cond branch to an uncond branch.  This simplifies the
    +  // loop in cases important for nested loops, and it also means we don't have
    +  // to split as many edges.
    +  BranchInst *PHBI = cast(OrigPreheader->getTerminator());
    +  assert(PHBI->isConditional() && "Should be clone of BI condbr!");
    +  if (!isa(PHBI->getCondition()) ||
    +      PHBI->getSuccessor(cast(PHBI->getCondition())->isZero())
    +          != NewHeader) {
    +    // The conditional branch can't be folded, handle the general case.
    +    // Update DominatorTree to reflect the CFG change we just made.  Then split
    +    // edges as necessary to preserve LoopSimplify form.
    +    if (DominatorTree *DT = getAnalysisIfAvailable()) {
    +      // Since OrigPreheader now has the conditional branch to Exit block, it is
    +      // the dominator of Exit.
    +      DT->changeImmediateDominator(Exit, OrigPreheader);
    +      DT->changeImmediateDominator(NewHeader, OrigPreheader);
    +      
    +      // Update OrigHeader to be dominated by the new header block.
    +      DT->changeImmediateDominator(OrigHeader, OrigLatch);
    +    }
    +    
    +    // Right now OrigPreHeader has two successors, NewHeader and ExitBlock, and
    +    // thus is not a preheader anymore.  Split the edge to form a real preheader.
    +    BasicBlock *NewPH = SplitCriticalEdge(OrigPreheader, NewHeader, this);
    +    NewPH->setName(NewHeader->getName() + ".lr.ph");
    +    
    +    // Preserve canonical loop form, which means that 'Exit' should have only one
    +    // predecessor.
    +    BasicBlock *ExitSplit = SplitCriticalEdge(L->getLoopLatch(), Exit, this);
    +    ExitSplit->moveBefore(Exit);
    +  } else {
    +    // We can fold the conditional branch in the preheader, this makes things
    +    // simpler. The first step is to remove the extra edge to the Exit block.
    +    Exit->removePredecessor(OrigPreheader, true /*preserve LCSSA*/);
    +    BranchInst::Create(NewHeader, PHBI);
    +    PHBI->eraseFromParent();
         
    -    // Update OrigHeader to be dominated by the new header block.
    -    DT->changeImmediateDominator(OrigHeader, OrigLatch);
    +    // With our CFG finalized, update DomTree if it is available.
    +    if (DominatorTree *DT = getAnalysisIfAvailable()) {
    +      // Update OrigHeader to be dominated by the new header block.
    +      DT->changeImmediateDominator(NewHeader, OrigPreheader);
    +      DT->changeImmediateDominator(OrigHeader, OrigLatch);
    +    }
       }
       
    -  // Right now OrigPreHeader has two successors, NewHeader and ExitBlock, and
    -  // thus is not a preheader anymore.  Split the edge to form a real preheader.
    -  BasicBlock *NewPH = SplitCriticalEdge(OrigPreheader, NewHeader, this);
    -  NewPH->setName(NewHeader->getName() + ".lr.ph");
    -  
    -  // Preserve canonical loop form, which means that 'Exit' should have only one
    -  // predecessor.
    -  BasicBlock *ExitSplit = SplitCriticalEdge(L->getLoopLatch(), Exit, this);
    -  ExitSplit->moveBefore(Exit);
    -  
    -  assert(L->getLoopPreheader() == NewPH &&
    -         "Invalid loop preheader after loop rotation");
    +  assert(L->getLoopPreheader() && "Invalid loop preheader after loop rotation");
       assert(L->getLoopLatch() && "Invalid loop latch after loop rotation");
     
       // Now that the CFG and DomTree are in a consistent state again, merge the
    
    Modified: llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll?rev=123079&r1=123078&r2=123079&view=diff
    ==============================================================================
    --- llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll (original)
    +++ llvm/trunk/test/Transforms/LoopRotate/phi-duplicate.ll Sat Jan  8 13:59:06 2011
    @@ -28,19 +28,13 @@
       ret void
     }
     
    -; Should only end up with one phi. Also, the original for.cond block should
    -; be moved to the end of the loop so that the new loop header pleasantly
    -; ends up at the top.
    -
    +; Should only end up with one phi.
     ; CHECK:      define void @test
     ; CHECK-NEXT: entry:
    -; CHECK-NEXT:   br i1 true, label %for.body.lr.ph, label %for.end
    -; CHECK-NOT:  :
    -; CHECK:      for.body.lr.ph:
     ; CHECK-NEXT:   br label %for.body
    -; CHECK-NOT:  :
     ; CHECK:      for.body:
     ; CHECK-NEXT:   %j.01 = phi i64
    -; CHECK-NOT:    phi
    -; CHECK:        ret void
    -; CHECK-NEXT: }
    +; CHECK-NOT:  br
    +; CHECK:   br i1 %cmp, label %for.body, label %for.end
    +; CHECK:      for.end:
    +; CHECK-NEXT:        ret void
    
    
    
    From sabre at nondot.org  Sat Jan  8 14:24:02 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 20:24:02 -0000
    Subject: [llvm-commits] [llvm] r123081 -
    	/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
    Message-ID: <20110108202402.0B9662A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 14:24:01 2011
    New Revision: 123081
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123081&view=rev
    Log:
    constify TargetData references.
    Split memset formation logic out into its own
    "tryMergingIntoMemset" helper function.
    
    Modified:
        llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
    
    Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=123081&r1=123080&r2=123081&view=diff
    ==============================================================================
    --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original)
    +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Sat Jan  8 14:24:01 2011
    @@ -37,7 +37,7 @@
     STATISTIC(NumCpyToSet,    "Number of memcpys converted to memset");
     
     static int64_t GetOffsetFromIndex(const GetElementPtrInst *GEP, unsigned Idx,
    -                                  bool &VariableIdxFound, TargetData &TD) {
    +                                  bool &VariableIdxFound, const TargetData &TD){
       // Skip over the first indices.
       gep_type_iterator GTI = gep_type_begin(GEP);
       for (unsigned i = 1; i != Idx; ++i, ++GTI)
    @@ -70,7 +70,7 @@
     /// constant offset, and return that constant offset.  For example, Ptr1 might
     /// be &A[42], and Ptr2 might be &A[40].  In this case offset would be -8.
     static bool IsPointerOffset(Value *Ptr1, Value *Ptr2, int64_t &Offset,
    -                            TargetData &TD) {
    +                            const TargetData &TD) {
       // Right now we handle the case when Ptr1/Ptr2 are both GEPs with an identical
       // base.  After that base, they may have some number of common (and
       // potentially variable) indices.  After that they handle some constant
    @@ -165,9 +165,9 @@
       /// because each element is relatively large and expensive to copy.
       std::list Ranges;
       typedef std::list::iterator range_iterator;
    -  TargetData &TD;
    +  const TargetData &TD;
     public:
    -  MemsetRanges(TargetData &td) : TD(td) {}
    +  MemsetRanges(const TargetData &td) : TD(td) {}
       
       typedef std::list::const_iterator const_iterator;
       const_iterator begin() const { return Ranges.begin(); }
    @@ -175,6 +175,10 @@
       bool empty() const { return Ranges.empty(); }
       
       void addStore(int64_t OffsetFromFirst, StoreInst *SI);
    +  
    +  void addInst(int64_t OffsetFromFirst, Instruction *Inst) {
    +    addStore(OffsetFromFirst, cast(Inst));
    +  }
     };
       
     } // end anon namespace
    @@ -252,7 +256,7 @@
     namespace {
       class MemCpyOpt : public FunctionPass {
         MemoryDependenceAnalysis *MD;
    -    bool runOnFunction(Function &F);
    +    const TargetData *TD;
       public:
         static char ID; // Pass identification, replacement for typeid
         MemCpyOpt() : FunctionPass(ID) {
    @@ -260,6 +264,8 @@
           MD = 0;
         }
     
    +    bool runOnFunction(Function &F);
    +
       private:
         // This transformation requires dominator postdominator info
         virtual void getAnalysisUsage(AnalysisUsage &AU) const {
    @@ -280,6 +286,9 @@
         bool processMemCpyMemCpyDependence(MemCpyInst *M, MemCpyInst *MDep,
                                            uint64_t MSize);
         bool processByValArgument(CallSite CS, unsigned ArgNo);
    +    Instruction *tryMergingIntoMemset(Instruction *I, Value *StartPtr,
    +                                      Value *ByteVal);
    +
         bool iterateOnFunction(Function &F);
       };
       
    @@ -297,70 +306,30 @@
     INITIALIZE_PASS_END(MemCpyOpt, "memcpyopt", "MemCpy Optimization",
                         false, false)
     
    -/// processStore - When GVN is scanning forward over instructions, we look for
    +/// tryMergingIntoMemset - When scanning forward over instructions, we look for
     /// some other patterns to fold away.  In particular, this looks for stores to
    -/// neighboring locations of memory.  If it sees enough consequtive ones
    -/// (currently 4) it attempts to merge them together into a memcpy/memset.
    -bool MemCpyOpt::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
    -  if (SI->isVolatile()) return false;
    -  
    -  TargetData *TD = getAnalysisIfAvailable();
    -  if (!TD) return false;
    -
    -  // Detect cases where we're performing call slot forwarding, but
    -  // happen to be using a load-store pair to implement it, rather than
    -  // a memcpy.
    -  if (LoadInst *LI = dyn_cast(SI->getOperand(0))) {
    -    if (!LI->isVolatile() && LI->hasOneUse()) {
    -      MemDepResult dep = MD->getDependency(LI);
    -      CallInst *C = 0;
    -      if (dep.isClobber() && !isa(dep.getInst()))
    -        C = dyn_cast(dep.getInst());
    -      
    -      if (C) {
    -        bool changed = performCallSlotOptzn(LI,
    -                        SI->getPointerOperand()->stripPointerCasts(), 
    -                        LI->getPointerOperand()->stripPointerCasts(),
    -                        TD->getTypeStoreSize(SI->getOperand(0)->getType()), C);
    -        if (changed) {
    -          MD->removeInstruction(SI);
    -          SI->eraseFromParent();
    -          LI->eraseFromParent();
    -          ++NumMemCpyInstr;
    -          return true;
    -        }
    -      }
    -    }
    -  }
    +/// neighboring locations of memory.  If it sees enough consequtive ones, it
    +/// attempts to merge them together into a memcpy/memset.
    +Instruction *MemCpyOpt::tryMergingIntoMemset(Instruction *StartInst, 
    +                                             Value *StartPtr, Value *ByteVal) {
    +  if (TD == 0) return 0;
       
    -  // There are two cases that are interesting for this code to handle: memcpy
    -  // and memset.  Right now we only handle memset.
    -  
    -  // Ensure that the value being stored is something that can be memset'able a
    -  // byte at a time like "0" or "-1" or any width, as well as things like
    -  // 0xA0A0A0A0 and 0.0.
    -  Value *ByteVal = isBytewiseValue(SI->getOperand(0));
    -  if (!ByteVal)
    -    return false;
    -
       AliasAnalysis &AA = getAnalysis();
    -
    +  
       // Okay, so we now have a single store that can be splatable.  Scan to find
       // all subsequent stores of the same value to offset from the same pointer.
       // Join these together into ranges, so we can decide whether contiguous blocks
       // are stored.
       MemsetRanges Ranges(*TD);
       
    -  Value *StartPtr = SI->getPointerOperand();
    -  
    -  BasicBlock::iterator BI = SI;
    +  BasicBlock::iterator BI = StartInst;
       for (++BI; !isa(BI); ++BI) {
         if (isa(BI) || isa(BI)) { 
           // If the call is readnone, ignore it, otherwise bail out.  We don't even
           // allow readonly here because we don't want something like:
           // A[1] = 2; strlen(A); A[2] = 2; -> memcpy(A, ...); strlen(A).
           if (AA.getModRefBehavior(CallSite(BI)) ==
    -            AliasAnalysis::DoesNotAccessMemory)
    +          AliasAnalysis::DoesNotAccessMemory)
             continue;
           
           // TODO: If this is a memset, try to join it in.
    @@ -368,7 +337,7 @@
           break;
         } else if (isa(BI) || isa(BI))
           break;
    -
    +    
         // If this is a non-store instruction it is fine, ignore it.
         StoreInst *NextStore = dyn_cast(BI);
         if (NextStore == 0) continue;
    @@ -379,78 +348,120 @@
         // Check to see if this stored value is of the same byte-splattable value.
         if (ByteVal != isBytewiseValue(NextStore->getOperand(0)))
           break;
    -
    +    
         // Check to see if this store is to a constant offset from the start ptr.
         int64_t Offset;
         if (!IsPointerOffset(StartPtr, NextStore->getPointerOperand(), Offset, *TD))
           break;
    -
    +    
         Ranges.addStore(Offset, NextStore);
       }
    -
    +  
       // If we have no ranges, then we just had a single store with nothing that
       // could be merged in.  This is a very common case of course.
       if (Ranges.empty())
    -    return false;
    +    return 0;
       
       // If we had at least one store that could be merged in, add the starting
       // store as well.  We try to avoid this unless there is at least something
       // interesting as a small compile-time optimization.
    -  Ranges.addStore(0, SI);
    -  
    -  
    +  Ranges.addInst(0, StartInst);
    +
    +  // If we create any memsets, we put it right before the first instruction that
    +  // isn't part of the memset block.  This ensure that the memset is dominated
    +  // by any addressing instruction needed by the start of the block.
    +  IRBuilder<> Builder(BI);
    +
       // Now that we have full information about ranges, loop over the ranges and
       // emit memset's for anything big enough to be worthwhile.
    -  bool MadeChange = false;
    +  Instruction *AMemSet = 0;
       for (MemsetRanges::const_iterator I = Ranges.begin(), E = Ranges.end();
            I != E; ++I) {
         const MemsetRange &Range = *I;
    -
    +    
         if (Range.TheStores.size() == 1) continue;
         
         // If it is profitable to lower this range to memset, do so now.
         if (!Range.isProfitableToUseMemset(*TD))
           continue;
         
    -    // Otherwise, we do want to transform this!  Create a new memset.  We put
    -    // the memset right before the first instruction that isn't part of this
    -    // memset block.  This ensure that the memset is dominated by any addressing
    -    // instruction needed by the start of the block.
    -    BasicBlock::iterator InsertPt = BI;
    -
    +    // Otherwise, we do want to transform this!  Create a new memset.
         // Get the starting pointer of the block.
         StartPtr = Range.StartPtr;
    -
    +    
         // Determine alignment
         unsigned Alignment = Range.Alignment;
         if (Alignment == 0) {
           const Type *EltType = 
    -         cast(StartPtr->getType())->getElementType();
    +        cast(StartPtr->getType())->getElementType();
           Alignment = TD->getABITypeAlignment(EltType);
         }
    -
    -    IRBuilder<> Builder(InsertPt);
    -    Value *C = 
    +    
    +    AMemSet = 
           Builder.CreateMemSet(StartPtr, ByteVal, Range.End-Range.Start, Alignment);
         
         DEBUG(dbgs() << "Replace stores:\n";
               for (unsigned i = 0, e = Range.TheStores.size(); i != e; ++i)
                 dbgs() << *Range.TheStores[i] << '\n';
    -          dbgs() << "With: " << *C << '\n'); (void)C;
    -  
    -    // Don't invalidate the iterator
    -    BBI = BI;
    -  
    +          dbgs() << "With: " << *AMemSet << '\n');
    +    
         // Zap all the stores.
         for (SmallVector::const_iterator
              SI = Range.TheStores.begin(),
              SE = Range.TheStores.end(); SI != SE; ++SI)
           (*SI)->eraseFromParent();
         ++NumMemSetInfer;
    -    MadeChange = true;
       }
       
    -  return MadeChange;
    +  return AMemSet;
    +}
    +
    +
    +bool MemCpyOpt::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
    +  if (SI->isVolatile()) return false;
    +  
    +  if (TD == 0) return false;
    +
    +  // Detect cases where we're performing call slot forwarding, but
    +  // happen to be using a load-store pair to implement it, rather than
    +  // a memcpy.
    +  if (LoadInst *LI = dyn_cast(SI->getOperand(0))) {
    +    if (!LI->isVolatile() && LI->hasOneUse()) {
    +      MemDepResult dep = MD->getDependency(LI);
    +      CallInst *C = 0;
    +      if (dep.isClobber() && !isa(dep.getInst()))
    +        C = dyn_cast(dep.getInst());
    +      
    +      if (C) {
    +        bool changed = performCallSlotOptzn(LI,
    +                        SI->getPointerOperand()->stripPointerCasts(), 
    +                        LI->getPointerOperand()->stripPointerCasts(),
    +                        TD->getTypeStoreSize(SI->getOperand(0)->getType()), C);
    +        if (changed) {
    +          MD->removeInstruction(SI);
    +          SI->eraseFromParent();
    +          LI->eraseFromParent();
    +          ++NumMemCpyInstr;
    +          return true;
    +        }
    +      }
    +    }
    +  }
    +  
    +  // There are two cases that are interesting for this code to handle: memcpy
    +  // and memset.  Right now we only handle memset.
    +  
    +  // Ensure that the value being stored is something that can be memset'able a
    +  // byte at a time like "0" or "-1" or any width, as well as things like
    +  // 0xA0A0A0A0 and 0.0.
    +  if (Value *ByteVal = isBytewiseValue(SI->getOperand(0)))
    +    if (Instruction *I = tryMergingIntoMemset(SI, SI->getPointerOperand(),
    +                                              ByteVal)) {
    +      BBI = I;  // Don't invalidate iterator.
    +      return true;
    +    }
    +  
    +  return false;
     }
     
     
    @@ -484,8 +495,7 @@
         return false;
     
       // Check that all of src is copied to dest.
    -  TargetData *TD = getAnalysisIfAvailable();
    -  if (!TD) return false;
    +  if (TD == 0) return false;
     
       ConstantInt *srcArraySize = dyn_cast(srcAlloca->getArraySize());
       if (!srcArraySize)
    @@ -751,8 +761,7 @@
       
     /// processByValArgument - This is called on every byval argument in call sites.
     bool MemCpyOpt::processByValArgument(CallSite CS, unsigned ArgNo) {
    -  TargetData *TD = getAnalysisIfAvailable();
    -  if (!TD) return false;
    +  if (TD == 0) return false;
     
       // Find out what feeds this byval argument.
       Value *ByValArg = CS.getArgument(ArgNo);
    @@ -856,6 +865,7 @@
     bool MemCpyOpt::runOnFunction(Function &F) {
       bool MadeChange = false;
       MD = &getAnalysis();
    +  TD = getAnalysisIfAvailable();
       while (1) {
         if (!iterateOnFunction(F))
           break;
    
    
    
    From sabre at nondot.org  Sat Jan  8 14:27:23 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 20:27:23 -0000
    Subject: [llvm-commits] [llvm] r123082 - in
     /llvm/trunk/test/Transforms/MemCpyOpt: form-memset.ll form-memset2.ll
    Message-ID: <20110108202723.2944C2A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 14:27:22 2011
    New Revision: 123082
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123082&view=rev
    Log:
    merge two tests and filecheckify
    
    Removed:
        llvm/trunk/test/Transforms/MemCpyOpt/form-memset2.ll
    Modified:
        llvm/trunk/test/Transforms/MemCpyOpt/form-memset.ll
    
    Modified: llvm/trunk/test/Transforms/MemCpyOpt/form-memset.ll
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MemCpyOpt/form-memset.ll?rev=123082&r1=123081&r2=123082&view=diff
    ==============================================================================
    --- llvm/trunk/test/Transforms/MemCpyOpt/form-memset.ll (original)
    +++ llvm/trunk/test/Transforms/MemCpyOpt/form-memset.ll Sat Jan  8 14:27:22 2011
    @@ -1,12 +1,11 @@
    -; RUN: opt < %s -memcpyopt -S | not grep store
    -; RUN: opt < %s -memcpyopt -S | grep {call.*llvm.memset}
    +; RUN: opt < %s -memcpyopt -S | FileCheck %s
     
     ; All the stores in this example should be merged into a single memset.
     
     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-darwin8"
     
    -define void @foo(i8 signext  %c) nounwind  {
    +define void @test1(i8 signext  %c) nounwind  {
     entry:
     	%x = alloca [19 x i8]		; <[19 x i8]*> [#uses=20]
     	%tmp = getelementptr [19 x i8]* %x, i32 0, i32 0		;  [#uses=1]
    @@ -47,9 +46,119 @@
     	store i8 %c, i8* %tmp69, align 1
     	%tmp73 = getelementptr [19 x i8]* %x, i32 0, i32 18		;  [#uses=1]
     	store i8 %c, i8* %tmp73, align 1
    -	%tmp76 = call i32 (...)* @bar( [19 x i8]* %x ) nounwind 		;  [#uses=0]
    +	%tmp76 = call i32 (...)* @bar( [19 x i8]* %x ) nounwind
     	ret void
    +; CHECK: @test1
    +; CHECK-NOT: store
    +; CHECK: call void @llvm.memset.p0i8.i64
    +; CHECK-NOT: store
    +; CHECK: ret
     }
     
     declare i32 @bar(...)
     
    +
    +	%struct.MV = type { i16, i16 }
    +
    +define void @test2() nounwind  {
    +entry:
    +	%ref_idx = alloca [8 x i8]		; <[8 x i8]*> [#uses=8]
    +	%left_mvd = alloca [8 x %struct.MV]		; <[8 x %struct.MV]*> [#uses=17]
    +	%up_mvd = alloca [8 x %struct.MV]		; <[8 x %struct.MV]*> [#uses=17]
    +	%tmp20 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 7		;  [#uses=1]
    +	store i8 -1, i8* %tmp20, align 1
    +	%tmp23 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 6		;  [#uses=1]
    +	store i8 -1, i8* %tmp23, align 1
    +	%tmp26 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 5		;  [#uses=1]
    +	store i8 -1, i8* %tmp26, align 1
    +	%tmp29 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 4		;  [#uses=1]
    +	store i8 -1, i8* %tmp29, align 1
    +	%tmp32 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 3		;  [#uses=1]
    +	store i8 -1, i8* %tmp32, align 1
    +	%tmp35 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 2		;  [#uses=1]
    +	store i8 -1, i8* %tmp35, align 1
    +	%tmp38 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 1		;  [#uses=1]
    +	store i8 -1, i8* %tmp38, align 1
    +	%tmp41 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 0		;  [#uses=2]
    +	store i8 -1, i8* %tmp41, align 1
    +	%tmp43 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 7, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp43, align 2
    +	%tmp46 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 7, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp46, align 2
    +	%tmp57 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 6, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp57, align 2
    +	%tmp60 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 6, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp60, align 2
    +	%tmp71 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 5, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp71, align 2
    +	%tmp74 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 5, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp74, align 2
    +	%tmp85 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 4, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp85, align 2
    +	%tmp88 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 4, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp88, align 2
    +	%tmp99 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 3, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp99, align 2
    +	%tmp102 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 3, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp102, align 2
    +	%tmp113 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 2, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp113, align 2
    +	%tmp116 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 2, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp116, align 2
    +	%tmp127 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 1, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp127, align 2
    +	%tmp130 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 1, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp130, align 2
    +	%tmp141 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 0, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp141, align 8
    +	%tmp144 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 0, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp144, align 2
    +	%tmp148 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 7, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp148, align 2
    +	%tmp151 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 7, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp151, align 2
    +	%tmp162 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 6, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp162, align 2
    +	%tmp165 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 6, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp165, align 2
    +	%tmp176 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 5, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp176, align 2
    +	%tmp179 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 5, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp179, align 2
    +	%tmp190 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 4, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp190, align 2
    +	%tmp193 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 4, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp193, align 2
    +	%tmp204 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 3, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp204, align 2
    +	%tmp207 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 3, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp207, align 2
    +	%tmp218 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 2, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp218, align 2
    +	%tmp221 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 2, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp221, align 2
    +	%tmp232 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 1, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp232, align 2
    +	%tmp235 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 1, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp235, align 2
    +	%tmp246 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 0, i32 0		;  [#uses=1]
    +	store i16 0, i16* %tmp246, align 8
    +	%tmp249 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 0, i32 1		;  [#uses=1]
    +	store i16 0, i16* %tmp249, align 2
    +	%up_mvd252 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 0		; <%struct.MV*> [#uses=1]
    +	%left_mvd253 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 0		; <%struct.MV*> [#uses=1]
    +	call void @foo( %struct.MV* %up_mvd252, %struct.MV* %left_mvd253, i8* %tmp41 ) nounwind 
    +	ret void
    +        
    +; CHECK: @test2
    +; CHECK-NOT: store
    +; CHECK: call void @llvm.memset.p0i8.i64(i8* %tmp41, i8 -1, i64 8, i32 1, i1 false)
    +; CHECK-NOT: store
    +; CHECK: call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 32, i32 8, i1 false)
    +; CHECK-NOT: store
    +; CHECK: call void @llvm.memset.p0i8.i64(i8* %1, i8 0, i64 32, i32 8, i1 false)
    +; CHECK-NOT: store
    +; CHECK: ret
    +}
    +
    +declare void @foo(%struct.MV*, %struct.MV*, i8*)
    
    Removed: llvm/trunk/test/Transforms/MemCpyOpt/form-memset2.ll
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MemCpyOpt/form-memset2.ll?rev=123081&view=auto
    ==============================================================================
    --- llvm/trunk/test/Transforms/MemCpyOpt/form-memset2.ll (original)
    +++ llvm/trunk/test/Transforms/MemCpyOpt/form-memset2.ll (removed)
    @@ -1,99 +0,0 @@
    -; RUN: opt < %s -memcpyopt -S | not grep store
    -; RUN: opt < %s -memcpyopt -S | grep {call.*llvm.memset} | count 3
    -
    -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-darwin8"
    -	%struct.MV = type { i16, i16 }
    -
    -define i32 @t() nounwind  {
    -entry:
    -	%ref_idx = alloca [8 x i8]		; <[8 x i8]*> [#uses=8]
    -	%left_mvd = alloca [8 x %struct.MV]		; <[8 x %struct.MV]*> [#uses=17]
    -	%up_mvd = alloca [8 x %struct.MV]		; <[8 x %struct.MV]*> [#uses=17]
    -	%tmp20 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 7		;  [#uses=1]
    -	store i8 -1, i8* %tmp20, align 1
    -	%tmp23 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 6		;  [#uses=1]
    -	store i8 -1, i8* %tmp23, align 1
    -	%tmp26 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 5		;  [#uses=1]
    -	store i8 -1, i8* %tmp26, align 1
    -	%tmp29 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 4		;  [#uses=1]
    -	store i8 -1, i8* %tmp29, align 1
    -	%tmp32 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 3		;  [#uses=1]
    -	store i8 -1, i8* %tmp32, align 1
    -	%tmp35 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 2		;  [#uses=1]
    -	store i8 -1, i8* %tmp35, align 1
    -	%tmp38 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 1		;  [#uses=1]
    -	store i8 -1, i8* %tmp38, align 1
    -	%tmp41 = getelementptr [8 x i8]* %ref_idx, i32 0, i32 0		;  [#uses=2]
    -	store i8 -1, i8* %tmp41, align 1
    -	%tmp43 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 7, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp43, align 2
    -	%tmp46 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 7, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp46, align 2
    -	%tmp57 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 6, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp57, align 2
    -	%tmp60 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 6, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp60, align 2
    -	%tmp71 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 5, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp71, align 2
    -	%tmp74 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 5, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp74, align 2
    -	%tmp85 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 4, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp85, align 2
    -	%tmp88 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 4, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp88, align 2
    -	%tmp99 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 3, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp99, align 2
    -	%tmp102 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 3, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp102, align 2
    -	%tmp113 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 2, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp113, align 2
    -	%tmp116 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 2, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp116, align 2
    -	%tmp127 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 1, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp127, align 2
    -	%tmp130 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 1, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp130, align 2
    -	%tmp141 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 0, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp141, align 8
    -	%tmp144 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 0, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp144, align 2
    -	%tmp148 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 7, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp148, align 2
    -	%tmp151 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 7, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp151, align 2
    -	%tmp162 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 6, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp162, align 2
    -	%tmp165 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 6, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp165, align 2
    -	%tmp176 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 5, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp176, align 2
    -	%tmp179 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 5, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp179, align 2
    -	%tmp190 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 4, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp190, align 2
    -	%tmp193 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 4, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp193, align 2
    -	%tmp204 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 3, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp204, align 2
    -	%tmp207 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 3, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp207, align 2
    -	%tmp218 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 2, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp218, align 2
    -	%tmp221 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 2, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp221, align 2
    -	%tmp232 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 1, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp232, align 2
    -	%tmp235 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 1, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp235, align 2
    -	%tmp246 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 0, i32 0		;  [#uses=1]
    -	store i16 0, i16* %tmp246, align 8
    -	%tmp249 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 0, i32 1		;  [#uses=1]
    -	store i16 0, i16* %tmp249, align 2
    -	%up_mvd252 = getelementptr [8 x %struct.MV]* %up_mvd, i32 0, i32 0		; <%struct.MV*> [#uses=1]
    -	%left_mvd253 = getelementptr [8 x %struct.MV]* %left_mvd, i32 0, i32 0		; <%struct.MV*> [#uses=1]
    -	call void @foo( %struct.MV* %up_mvd252, %struct.MV* %left_mvd253, i8* %tmp41 ) nounwind 
    -	ret i32 undef
    -}
    -
    -declare void @foo(%struct.MV*, %struct.MV*, i8*)
    
    
    
    From sabre at nondot.org  Sat Jan  8 14:53:41 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 20:53:41 -0000
    Subject: [llvm-commits] [llvm] r123085 -
    	/llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
    Message-ID: <20110108205341.B593B2A6C12C@llvm.org>
    
    Author: lattner
    Date: Sat Jan  8 14:53:41 2011
    New Revision: 123085
    
    URL: http://llvm.org/viewvc/llvm-project?rev=123085&view=rev
    Log:
    fit in 80 cols
    
    Modified:
        llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
    
    Modified: llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasAnalysis.h?rev=123085&r1=123084&r2=123085&view=diff
    ==============================================================================
    --- llvm/trunk/include/llvm/Analysis/AliasAnalysis.h (original)
    +++ llvm/trunk/include/llvm/Analysis/AliasAnalysis.h Sat Jan  8 14:53:41 2011
    @@ -402,7 +402,7 @@
       ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc);
     
       /// getModRefInfo (for stores) - A convenience wrapper.
    -  ModRefResult getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size) {
    +  ModRefResult getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size){
         return getModRefInfo(S, Location(P, Size));
       }
     
    @@ -411,7 +411,7 @@
       ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc);
     
       /// getModRefInfo (for va_args) - A convenience wrapper.
    -  ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t Size) {
    +  ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t Size){
         return getModRefInfo(I, Location(P, Size));
       }
     
    
    
    
    From sabre at nondot.org  Sat Jan  8 14:54:51 2011
    From: sabre at nondot.org (Chris Lattner)
    Date: Sat, 08 Jan 2011 20:54:51 -0000
    Subject: [llvm-commits] [llvm] r123086 - in /llvm/trunk:
     lib/Transforms/Scalar/MemCpyOptimizer.cpp
     test/Transforms/MemCpyOpt/form-memset.ll
    Message-ID: <20110108205451.7D2222A6C12C@llvm.o