From lattner at cs.uiuc.edu Mon Nov 8 00:18:17 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 Nov 2004 00:18:17 -0600 Subject: [llvm-commits] CVS: poolalloc/lib/PoolAllocate/Heuristic.cpp Heuristic.h PoolAllocate.cpp PoolAllocate.h Message-ID: <200411080618.iA86IHq4018989@apoc.cs.uiuc.edu> Changes in directory poolalloc/lib/PoolAllocate: Heuristic.cpp added (r1.1) Heuristic.h added (r1.1) PoolAllocate.cpp updated: 1.86 -> 1.87 PoolAllocate.h updated: 1.28 -> 1.29 --- Log message: Introduce a new *formal* interface between the pool allocator and the various heuristics it supports. This gives us a uniform way to handle the global pools and function local pools, and makes it easy to implement coallescing heuristics. This also removes most of the special purpose hacks for the various heuristics spread throughout the pool allocator. The pool allocator now looks like this: $ wc *.cpp *.h 439 1904 17119 EquivClassGraphs.cpp 398 1728 15760 Heuristic.cpp 817 3389 32438 PoolAllocate.cpp 529 2092 20645 TransformFunctionBody.cpp 106 447 3785 EquivClassGraphs.h 93 376 3010 Heuristic.h 206 936 7455 PoolAllocate.h 2588 10872 100212 total --- Diffs of the changes: (+572 -332) Index: poolalloc/lib/PoolAllocate/Heuristic.cpp diff -c /dev/null poolalloc/lib/PoolAllocate/Heuristic.cpp:1.1 *** /dev/null Mon Nov 8 00:18:17 2004 --- poolalloc/lib/PoolAllocate/Heuristic.cpp Mon Nov 8 00:18:07 2004 *************** *** 0 **** --- 1,398 ---- + //===-- 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. + // + //===----------------------------------------------------------------------===// + + #include "Heuristic.h" + #include "PoolAllocate.h" + #include "llvm/Instructions.h" + #include "llvm/Module.h" + #include "llvm/Analysis/DataStructure/DSGraphTraits.h" + #include "llvm/ADT/DepthFirstIterator.h" + #include "llvm/Support/CommandLine.h" + #include "llvm/Target/TargetData.h" + using namespace llvm; + using namespace PA; + + namespace { + enum PoolAllocHeuristic { + NoNodes, + OnlyOverhead, + AllInOneGlobalPool, + SmartCoallesceNodes, + CyclicNodes, + AllButUnreachableFromMemory, + AllNodes, + }; + cl::opt + TheHeuristic("poolalloc-heuristic", + cl::desc("Heuristic to choose which nodes to pool allocate"), + cl::values(clEnumVal(AllNodes, " Pool allocate all nodes"), + clEnumVal(AllButUnreachableFromMemory, " Pool allocate all reachable from memory objects"), + clEnumVal(CyclicNodes, " Pool allocate nodes with cycles"), + clEnumVal(SmartCoallesceNodes, " Use the smart node merging heuristic"), + clEnumVal(AllInOneGlobalPool, " Use pool library as replacement for malloc/free"), + clEnumVal(OnlyOverhead, " Do not pool allocate anything, but induce all overhead from it"), + clEnumVal(NoNodes, " Do not pool allocate anything"), + clEnumValEnd), + cl::init(AllButUnreachableFromMemory)); + } + + Heuristic::~Heuristic() {} + + unsigned Heuristic::getRecommendedSize(DSNode *N) { + unsigned PoolSize = 0; + if (!N->isArray() && N->getType()->isSized()) { + DSGraph *G = N->getParentGraph(); + PoolSize = G->getTargetData().getTypeSize(N->getType()); + } + if (PoolSize == 1) PoolSize = 0; + return PoolSize; + } + + //===-- AllNodes Heuristic ------------------------------------------------===// + // + // This heuristic pool allocates everything possible into separate pools. + // + struct AllNodesHeuristic : public Heuristic { + + void 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 + // the pool is not reachable by other memory objects. This filters out objects + // that are not cyclic and are only pointed to by scalars: these tend to be + // singular memory allocations that are not worth creating a whole pool for. + // + struct AllButUnreachableFromMemoryHeuristic : public Heuristic { + + void AssignToPools(const std::vector &NodesToPA, + Function *F, DSGraph &G, + std::vector &ResultPools) { + // FIXME: implement + for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) + ResultPools.push_back(OnePool(NodesToPA[i])); + } + }; + + //===-- CyclicNodes Heuristic ---------------------------------------------===// + // + // This heuristic only pool allocates nodes in an SCC in the DSGraph. + // + struct CyclicNodesHeuristic : public Heuristic { + + void AssignToPools(const std::vector &NodesToPA, + Function *F, DSGraph &G, + std::vector &ResultPools); + }; + + static bool NodeExistsInCycle(DSNode *N) { + for (DSNode::iterator I = N->begin(), E = N->end(); I != E; ++I) + if (*I && std::find(df_begin(*I), df_end(*I), N) != df_end(*I)) + return true; + return false; + } + + void CyclicNodesHeuristic::AssignToPools(const std::vector &NodesToPA, + Function *F, DSGraph &G, + std::vector &ResultPools) { + for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) + if (NodeExistsInCycle(NodesToPA[i])) + ResultPools.push_back(OnePool(NodesToPA[i])); + } + + + //===-- SmartCoallesceNodes Heuristic -------------------------------------===// + // + // This heuristic attempts to be smart and coallesce nodes at times. In + // practice, it doesn't work very well. + // + struct SmartCoallesceNodesHeuristic : public Heuristic { + + void AssignToPools(const std::vector &NodesToPA, + Function *F, DSGraph &G, + std::vector &ResultPools) { + // For globals, do not pool allocate unless the node is cyclic and not an + // array (unless it's collapsed). + if (F == 0) { + for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) { + DSNode *Node = NodesToPA[i]; + if ((Node->isNodeCompletelyFolded() || !Node->isArray()) && + NodeExistsInCycle(Node)) + ResultPools.push_back(OnePool(Node)); + } + } else { + // TODO + } + } + }; + + #if 0 + // Heuristic for building per-function pools + + switch (Heuristic) { + case SmartCoallesceNodes: { + std::set NodesToPASet(NodesToPA.begin(), NodesToPA.end()); + + // DSGraphs only have unidirectional edges, to traverse or inspect the + // predecessors of nodes, we must build a mapping of the inverse graph. + std::map > InverseGraph; + + for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) { + DSNode *Node = NodesToPA[i]; + for (DSNode::iterator CI = Node->begin(), E = Node->end(); CI != E; ++CI) + if (DSNode *Child = const_cast(*CI)) + if (NodesToPASet.count(Child)) + InverseGraph[Child].push_back(Node); + } + + // Traverse the heap nodes in reverse-post-order so that we are guaranteed + // to visit all nodes pointing to another node before we visit that node + // itself (except with cycles). + + // FIXME: This really should be using the PostOrderIterator.h file stuff, + // but the routines there do not support external storage! + std::set Visited; + std::vector Order; + for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) + POVisit(NodesToPA[i], Visited, Order); + + // We want RPO, not PO, so reverse the order. + std::reverse(Order.begin(), Order.end()); + + // Okay, we have an ordering of the nodes in reverse post order. Traverse + // each node in this ordering, noting that there may be nodes in the order + // that are not in our NodesToPA list. + for (unsigned i = 0, e = Order.size(); i != e; ++i) + if (NodesToPASet.count(Order[i])) { // Only process pa nodes. + DSNode *N = Order[i]; + + // If this node has a backedge to itself, pool allocate it in a new + // pool. + if (NodeIsSelfRecursive(N)) { + // Create a new alloca instruction for the pool... + Value *AI = new AllocaInst(PoolDescType, 0, "PD", InsertPoint); + + // Void types in DS graph are never used + if (N->isNodeCompletelyFolded()) + std::cerr << "Node collapsing in '" << F.getName() << "'\n"; + + // Update the PoolDescriptors map + PoolDescriptors.insert(std::make_pair(N, AI)); + #if 1 + } else if (N->isArray() && !N->isNodeCompletelyFolded()) { + // We never pool allocate array nodes. + PoolDescriptors[N] = + Constant::getNullValue(PointerType::get(PoolDescType)); + ++NumNonprofit; + #endif + } else { + // Otherwise the node is not self recursive. If the node is not an + // array, we can co-locate it with the pool of a predecessor node if + // any has been pool allocated, and start a new pool if a predecessor + // is an array. If there is a predecessor of this node that has not + // been visited yet in this RPO traversal, that means there is a + // cycle, so we choose to pool allocate this node right away. + // + // If there multiple predecessors in multiple different pools, we + // don't pool allocate this at all. + + // Check out each of the predecessors of this node. + std::vector &Preds = InverseGraph[N]; + Value *PredPool = 0; + bool HasUnvisitedPred = false; + bool HasArrayPred = false; + bool HasMultiplePredPools = false; + for (unsigned p = 0, e = Preds.size(); p != e; ++p) { + DSNode *Pred = Preds[p]; + if (!PoolDescriptors.count(Pred)) + HasUnvisitedPred = true; // no pool assigned to predecessor? + else if (Pred->isArray() && !Pred->isNodeCompletelyFolded()) + HasArrayPred = true; + else if (PredPool && PoolDescriptors[Pred] != PredPool) + HasMultiplePredPools = true; + else if (!PredPool && + !isa(PoolDescriptors[Pred])) + PredPool = PoolDescriptors[Pred]; + // Otherwise, this predecessor has the same pool as a previous one. + } + + if (HasMultiplePredPools) { + // If this node has predecessors that are in different pools, don't + // pool allocate this node. + PoolDescriptors[N] = + Constant::getNullValue(PointerType::get(PoolDescType)); + ++NumNonprofit; + } else if (PredPool) { + // If all of the predecessors of this node are already in a pool, + // colocate. + PoolDescriptors[N] = PredPool; + ++NumColocated; + } else if (HasArrayPred || HasUnvisitedPred) { + // If this node has an array predecessor, or if there is a + // predecessor that has not been visited yet, allocate a new pool + // for it. + Value *AI = new AllocaInst(PoolDescType, 0, "PD", InsertPoint); + if (N->isNodeCompletelyFolded()) + std::cerr << "Node collapsing in '" << F.getName() << "'\n"; + + PoolDescriptors[N] = AI; + } else { + // If this node has no pool allocated predecessors, and there is no + // reason to pool allocate it, don't. + assert(PredPool == 0); + PoolDescriptors[N] = + Constant::getNullValue(PointerType::get(PoolDescType)); + ++NumNonprofit; + } + } + } + } // End switch case + } // end switch + #endif + + + //===-- AllInOneGlobalPool Heuristic --------------------------------------===// + // + // This heuristic puts all memory in the whole program into a single global + // pool. This is not safe, and is not good for performance, but can be used to + // evaluate how good the pool allocator runtime works as a "malloc replacement". + // + struct AllInOneGlobalPoolHeuristic : public Heuristic { + // TheGlobalPD - This global pool is the one and only one used when running + // with Heuristic=AllInOneGlobalPool. + GlobalVariable *TheGlobalPD; + + AllInOneGlobalPoolHeuristic() : TheGlobalPD(0) {} + + + virtual bool IsRealHeuristic() { return false; } + + void AssignToPools(const std::vector &NodesToPA, + Function *F, DSGraph &G, + std::vector &ResultPools) { + if (TheGlobalPD == 0) + TheGlobalPD = PA->CreateGlobalPool(0); + + // All nodes allocate from the same global pool. + OnePool Pool; + Pool.NodesInPool = NodesToPA; + Pool.PoolDesc = TheGlobalPD; + ResultPools.push_back(Pool); + } + }; + + //===-- OnlyOverhead Heuristic --------------------------------------------===// + // + // This heuristic is a hack to evaluate how much overhead pool allocation adds + // to a program. It adds all of the arguments, poolinits and pool destroys to + // the program, but dynamically only passes null into the pool alloc/free + // functions, causing them to allocate from the heap. + // + struct OnlyOverheadHeuristic : public Heuristic { + virtual bool IsRealHeuristic() { return false; } + + void AssignToPools(const std::vector &NodesToPA, + Function *F, DSGraph &G, + std::vector &ResultPools) { + // For this heuristic, we assign everything possible to its own pool. + for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) + ResultPools.push_back(OnePool(NodesToPA[i])); + } + + void HackFunctionBody(Function &F, std::map &PDs); + }; + + /// getDynamicallyNullPool - Return a PoolDescriptor* that is always dynamically + /// null. Insert the code necessary to produce it before the specified + /// instruction. + static Value *getDynamicallyNullPool(BasicBlock::iterator I) { + // Arrange to dynamically pass null into all of the pool functions if we are + // only checking for overhead. + static Value *NullGlobal = 0; + if (!NullGlobal) { + Module *M = I->getParent()->getParent()->getParent(); + NullGlobal = new GlobalVariable(PoolAllocate::PoolDescPtrTy, false, + GlobalValue::ExternalLinkage, + Constant::getNullValue(PoolAllocate::PoolDescPtrTy), + "llvm-poolalloc-null-init", M); + } + while (isa(I)) ++I; + + return new LoadInst(NullGlobal, "nullpd", I); + } + + // HackFunctionBody - This method is called on every transformed function body. + // Basically it replaces all uses of real pool descriptors with dynamically null + // values. However, it leaves pool init/destroy alone. + void OnlyOverheadHeuristic::HackFunctionBody(Function &F, + std::map &PDs) { + Function *PoolInit = PA->PoolInit; + Function *PoolDestroy = PA->PoolDestroy; + + Value *NullPD = getDynamicallyNullPool(F.front().begin()); + for (std::map::iterator PDI = PDs.begin(), E = PDs.end(); + PDI != E; ++PDI) { + Value *OldPD = PDI->second; + std::vector OldPDUsers(OldPD->use_begin(), OldPD->use_end()); + for (unsigned i = 0, e = OldPDUsers.size(); i != e; ++i) { + CallSite PDUser = CallSite::get(cast(OldPDUsers[i])); + if (PDUser.getCalledValue() != PoolInit && + PDUser.getCalledValue() != PoolDestroy) { + assert(PDUser.getInstruction()->getParent()->getParent() == &F && + "Not in cur fn??"); + PDUser.getInstruction()->replaceUsesOfWith(OldPD, NullPD); + } + } + } + } + + + //===-- NoNodes Heuristic -------------------------------------------------===// + // + // This dummy heuristic chooses to not pool allocate anything. + // + struct NoNodesHeuristic : public Heuristic { + virtual bool IsRealHeuristic() { return false; } + + void AssignToPools(const std::vector &NodesToPA, + Function *F, DSGraph &G, + std::vector &ResultPools) { + // Nothing to pool allocate here. + } + }; + + //===----------------------------------------------------------------------===// + // Heuristic dispatch support + // + + PA::Heuristic *Heuristic::create() { + switch (TheHeuristic) { + default: assert(0 && "Unknown heuristic!"); + case AllNodes: return new AllNodesHeuristic(); + case AllButUnreachableFromMemory: + return new AllButUnreachableFromMemoryHeuristic(); + case CyclicNodes: return new CyclicNodesHeuristic(); + case SmartCoallesceNodes: return new SmartCoallesceNodesHeuristic(); + case AllInOneGlobalPool: return new AllInOneGlobalPoolHeuristic(); + case OnlyOverhead: return new OnlyOverheadHeuristic(); + case NoNodes: return new NoNodesHeuristic(); + } + } Index: poolalloc/lib/PoolAllocate/Heuristic.h diff -c /dev/null poolalloc/lib/PoolAllocate/Heuristic.h:1.1 *** /dev/null Mon Nov 8 00:18:17 2004 --- poolalloc/lib/PoolAllocate/Heuristic.h Mon Nov 8 00:18:07 2004 *************** *** 0 **** --- 1,93 ---- + //===-- Heuristic.h - Interface to PA heuristics ----------------*- C++ -*-===// + // + // 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 header is the abstract interface used by the pool allocator to access + // the various heuristics supported. + // + //===----------------------------------------------------------------------===// + + #ifndef POOLALLOCATION_HEURISTIC_H + #define POOLALLOCATION_HEURISTIC_H + + #include + #include + + namespace llvm { + class Value; + class Function; + class Module; + class DSGraph; + class DSNode; + class PoolAllocate; + namespace PA { + class Heuristic { + protected: + Module *M; + DSGraph *GG; + PoolAllocate *PA; + + Heuristic() {} + public: + void Initialize(Module &m, DSGraph &gg, PoolAllocate &pa) { + M = &m; GG = ≫ PA = &pa; + } + virtual ~Heuristic(); + + /// IsRealHeuristic - Return true if this is not a real pool allocation + /// heuristic. + virtual bool IsRealHeuristic() { return true; } + + /// OnePool - This represents some number of nodes which are coallesced into + /// a pool. + struct OnePool { + // NodesInPool - The DS nodes to be allocated to this pool. There may be + // multiple here if they are being coallesced into the same pool. + std::vector NodesInPool; + + // PoolDesc - If the heuristic wants the nodes allocated to a specific + // pool descriptor, it can specify it here, otherwise a new pool is + // created. + Value *PoolDesc; + + // PoolSize - If the pool is to be created, indicate the "recommended + // size" for the pool here. This gets passed into poolinit. + unsigned PoolSize; + + OnePool() : PoolDesc(0), PoolSize(0) {} + + OnePool(DSNode *N) : PoolDesc(0), PoolSize(getRecommendedSize(N)) { + NodesInPool.push_back(N); + } + OnePool(DSNode *N, Value *PD) : PoolDesc(PD), PoolSize(0) { + NodesInPool.push_back(N); + } + }; + + /// AssignToPools - Partition NodesToPA into a set of disjoint pools, + /// returning the result in ResultPools. If this is a function being pool + /// allocated, F will not be null. + virtual void AssignToPools(const std::vector &NodesToPA, + Function *F, DSGraph &G, + std::vector &ResultPools) = 0; + + // Hacks for the OnlyOverhead heuristic. + virtual void HackFunctionBody(Function &F, std::map &PDs){} + + /// getRecommendedSize - Return the recommended pool size for this DSNode. + /// + static unsigned getRecommendedSize(DSNode *N); + + /// create - This static ctor creates the heuristic, based on the command + /// line argument to choose the heuristic. + static Heuristic *create(); + }; + } + } + + #endif Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.86 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.87 --- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.86 Sun Nov 7 16:19:59 2004 +++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp Mon Nov 8 00:18:07 2004 @@ -13,8 +13,9 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "poolalloc" -#include "EquivClassGraphs.h" #include "PoolAllocate.h" +#include "EquivClassGraphs.h" +#include "Heuristic.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" @@ -22,7 +23,6 @@ #include "llvm/Constants.h" #include "llvm/Analysis/DataStructure/DataStructure.h" #include "llvm/Analysis/DataStructure/DSGraph.h" -#include "llvm/Analysis/DataStructure/DSGraphTraits.h" #include "llvm/Support/CFG.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" @@ -62,37 +62,12 @@ // poolfree?) const Type *PoolDescType; - enum PoolAllocHeuristic { - NoNodes, - OnlyOverhead, - AllInOneGlobalPool, - SmartCoallesceNodes, - CyclicNodes, - AllNodes, - }; - cl::opt - Heuristic("poolalloc-heuristic", - cl::desc("Heuristic to choose which nodes to pool allocate"), - cl::values(clEnumVal(AllNodes, " Pool allocate all nodes"), - clEnumVal(CyclicNodes, " Pool allocate nodes with cycles"), - clEnumVal(SmartCoallesceNodes, " Use the smart node merging heuristic"), - clEnumVal(AllInOneGlobalPool, " Use pool library as replacement for malloc/free"), - clEnumVal(OnlyOverhead, " Do not pool allocate anything, but induce all overhead from it"), - clEnumVal(NoNodes, " Do not pool allocate anything"), - clEnumValEnd), - cl::init(AllNodes)); - cl::opt DisableInitDestroyOpt("poolalloc-force-simple-pool-init", cl::desc("Always insert poolinit/pooldestroy calls at start and exit of functions"), cl::init(true)); cl::opt DisablePoolFreeOpt("poolalloc-force-all-poolfrees", cl::desc("Do not try to elide poolfree's where possible")); - - - // TheGlobalPD - This global pool is the one and only one used when running - // with Heuristic=AllInOneGlobalPool. - GlobalVariable *TheGlobalPD = 0; } void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const { @@ -105,6 +80,9 @@ CurModule = &M; ECGraphs = &getAnalysis(); // folded inlined CBU graphs + CurHeuristic = Heuristic::create(); + CurHeuristic->Initialize(M, ECGraphs->getGlobalsGraph(), *this); + // Add the pool* prototypes to the module AddPoolPrototypes(); @@ -147,9 +125,10 @@ F->replaceAllUsesWith(ConstantExpr::getCast(I->second, F->getType())); } - if (Heuristic != NoNodes && Heuristic != OnlyOverhead && - Heuristic != AllInOneGlobalPool) + if (CurHeuristic->IsRealHeuristic()) MicroOptimizePoolCalls(); + + delete CurHeuristic; return true; } @@ -253,15 +232,6 @@ G.getNodeForValue(*I).getNode()->markReachableNodes(NodesFromGlobals); } -static void printNTOMap(std::map &NTOM) { - std::cerr << "NTOM MAP\n"; - for (std::map::iterator I = NTOM.begin(), - E = NTOM.end(); I != E; ++I) { - if (!isa(I->first) && !isa(I->first)) - std::cerr << *I->first << " to " << *I->second << "\n"; - } -} - static void MarkNodesWhichMustBePassedIn(hash_set &MarkedNodes, Function &F, DSGraph &G) { // Mark globals and incomplete nodes as live... (this handles arguments) @@ -383,51 +353,6 @@ return FI.Clone = New; } -static bool NodeExistsInCycle(DSNode *N) { - for (DSNode::iterator I = N->begin(), E = N->end(); I != E; ++I) - if (*I && std::find(df_begin(*I), df_end(*I), N) != df_end(*I)) - return true; - return false; -} - -/// NodeIsSelfRecursive - Return true if this node contains a pointer to itself. -static bool NodeIsSelfRecursive(DSNode *N) { - for (DSNode::iterator I = N->begin(), E = N->end(); I != E; ++I) - if (*I == N) return true; - return false; -} - -static bool ShouldPoolAllocate(DSNode *N) { - // Now that we have a list of all of the nodes that CAN be pool allocated, use - // a heuristic to filter out nodes which are not profitable to pool allocate. - switch (Heuristic) { - default: - case AllInOneGlobalPool: - case OnlyOverhead: - case AllNodes: return true; - case NoNodes: return false; - case CyclicNodes: // Pool allocate nodes that are cyclic and not arrays - return NodeExistsInCycle(N); - } -} - -/// POVisit - This implements functionality found in Support/PostOrderIterator.h -/// but in a way that allows multiple roots to be used. If PostOrderIterator -/// supported an external set like DepthFirstIterator did I could eliminate this -/// cruft. -/// -static void POVisit(DSNode *N, std::set &Visited, - std::vector &Order) { - if (!Visited.insert(N).second) return; // already visited - - // Visit all children before visiting this node. - for (DSNode::iterator I = N->begin(), E = N->end(); I != E; ++I) - if (DSNode *C = const_cast(*I)) - POVisit(C, Visited, Order); - // Now that we visited all of our children, add ourself to the order. - Order.push_back(N); -} - // SetupGlobalPools - Create global pools for all DSNodes in the globals graph // which contain heap objects. If a global variable points to a piece of memory // allocated from the heap, this pool gets a global lifetime. This is @@ -455,10 +380,6 @@ GlobalHeapNodes.erase(Last); } - // If we don't need to create any global pools, exit now. - if (GlobalHeapNodes.empty() && - Heuristic != AllInOneGlobalPool) return false; - // Otherwise get the main function to insert the poolinit calls. Function *MainFunc = M.getMainFunction(); if (MainFunc == 0 || MainFunc->isExternal()) { @@ -476,75 +397,52 @@ std::cerr << "Pool allocating " << GlobalHeapNodes.size() << " global nodes!\n"; - // If we are putting everything into a single global pool, create it now and - // put all globals pool descriptors into it. - if (Heuristic == AllInOneGlobalPool) { - // Create the global pool descriptor. - TheGlobalPD = - new GlobalVariable(PoolDescType, false, GlobalValue::InternalLinkage, - Constant::getNullValue(PoolDescType), "GlobalPool",&M); - - // Initialize it on entry to main. - Value *ElSize = ConstantUInt::get(Type::UIntTy, 0); - new CallInst(PoolInit, make_vector((Value*)TheGlobalPD, ElSize, 0), - "", InsertPt); - - for (hash_set::iterator I = GlobalHeapNodes.begin(), - E = GlobalHeapNodes.end(); I != E; ++I) - GlobalNodes[*I] = TheGlobalPD; - ++NumPools; // We have one pool. - return false; + std::vector NodesToPA(GlobalHeapNodes.begin(),GlobalHeapNodes.end()); + std::vector ResultPools; + CurHeuristic->AssignToPools(NodesToPA, 0, GG, ResultPools); + + // Perform all global assignments as specified. + for (unsigned i = 0, e = ResultPools.size(); i != e; ++i) { + Heuristic::OnePool &Pool = ResultPools[i]; + Value *PoolDesc = Pool.PoolDesc; + if (PoolDesc == 0) + PoolDesc = CreateGlobalPool(Pool.PoolSize); + for (unsigned N = 0, e = Pool.NodesInPool.size(); N != e; ++N) { + GlobalNodes[Pool.NodesInPool[N]] = PoolDesc; + GlobalHeapNodes.erase(Pool.NodesInPool[N]); // Handled! + } } - - // Loop over all of the pools, creating a new global pool descriptor, - // inserting a new entry in GlobalNodes, and inserting a call to poolinit in - // main. + // Any unallocated DSNodes get null pool descriptor pointers. for (hash_set::iterator I = GlobalHeapNodes.begin(), E = GlobalHeapNodes.end(); I != E; ++I) { - bool ShouldPoolAlloc = true; - switch (Heuristic) { - case AllInOneGlobalPool: assert(0 && "Case handled above!"); - case OnlyOverhead: - case AllNodes: break; - case NoNodes: ShouldPoolAlloc = false; break; - case SmartCoallesceNodes: -#if 1 - if ((*I)->isArray() && !(*I)->isNodeCompletelyFolded()) - ShouldPoolAlloc = false; -#endif - // fall through - case CyclicNodes: - if (!NodeExistsInCycle(*I)) - ShouldPoolAlloc = false; - break; - } - - if (ShouldPoolAlloc) { - GlobalVariable *GV = - new GlobalVariable(PoolDescType, false, GlobalValue::InternalLinkage, - Constant::getNullValue(PoolDescType), "GlobalPool",&M); - GlobalNodes[*I] = GV; - - Value *ElSize = - ConstantUInt::get(Type::UIntTy, (*I)->getType()->isSized() ? - TD.getTypeSize((*I)->getType()) : 0); - new CallInst(PoolInit, make_vector((Value*)GV, ElSize, 0), "", InsertPt); - - ++NumPools; - if (!(*I)->isNodeCompletelyFolded()) - ++NumTSPools; - } else { - GlobalNodes[*I] = - Constant::getNullValue(PointerType::get(PoolDescType)); - ++NumNonprofit; - } + GlobalNodes[*I] = Constant::getNullValue(PointerType::get(PoolDescType)); + ++NumNonprofit; } - + return false; } +GlobalVariable *PoolAllocate::CreateGlobalPool(unsigned RecSize) { + GlobalVariable *GV = + new GlobalVariable(PoolDescType, false, GlobalValue::InternalLinkage, + Constant::getNullValue(PoolDescType), "GlobalPool", + CurModule); + + Function *MainFunc = CurModule->getMainFunction(); + assert(MainFunc && "No main in program??"); + + BasicBlock::iterator InsertPt = MainFunc->getEntryBlock().begin(); + while (isa(InsertPt)) ++InsertPt; + + Value *ElSize = ConstantUInt::get(Type::UIntTy, RecSize); + new CallInst(PoolInit, make_vector((Value*)GV, ElSize, 0), "", InsertPt); + ++NumPools; + return GV; +} + + // CreatePools - This creates the pool initialization and destruction code for // the DSNodes specified by the NodesToPA list. This adds an entry to the // PoolDescriptors map for each DSNode. @@ -554,178 +452,35 @@ std::map &PoolDescriptors) { if (NodesToPA.empty()) return; - // Loop over all of the pools, inserting code into the entry block of the - // function for the initialization and code in the exit blocks for - // destruction. - // - Instruction *InsertPoint = F.front().begin(); - - switch (Heuristic) { - case AllNodes: - case NoNodes: - case CyclicNodes: - case OnlyOverhead: - for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) { - DSNode *Node = NodesToPA[i]; - if (ShouldPoolAllocate(Node)) { - // Create a new alloca instruction for the pool... - Value *AI = new AllocaInst(PoolDescType, 0, "PD", InsertPoint); - - // Void types in DS graph are never used - if (Node->getType() == Type::VoidTy) - std::cerr << "Node collapsing in '" << F.getName() << "'\n"; - - // Update the PoolDescriptors map - PoolDescriptors.insert(std::make_pair(Node, AI)); - } else { - PoolDescriptors[Node] = - Constant::getNullValue(PointerType::get(PoolDescType)); - ++NumNonprofit; - } - } - break; - case AllInOneGlobalPool: - for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) - PoolDescriptors[NodesToPA[i]] = TheGlobalPD; - break; - - case SmartCoallesceNodes: { - std::set NodesToPASet(NodesToPA.begin(), NodesToPA.end()); - - // DSGraphs only have unidirectional edges, to traverse or inspect the - // predecessors of nodes, we must build a mapping of the inverse graph. - std::map > InverseGraph; - - for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) { - DSNode *Node = NodesToPA[i]; - for (DSNode::iterator CI = Node->begin(), E = Node->end(); CI != E; ++CI) - if (DSNode *Child = const_cast(*CI)) - if (NodesToPASet.count(Child)) - InverseGraph[Child].push_back(Node); - } + std::vector ResultPools; + CurHeuristic->AssignToPools(NodesToPA, &F, *NodesToPA[0]->getParentGraph(), + ResultPools); - // Traverse the heap nodes in reverse-post-order so that we are guaranteed - // to visit all nodes pointing to another node before we visit that node - // itself (except with cycles). - - // FIXME: This really should be using the PostOrderIterator.h file stuff, - // but the routines there do not support external storage! - std::set Visited; - std::vector Order; - for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) - POVisit(NodesToPA[i], Visited, Order); - - // We want RPO, not PO, so reverse the order. - std::reverse(Order.begin(), Order.end()); - - // Okay, we have an ordering of the nodes in reverse post order. Traverse - // each node in this ordering, noting that there may be nodes in the order - // that are not in our NodesToPA list. - for (unsigned i = 0, e = Order.size(); i != e; ++i) - if (NodesToPASet.count(Order[i])) { // Only process pa nodes. - DSNode *N = Order[i]; - - // If this node has a backedge to itself, pool allocate it in a new - // pool. - if (NodeIsSelfRecursive(N)) { - // Create a new alloca instruction for the pool... - Value *AI = new AllocaInst(PoolDescType, 0, "PD", InsertPoint); - - // Void types in DS graph are never used - if (N->isNodeCompletelyFolded()) - std::cerr << "Node collapsing in '" << F.getName() << "'\n"; - - // Update the PoolDescriptors map - PoolDescriptors.insert(std::make_pair(N, AI)); -#if 1 - } else if (N->isArray() && !N->isNodeCompletelyFolded()) { - // We never pool allocate array nodes. - PoolDescriptors[N] = - Constant::getNullValue(PointerType::get(PoolDescType)); - ++NumNonprofit; -#endif - } else { - // Otherwise the node is not self recursive. If the node is not an - // array, we can co-locate it with the pool of a predecessor node if - // any has been pool allocated, and start a new pool if a predecessor - // is an array. If there is a predecessor of this node that has not - // been visited yet in this RPO traversal, that means there is a - // cycle, so we choose to pool allocate this node right away. - // - // If there multiple predecessors in multiple different pools, we - // don't pool allocate this at all. - - // Check out each of the predecessors of this node. - std::vector &Preds = InverseGraph[N]; - Value *PredPool = 0; - bool HasUnvisitedPred = false; - bool HasArrayPred = false; - bool HasMultiplePredPools = false; - for (unsigned p = 0, e = Preds.size(); p != e; ++p) { - DSNode *Pred = Preds[p]; - if (!PoolDescriptors.count(Pred)) - HasUnvisitedPred = true; // no pool assigned to predecessor? - else if (Pred->isArray() && !Pred->isNodeCompletelyFolded()) - HasArrayPred = true; - else if (PredPool && PoolDescriptors[Pred] != PredPool) - HasMultiplePredPools = true; - else if (!PredPool && - !isa(PoolDescriptors[Pred])) - PredPool = PoolDescriptors[Pred]; - // Otherwise, this predecessor has the same pool as a previous one. - } + std::set UnallocatedNodes(NodesToPA.begin(), NodesToPA.end()); - if (HasMultiplePredPools) { - // If this node has predecessors that are in different pools, don't - // pool allocate this node. - PoolDescriptors[N] = - Constant::getNullValue(PointerType::get(PoolDescType)); - ++NumNonprofit; - } else if (PredPool) { - // If all of the predecessors of this node are already in a pool, - // colocate. - PoolDescriptors[N] = PredPool; - ++NumColocated; - } else if (HasArrayPred || HasUnvisitedPred) { - // If this node has an array predecessor, or if there is a - // predecessor that has not been visited yet, allocate a new pool - // for it. - Value *AI = new AllocaInst(PoolDescType, 0, "PD", InsertPoint); - if (N->isNodeCompletelyFolded()) - std::cerr << "Node collapsing in '" << F.getName() << "'\n"; - - PoolDescriptors[N] = AI; - } else { - // If this node has no pool allocated predecessors, and there is no - // reason to pool allocate it, don't. - assert(PredPool == 0); - PoolDescriptors[N] = - Constant::getNullValue(PointerType::get(PoolDescType)); - ++NumNonprofit; - } - } - } - } // End switch case - } // end switch -} + Instruction *InsertPoint = F.front().begin(); -/// getDynamicallyNullPool - Return a PoolDescriptor* that is always dynamically -/// null. Insert the code necessary to produce it before the specified -/// instruction. -static Value *getDynamicallyNullPool(BasicBlock::iterator I) { - // Arrange to dynamically pass null into all of the pool functions if we are - // only checking for overhead. - static Value *NullGlobal = 0; - if (!NullGlobal) { - Module *M = I->getParent()->getParent()->getParent(); - NullGlobal = new GlobalVariable(PoolAllocate::PoolDescPtrTy, false, - GlobalValue::ExternalLinkage, - Constant::getNullValue(PoolAllocate::PoolDescPtrTy), - "llvm-poolalloc-null-init", M); + // Perform all global assignments as specified. + for (unsigned i = 0, e = ResultPools.size(); i != e; ++i) { + Heuristic::OnePool &Pool = ResultPools[i]; + Value *PoolDesc = Pool.PoolDesc; + if (PoolDesc == 0) + // Create a new alloca instruction for the pool. The poolinit will be + // inserted later. + PoolDesc = new AllocaInst(PoolDescType, 0, "PD", InsertPoint); + + for (unsigned N = 0, e = Pool.NodesInPool.size(); N != e; ++N) { + PoolDescriptors[Pool.NodesInPool[N]] = PoolDesc; + UnallocatedNodes.erase(Pool.NodesInPool[N]); // Handled! + } } - while (isa(I)) ++I; - return new LoadInst(NullGlobal, "nullpd", I); + // Any unallocated DSNodes get null pool descriptor pointers. + for (std::set::iterator I = UnallocatedNodes.begin(), + E = UnallocatedNodes.end(); I != E; ++I) { + PoolDescriptors[*I] =Constant::getNullValue(PointerType::get(PoolDescType)); + ++NumNonprofit; + } } // processFunction - Pool allocate any data structures which are contained in @@ -753,10 +508,6 @@ GlobalsGraphNodeMapping); } - Value *NullPD = 0; - if (Heuristic == OnlyOverhead) - NullPD = getDynamicallyNullPool(NewF.front().begin()); - // Loop over all of the nodes which are non-escaping, adding pool-allocatable // ones to the NodesToPA vector. std::vector NodesToPA; @@ -769,8 +520,6 @@ DSNode *GGN = GlobalsGraphNodeMapping[N].getNode(); assert(GGN && GlobalNodes[GGN] && "No global node found??"); FI.PoolDescriptors[N] = GlobalNodes[GGN]; - if (Heuristic == OnlyOverhead) - FI.PoolDescriptors[N] = NullPD; } else if (!MarkedNodes.count(N)) { // Otherwise, if it was not passed in from outside the function, it must // be a local pool! @@ -797,6 +546,7 @@ if (!NodesToPA.empty()) InitializeAndDestroyPools(NewF, NodesToPA, FI.PoolDescriptors, PoolUses, PoolFrees); + CurHeuristic->HackFunctionBody(NewF, FI.PoolDescriptors); } template @@ -848,10 +598,6 @@ std::map &PoolDescriptors, std::set > &PoolUses, std::set > &PoolFrees) { - Value *NullPD = 0; - if (Heuristic == OnlyOverhead) - NullPD = getDynamicallyNullPool(F.front().begin()); - TargetData &TD = getAnalysis(); std::vector PoolInitPoints; @@ -897,11 +643,6 @@ if (!HasUse && !HasFree) continue; if (!AllocasHandled.insert(PD).second) continue; - // Arrange to dynamically pass null into all of the pool functions if we are - // only checking for overhead. - if (Heuristic == OnlyOverhead) - PD->replaceAllUsesWith(NullPD); - ++NumPools; if (!Node->isNodeCompletelyFolded()) ++NumTSPools; @@ -1026,8 +767,9 @@ // Insert the calls to initialize the pool. unsigned ElSizeV = 0; - if (Node->getType()->isSized()) + if (!Node->isArray() && Node->getType()->isSized()) ElSizeV = TD.getTypeSize(Node->getType()); + if (ElSizeV == 1) ElSizeV = 0; Value *ElSize = ConstantUInt::get(Type::UIntTy, ElSizeV); for (unsigned i = 0, e = PoolInitPoints.size(); i != e; ++i) { Index: poolalloc/lib/PoolAllocate/PoolAllocate.h diff -u poolalloc/lib/PoolAllocate/PoolAllocate.h:1.28 poolalloc/lib/PoolAllocate/PoolAllocate.h:1.29 --- poolalloc/lib/PoolAllocate/PoolAllocate.h:1.28 Sun Nov 7 16:19:59 2004 +++ poolalloc/lib/PoolAllocate/PoolAllocate.h Mon Nov 8 00:18:07 2004 @@ -14,8 +14,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TRANSFORMS_POOLALLOCATE_H -#define LLVM_TRANSFORMS_POOLALLOCATE_H +#ifndef POOLALLOCATE_H +#define POOLALLOCATE_H #include "llvm/Pass.h" #include "llvm/DerivedTypes.h" @@ -35,6 +35,7 @@ namespace PA { class EquivClassGraphs; + class Heuristic; /// FuncInfo - Represent the pool allocation information for one function in /// the program. Note that many functions must actually be cloned in order @@ -97,6 +98,8 @@ Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolRealloc, *PoolFree; static const Type *PoolDescPtrTy; + PA::Heuristic *CurHeuristic; + /// GlobalNodes - For each node (with an H marker) in the globals graph, this /// map contains the global variable that holds the pool descriptor for the /// node. @@ -132,6 +135,10 @@ Module *getCurModule() { return CurModule; } + /// CreateGlobalPool - Create a global pool descriptor, initialize it in main, + /// and return a pointer to the global for it. + GlobalVariable *CreateGlobalPool(unsigned RecSize); + private: /// AddPoolPrototypes - Add prototypes for the pool functions to the From alkis at cs.uiuc.edu Mon Nov 8 00:19:51 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 8 Nov 2004 00:19:51 -0600 Subject: [llvm-commits] CVS: llvm-java/Makefile.rules Message-ID: <200411080619.AAA02651@zion.cs.uiuc.edu> Changes in directory llvm-java: Makefile.rules updated: 1.12 -> 1.13 --- Log message: PROJTOOLCURRENT changed into ToolDir. --- Diffs of the changes: (+2 -2) Index: llvm-java/Makefile.rules diff -u llvm-java/Makefile.rules:1.12 llvm-java/Makefile.rules:1.13 --- llvm-java/Makefile.rules:1.12 Sat Oct 30 07:52:30 2004 +++ llvm-java/Makefile.rules Mon Nov 8 00:19:40 2004 @@ -7,8 +7,8 @@ # ##===----------------------------------------------------------------------===## -CLASS2LLVM := $(PROJTOOLCURRENT)/class2llvm$(EXEEXT) -CLASSDUMP := $(PROJTOOLCURRENT)/classdump$(EXEEXT) +CLASS2LLVM := $(ToolDir)/class2llvm$(EXEEXT) +CLASSDUMP := $(ToolDir)/classdump$(EXEEXT) # rule to make bytecode from assembly %.bc: %.ll From lattner at cs.uiuc.edu Mon Nov 8 00:32:41 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 Nov 2004 00:32:41 -0600 Subject: [llvm-commits] CVS: poolalloc/lib/PoolAllocate/PoolAllocate.cpp Message-ID: <200411080632.iA86Wfg5020596@apoc.cs.uiuc.edu> Changes in directory poolalloc/lib/PoolAllocate: PoolAllocate.cpp updated: 1.87 -> 1.88 --- Log message: Reenable partial pool allocation --- Diffs of the changes: (+2 -1) Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.87 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.88 --- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.87 Mon Nov 8 00:18:07 2004 +++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp Mon Nov 8 00:32:31 2004 @@ -624,7 +624,8 @@ for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) { DSNode *Node = NodesToPA[i]; - if (isa(PoolDescriptors[Node])) + if (isa(PoolDescriptors[Node]) || + isa(PoolDescriptors[Node])) continue; assert(isa(PoolDescriptors[Node]) && "Why pool allocate this?"); From lattner at cs.uiuc.edu Mon Nov 8 00:49:24 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 Nov 2004 00:49:24 -0600 Subject: [llvm-commits] CVS: poolalloc/lib/PoolAllocate/Heuristic.cpp Message-ID: <200411080649.iA86nOFt021116@apoc.cs.uiuc.edu> Changes in directory poolalloc/lib/PoolAllocate: Heuristic.cpp updated: 1.1 -> 1.2 --- Log message: Implement the AllButUnreachableFromMemoryHeuristic correctly. --- Diffs of the changes: (+43 -3) Index: poolalloc/lib/PoolAllocate/Heuristic.cpp diff -u poolalloc/lib/PoolAllocate/Heuristic.cpp:1.1 poolalloc/lib/PoolAllocate/Heuristic.cpp:1.2 --- poolalloc/lib/PoolAllocate/Heuristic.cpp:1.1 Mon Nov 8 00:18:07 2004 +++ poolalloc/lib/PoolAllocate/Heuristic.cpp Mon Nov 8 00:49:14 2004 @@ -74,7 +74,6 @@ //===-- AllButUnreachableFromMemoryHeuristic Heuristic --------------------===// -// // // This heuristic pool allocates everything possible into separate pools, unless // the pool is not reachable by other memory objects. This filters out objects @@ -86,9 +85,24 @@ void AssignToPools(const std::vector &NodesToPA, Function *F, DSGraph &G, std::vector &ResultPools) { - // FIXME: implement + // Build a set of all nodes that are reachable from another node in the + // graph. + std::set ReachableFromMemory; + for (DSGraph::node_iterator I = G.node_begin(), E = G.node_end(); + I != E; ++I) { + DSNode *N = *I; + for (DSNode::iterator NI = N->begin(), E = N->end(); NI != E; ++NI) + for (df_ext_iterator + DI = df_ext_begin(*NI, ReachableFromMemory), + E = df_ext_end(*NI, ReachableFromMemory); DI != E; ++DI) + /*empty*/; + } + + // Only pool allocate a node if it is reachable from a memory object (itself + // included). for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) - ResultPools.push_back(OnePool(NodesToPA[i])); + if (ReachableFromMemory.count(NodesToPA[i])) + ResultPools.push_back(OnePool(NodesToPA[i])); } }; @@ -145,6 +159,32 @@ }; #if 0 +/// NodeIsSelfRecursive - Return true if this node contains a pointer to itself. +static bool NodeIsSelfRecursive(DSNode *N) { + for (DSNode::iterator I = N->begin(), E = N->end(); I != E; ++I) + if (*I == N) return true; + return false; +} + +/// POVisit - This implements functionality found in Support/PostOrderIterator.h +/// but in a way that allows multiple roots to be used. If PostOrderIterator +/// supported an external set like DepthFirstIterator did I could eliminate this +/// cruft. +/// +static void POVisit(DSNode *N, std::set &Visited, + std::vector &Order) { + if (!Visited.insert(N).second) return; // already visited + + // Visit all children before visiting this node. + for (DSNode::iterator I = N->begin(), E = N->end(); I != E; ++I) + if (DSNode *C = const_cast(*I)) + POVisit(C, Visited, Order); + // Now that we visited all of our children, add ourself to the order. + Order.push_back(N); +} + + + // Heuristic for building per-function pools switch (Heuristic) { From lattner at cs.uiuc.edu Mon Nov 8 00:58:26 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 Nov 2004 00:58:26 -0600 Subject: [llvm-commits] CVS: poolalloc/test/TEST.poolalloc.Makefile TEST.poolalloc.report Message-ID: <200411080658.iA86wQVU022133@apoc.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.poolalloc.Makefile updated: 1.30 -> 1.31 TEST.poolalloc.report updated: 1.22 -> 1.23 --- Log message: Add allnodes back now htat the default pool allocation is not allnodes --- Diffs of the changes: (+51 -41) Index: poolalloc/test/TEST.poolalloc.Makefile diff -u poolalloc/test/TEST.poolalloc.Makefile:1.30 poolalloc/test/TEST.poolalloc.Makefile:1.31 --- poolalloc/test/TEST.poolalloc.Makefile:1.30 Sat Nov 6 23:24:22 2004 +++ poolalloc/test/TEST.poolalloc.Makefile Mon Nov 8 00:58:16 2004 @@ -7,7 +7,7 @@ CFLAGS = -O2 -fno-strict-aliasing -EXTRA_PA_FLAGS := -poolalloc-force-simple-pool-init +EXTRA_PA_FLAGS := # HEURISTIC can be set to: # AllNodes @@ -46,6 +46,11 @@ - at rm -f $(CURDIR)/$@.info -$(OPT_PA_STATS) -poolalloc $(EXTRA_PA_FLAGS) $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out +$(PROGRAMS_TO_TEST:%=Output/%.$(TEST).allnodes.bc): \ +Output/%.$(TEST).allnodes.bc: Output/%.llvm.bc $(PA_SO) $(LOPT) + - at rm -f $(CURDIR)/$@.info + -$(OPT_PA_STATS) -poolalloc -poolalloc-heuristic=AllNodes $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out + $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).mallocrepl.bc): \ Output/%.$(TEST).mallocrepl.bc: Output/%.llvm.bc $(PA_SO) $(LOPT) @@ -57,48 +62,50 @@ - at rm -f $(CURDIR)/$@.info -$(OPT_PA_STATS) -poolalloc -poolalloc-heuristic=OnlyOverhead $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out +$(PROGRAMS_TO_TEST:%=Output/%.nonpa.bc): \ +Output/%.nonpa.bc: Output/%.llvm.bc $(LOPT) + - at rm -f $(CURDIR)/$@.info + -$(LOPT) $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out # This rule compiles the new .bc file into a .c file using CBE $(PROGRAMS_TO_TEST:%=Output/%.poolalloc.cbe.c): \ Output/%.poolalloc.cbe.c: Output/%.$(TEST).poolalloc.bc $(LLC) -$(LLC) -march=c -f $< -o $@ -# This rule compiles the new .bc file into a .c file using CBE +$(PROGRAMS_TO_TEST:%=Output/%.allnodes.cbe.c): \ +Output/%.allnodes.cbe.c: Output/%.$(TEST).allnodes.bc $(LLC) + -$(LLC) -march=c -f $< -o $@ + $(PROGRAMS_TO_TEST:%=Output/%.mallocrepl.cbe.c): \ Output/%.mallocrepl.cbe.c: Output/%.$(TEST).mallocrepl.bc $(LLC) -$(LLC) -march=c -f $< -o $@ -# This rule compiles the new .bc file into a .c file using CBE $(PROGRAMS_TO_TEST:%=Output/%.onlyoverhead.cbe.c): \ Output/%.onlyoverhead.cbe.c: Output/%.$(TEST).onlyoverhead.bc $(LLC) -$(LLC) -march=c -f $< -o $@ -# This rule compiles the .c file into an executable using $CC +$(PROGRAMS_TO_TEST:%=Output/%.nonpa.cbe.c): \ +Output/%.nonpa.cbe.c: Output/%.nonpa.bc $(LLC) + -$(LLC) -march=c -f $< -o $@ + + + $(PROGRAMS_TO_TEST:%=Output/%.poolalloc.cbe): \ Output/%.poolalloc.cbe: Output/%.poolalloc.cbe.c $(PA_RT_O) -$(CC) $(CFLAGS) $< $(PA_RT_O) $(LLCLIBS) $(LDFLAGS) -o $@ -# This rule compiles the .c file into an executable using $CC +$(PROGRAMS_TO_TEST:%=Output/%.allnodes.cbe): \ +Output/%.allnodes.cbe: Output/%.allnodes.cbe.c $(PA_RT_O) + -$(CC) $(CFLAGS) $< $(PA_RT_O) $(LLCLIBS) $(LDFLAGS) -o $@ + $(PROGRAMS_TO_TEST:%=Output/%.mallocrepl.cbe): \ Output/%.mallocrepl.cbe: Output/%.mallocrepl.cbe.c $(PA_RT_O) -$(CC) $(CFLAGS) $< $(PA_RT_O) $(LLCLIBS) $(LDFLAGS) -o $@ -# This rule compiles the .c file into an executable using $CC $(PROGRAMS_TO_TEST:%=Output/%.onlyoverhead.cbe): \ Output/%.onlyoverhead.cbe: Output/%.onlyoverhead.cbe.c $(PA_RT_O) -$(CC) $(CFLAGS) $< $(PA_RT_O) $(LLCLIBS) $(LDFLAGS) -o $@ - -$(PROGRAMS_TO_TEST:%=Output/%.nonpa.bc): \ -Output/%.nonpa.bc: Output/%.llvm.bc $(LOPT) - - at rm -f $(CURDIR)/$@.info - -$(LOPT) $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out - -$(PROGRAMS_TO_TEST:%=Output/%.nonpa.cbe.c): \ -Output/%.nonpa.cbe.c: Output/%.nonpa.bc $(LLC) - -$(LLC) -march=c -f $< -o $@ - -# This rule compiles the .c file into an executable using $CC $(PROGRAMS_TO_TEST:%=Output/%.nonpa.cbe): \ Output/%.nonpa.cbe: Output/%.nonpa.cbe.c $(PA_RT_O) -$(CC) $(CFLAGS) $< $(PA_RT_O) $(LLCLIBS) $(LDFLAGS) -o $@ @@ -113,22 +120,18 @@ Output/%.poolalloc.out-cbe: Output/%.poolalloc.cbe -$(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) -# This rule runs the generated executable, generating timing information, for -# normal test programs +$(PROGRAMS_TO_TEST:%=Output/%.allnodes.out-cbe): \ +Output/%.allnodes.out-cbe: Output/%.allnodes.cbe + -$(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) + $(PROGRAMS_TO_TEST:%=Output/%.mallocrepl.out-cbe): \ Output/%.mallocrepl.out-cbe: Output/%.mallocrepl.cbe -$(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) - -# This rule runs the generated executable, generating timing information, for -# normal test programs $(PROGRAMS_TO_TEST:%=Output/%.onlyoverhead.out-cbe): \ Output/%.onlyoverhead.out-cbe: Output/%.onlyoverhead.cbe -$(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) - -# This rule runs the generated executable, generating timing information, for -# normal test programs $(PROGRAMS_TO_TEST:%=Output/%.nonpa.out-cbe): \ Output/%.nonpa.out-cbe: Output/%.nonpa.cbe -$(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) @@ -144,8 +147,14 @@ -(cd Output/poolalloccbe-$(RUN_TYPE); cat $(LOCAL_OUTPUTS)) > $@ -cp Output/poolalloccbe-$(RUN_TYPE)/$(STDOUT_FILENAME).time $@.time -# This rule runs the generated executable, generating timing information, for -# SPEC +$(PROGRAMS_TO_TEST:%=Output/%.allnodes.out-cbe): \ +Output/%.allnodes.out-cbe: Output/%.allnodes.cbe + -$(SPEC_SANDBOX) allnodescbe-$(RUN_TYPE) $@ $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + ../../$< $(RUN_OPTIONS) + -(cd Output/allnodescbe-$(RUN_TYPE); cat $(LOCAL_OUTPUTS)) > $@ + -cp Output/allnodescbe-$(RUN_TYPE)/$(STDOUT_FILENAME).time $@.time + $(PROGRAMS_TO_TEST:%=Output/%.mallocrepl.out-cbe): \ Output/%.mallocrepl.out-cbe: Output/%.mallocrepl.cbe -$(SPEC_SANDBOX) mallocreplcbe-$(RUN_TYPE) $@ $(REF_IN_DIR) \ @@ -154,8 +163,6 @@ -(cd Output/mallocreplcbe-$(RUN_TYPE); cat $(LOCAL_OUTPUTS)) > $@ -cp Output/mallocreplcbe-$(RUN_TYPE)/$(STDOUT_FILENAME).time $@.time -# This rule runs the generated executable, generating timing information, for -# SPEC $(PROGRAMS_TO_TEST:%=Output/%.onlyoverhead.out-cbe): \ Output/%.onlyoverhead.out-cbe: Output/%.onlyoverhead.cbe -$(SPEC_SANDBOX) onlyoverheadcbe-$(RUN_TYPE) $@ $(REF_IN_DIR) \ @@ -164,8 +171,6 @@ -(cd Output/onlyoverheadcbe-$(RUN_TYPE); cat $(LOCAL_OUTPUTS)) > $@ -cp Output/onlyoverheadcbe-$(RUN_TYPE)/$(STDOUT_FILENAME).time $@.time -# This rule runs the generated executable, generating timing information, for -# SPEC $(PROGRAMS_TO_TEST:%=Output/%.nonpa.out-cbe): \ Output/%.nonpa.out-cbe: Output/%.nonpa.cbe -$(SPEC_SANDBOX) nonpacbe-$(RUN_TYPE) $@ $(REF_IN_DIR) \ @@ -184,22 +189,21 @@ @cp Output/$*.out-nat Output/$*.poolalloc.out-nat -$(DIFFPROG) cbe $*.poolalloc $(HIDEDIFF) -# This rule diffs the post-poolallocated version to make sure we didn't break -# the program! +$(PROGRAMS_TO_TEST:%=Output/%.allnodes.diff-cbe): \ +Output/%.allnodes.diff-cbe: Output/%.out-nat Output/%.allnodes.out-cbe + @cp Output/$*.out-nat Output/$*.allnodes.out-nat + -$(DIFFPROG) cbe $*.allnodes $(HIDEDIFF) + $(PROGRAMS_TO_TEST:%=Output/%.mallocrepl.diff-cbe): \ Output/%.mallocrepl.diff-cbe: Output/%.out-nat Output/%.mallocrepl.out-cbe @cp Output/$*.out-nat Output/$*.mallocrepl.out-nat -$(DIFFPROG) cbe $*.mallocrepl $(HIDEDIFF) -# This rule diffs the post-poolallocated version to make sure we didn't break -# the program! $(PROGRAMS_TO_TEST:%=Output/%.onlyoverhead.diff-cbe): \ Output/%.onlyoverhead.diff-cbe: Output/%.out-nat Output/%.onlyoverhead.out-cbe @cp Output/$*.out-nat Output/$*.onlyoverhead.out-nat -$(DIFFPROG) cbe $*.onlyoverhead $(HIDEDIFF) -# This rule diffs the post-nonpa version to make sure we didn't break the -# program! $(PROGRAMS_TO_TEST:%=Output/%.nonpa.diff-cbe): \ Output/%.nonpa.diff-cbe: Output/%.out-nat Output/%.nonpa.out-cbe @cp Output/$*.out-nat Output/$*.nonpa.out-nat @@ -211,7 +215,8 @@ $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ Output/%.$(TEST).report.txt: Output/%.nonpa.diff-cbe \ Output/%.poolalloc.diff-cbe \ - Output/%.mallocrepl.diff-cbe \ + Output/%.allnodes.diff-cbe \ + Output/%.mallocrepl.diff-cbe \ Output/%.onlyoverhead.diff-cbe \ Output/%.LOC.txt @echo > $@ @@ -225,14 +230,17 @@ printf "CBE-RUN-TIME-ONLYOVERHEAD: " >> $@;\ grep "^program" Output/$*.onlyoverhead.out-cbe.time >> $@;\ \ + printf "CBE-RUN-TIME-ALLNODES: " >> $@;\ + grep "^program" Output/$*.allnodes.out-cbe.time >> $@;\ + \ printf "CBE-RUN-TIME-POOLALLOC: " >> $@;\ grep "^program" Output/$*.poolalloc.out-cbe.time >> $@;\ printf "LOC: " >> $@;\ cat Output/$*.LOC.txt >> $@;\ fi - @cat Output/$*.$(TEST).poolalloc.bc.info >> $@ - @#cat Output/$*.$(TEST).poolalloc.bc.out >> $@ + @cat Output/$*.$(TEST).allnodes.bc.info >> $@ + @#cat Output/$*.$(TEST).allnodes.bc.out >> $@ $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ Index: poolalloc/test/TEST.poolalloc.report diff -u poolalloc/test/TEST.poolalloc.report:1.22 poolalloc/test/TEST.poolalloc.report:1.23 --- poolalloc/test/TEST.poolalloc.report:1.22 Sun Nov 7 16:14:00 2004 +++ poolalloc/test/TEST.poolalloc.report Mon Nov 8 00:58:16 2004 @@ -31,7 +31,6 @@ @LatexColumns = (1, 5, 8, 12, 9, 13, 14, 15, 2, 16); -my $OLDEN = 'MultiSource/Benchmarks/Olden'; my $FREEBENCH = 'MultiSource/Benchmarks/FreeBench'; my $PTRDIST = 'MultiSource/Benchmarks/Ptrdist'; @@ -77,6 +76,9 @@ ["PA Time", 'CBE-RUN-TIME-POOLALLOC: program\s*([.0-9m:]+)', \&FormatTime], ["PA run%", \&RuntimePercent], [], + ["AllNodes", 'CBE-RUN-TIME-ALLNODES: program\s*([.0-9m:]+)', \&FormatTime], + ["AN run%", \&RuntimePercent], + [], ["NumPools", '([0-9]+).*Number of pools allocated'], ["Typesafe", '([0-9]+).*Number of typesafe pools'], ["NumArgs", '([0-9]+).*Number of function arguments added'], From alkis at cs.uiuc.edu Mon Nov 8 02:00:50 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 8 Nov 2004 02:00:50 -0600 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/Bytecode.h Message-ID: <200411080800.CAA03380@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: Bytecode.h updated: 1.12 -> 1.13 --- Log message: Fix pad skipping. Make short and int reads not depends on the order of evaluation of |. --- Diffs of the changes: (+7 -6) Index: llvm-java/include/llvm/Java/Bytecode.h diff -u llvm-java/include/llvm/Java/Bytecode.h:1.12 llvm-java/include/llvm/Java/Bytecode.h:1.13 --- llvm-java/include/llvm/Java/Bytecode.h:1.12 Mon Oct 11 16:51:24 2004 +++ llvm-java/include/llvm/Java/Bytecode.h Mon Nov 8 02:00:40 2004 @@ -14,9 +14,6 @@ #ifndef LLVM_JAVA_BYTECODE_H #define LLVM_JAVA_BYTECODE_H -#include -#include - #include namespace llvm { namespace Java { @@ -249,15 +246,18 @@ } inline int readSShort(const uint8_t* code, unsigned& i) { - return (readSByte(code, i) << 8) | readUByte(code, i); + int val = readSByte(code, i) << 8; + return val | readUByte(code, i); } inline unsigned readUShort(const uint8_t* code, unsigned& i) { - return (readUByte(code, i) << 8) | readUByte(code, i); + unsigned val = readUByte(code, i) << 8; + return val | readUByte(code, i); } inline int readSInt(const uint8_t* code, unsigned& i) { - return (readUShort(code, i) << 16) | readUShort(code, i); + int val = readUShort(code, i) << 16; + return val | readUShort(code, i); } inline unsigned readUInt(const uint8_t* code, unsigned& i) { @@ -265,6 +265,7 @@ } inline void skipPadBytes(unsigned& i) { + ++i; unsigned lastTwoBits = i & 0x3; i += (4 - lastTwoBits) & 0x3; --i; From alkis at cs.uiuc.edu Mon Nov 8 02:04:38 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 8 Nov 2004 02:04:38 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200411080804.CAA03475@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.142 -> 1.143 --- Log message: Handle the case where a static method defined on the Base class is called through a reference to a Derived. --- Diffs of the changes: (+28 -21) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.142 llvm-java/lib/Compiler/Compiler.cpp:1.143 --- llvm-java/lib/Compiler/Compiler.cpp:1.142 Sun Nov 7 03:47:03 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Mon Nov 8 02:04:27 2004 @@ -1089,6 +1089,7 @@ cf_ = method->getParent(); Function* function = getFunction(method); + assert(function->empty() && "Compiling an already compiled method!"); if (method->isNative()) { DEBUG(std::cerr << "Ignoring native method: "; @@ -1250,6 +1251,14 @@ return function; } + /// Returns the llvm::Java::Method given a + /// llvm::Java::ClassMethodRef. + Method* getMethod(ConstantMethodRef* methodRef) { + return getMethod(methodRef->getClass()->getName()->str() + '/' + + methodRef->getNameAndType()->getName()->str() + + methodRef->getNameAndType()->getDescriptor()->str()); + } + /// Returns the llvm::Java::Method given a /// descriptor. Method* getMethod(const std::string& classMethodDesc) { @@ -1257,15 +1266,22 @@ std::string className = classMethodDesc.substr(0, slash); std::string methodNameAndDescr = classMethodDesc.substr(slash+1); - ClassFile* classfile = ClassFile::get(className); - emitStaticInitializers(classfile); - Method* method = classfile->getMethod(methodNameAndDescr); - - if (!method) - throw InvocationTargetException("Method " + methodNameAndDescr + - " not found in class " + className); + while (true) { + ClassFile* classfile = ClassFile::get(className); + emitStaticInitializers(classfile); + + Method* method = classfile->getMethod(methodNameAndDescr); + if (method) + return method; + + if (!classfile->getSuperClass()) + break; + + className = classfile->getSuperClass()->getName()->str(); + } - return method; + throw InvocationTargetException("Method " + methodNameAndDescr + + " not found in class " + className); } public: @@ -1829,7 +1845,7 @@ } } - std::vector getParams(FunctionType* funTy) { + std::vector getParams(const FunctionType* funTy) { unsigned numParams = funTy->getNumParams(); std::vector params(numParams); while (numParams--) { @@ -1959,19 +1975,10 @@ } void do_invokestatic(unsigned index) { - ConstantMethodRef* methodRef = cf_->getConstantMethodRef(index); - ConstantNameAndType* nameAndType = methodRef->getNameAndType(); - - std::string funcName = - methodRef->getClass()->getName()->str() + '/' + - nameAndType->getName()->str() + - nameAndType->getDescriptor()->str(); - - FunctionType* funcTy = - cast(getType(nameAndType->getDescriptor())); - Function* function = module_.getOrInsertFunction(funcName, funcTy); + Method* method = getMethod(cf_->getConstantMethodRef(index)); + Function* function = getFunction(method); toCompileFunctions_.insert(function); - makeCall(function, getParams(funcTy)); + makeCall(function, getParams(function->getFunctionType())); } void do_invokeinterface(unsigned index) { From reid at x10sys.com Mon Nov 8 02:28:01 2004 From: reid at x10sys.com (Reid Spencer) Date: Mon, 8 Nov 2004 02:28:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/FreeBSD/Path.cpp Message-ID: <200411080828.CAA03653@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/FreeBSD: Path.cpp updated: 1.3 -> 1.4 --- Log message: Fix a typo: isvalid -> isValid --- Diffs of the changes: (+1 -1) Index: llvm/lib/System/FreeBSD/Path.cpp diff -u llvm/lib/System/FreeBSD/Path.cpp:1.3 llvm/lib/System/FreeBSD/Path.cpp:1.4 --- llvm/lib/System/FreeBSD/Path.cpp:1.3 Fri Nov 5 16:15:35 2004 +++ llvm/lib/System/FreeBSD/Path.cpp Mon Nov 8 02:27:51 2004 @@ -23,7 +23,7 @@ using namespace sys; bool -Path::isvalid() const { +Path::isValid() const { if (path.empty()) return false; char pathname[MAXPATHLEN]; From reid at x10sys.com Mon Nov 8 02:55:32 2004 From: reid at x10sys.com (Reid Spencer) Date: Mon, 8 Nov 2004 02:55:32 -0600 Subject: [llvm-commits] CVS: llvm/docs/BytecodeFormat.html Message-ID: <200411080855.CAA03799@zion.cs.uiuc.edu> Changes in directory llvm/docs: BytecodeFormat.html updated: 1.34 -> 1.35 --- Log message: Document compressed bytecode details. --- Diffs of the changes: (+29 -2) Index: llvm/docs/BytecodeFormat.html diff -u llvm/docs/BytecodeFormat.html:1.34 llvm/docs/BytecodeFormat.html:1.35 --- llvm/docs/BytecodeFormat.html:1.34 Sat Nov 6 18:59:57 2004 +++ llvm/docs/BytecodeFormat.html Mon Nov 8 02:55:21 2004 @@ -580,30 +580,57 @@ other blocks because there is no identifier and no block length at the start of the block. Essentially, this block is just the "magic number" for the file.

+

There are two types of signatures for LLVM bytecode: uncompressed and +compressed as shown in the table below.

- + + + + + + + + + + +
TypeField DescriptionUncompressedCompressed
char Constant "l" (0x6C)Constant "l" (0x6C)
char Constant "l" (0x6C)Constant "l" (0x6C)
char Constant "v" (0x76)Constant "v" (0x76)
char Constant "m" (0x6D)Constant "c" (0x63)
charN/A'0'=null,'1'=gzip,'2'=bzip2
+

In other words, the uncompressed signature is just the characters 'llvm' +while the compressed signature is the characters 'llvc' followed by an ascii +digit ('0', '1', or '2') that indicates the kind of compression used. A value of +'0' indicates that null compression was used. This can happen when compression +was requested on a platform that wasn't configured for gzip or bzip2. A value of +'1' means that the rest of the file is compressed using the gzip algorithm and +should be uncompressed before interpretation. A value of '2' means that the rest +of the file is compressed using the bzip2 algorithm and should be uncompressed +before interpretation. In all cases, the data resulting from uncompression +should be interpreted as if it occurred immediately after the 'llvm' +signature (i.e. the uncompressed data begins with the +Module Block

+

NOTE: As of LLVM 1.4, all bytecode files produced by the LLVM tools +are compressed byte default. To disable compression, pass the +--disable-compression option to the tool, if it supports it.

@@ -1865,7 +1892,7 @@ Reid Spencer and Chris Lattner
The LLVM Compiler Infrastructure
-Last modified: $Date: 2004/11/07 00:59:57 $ +Last modified: $Date: 2004/11/08 08:55:21 $ From reid at x10sys.com Mon Nov 8 03:11:01 2004 From: reid at x10sys.com (Reid Spencer) Date: Mon, 8 Nov 2004 03:11:01 -0600 Subject: [llvm-commits] CVS: llvm/docs/BytecodeFormat.html Message-ID: <200411080911.DAA22311@zion.cs.uiuc.edu> Changes in directory llvm/docs: BytecodeFormat.html updated: 1.35 -> 1.36 --- Log message: Fix typo. --- Diffs of the changes: (+2 -2) Index: llvm/docs/BytecodeFormat.html diff -u llvm/docs/BytecodeFormat.html:1.35 llvm/docs/BytecodeFormat.html:1.36 --- llvm/docs/BytecodeFormat.html:1.35 Mon Nov 8 02:55:21 2004 +++ llvm/docs/BytecodeFormat.html Mon Nov 8 03:10:50 2004 @@ -629,7 +629,7 @@ signature (i.e. the uncompressed data begins with the Module Block

NOTE: As of LLVM 1.4, all bytecode files produced by the LLVM tools -are compressed byte default. To disable compression, pass the +are compressed by default. To disable compression, pass the --disable-compression option to the tool, if it supports it. @@ -1892,7 +1892,7 @@ Reid Spencer and Chris Lattner
The LLVM Compiler Infrastructure
-Last modified: $Date: 2004/11/08 08:55:21 $ +Last modified: $Date: 2004/11/08 09:10:50 $ From reid at x10sys.com Mon Nov 8 11:32:22 2004 From: reid at x10sys.com (Reid Spencer) Date: Mon, 8 Nov 2004 11:32:22 -0600 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200411081732.LAA09431@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.232 -> 1.233 --- Log message: Implement and document the TOOL_VERBOSE option that asks each tool invoked to be verbose about its actions too. --- Diffs of the changes: (+9 -1) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.232 llvm/Makefile.rules:1.233 --- llvm/Makefile.rules:1.232 Tue Nov 2 10:56:15 2004 +++ llvm/Makefile.rules Mon Nov 8 11:32:11 2004 @@ -222,6 +222,14 @@ LD.Flags += -rpath $(LibDir) endif +ifdef TOOL_VERBOSE + C.Flags += -v + CXX.Flags += -v + LD.Flags += -v + BCLinkLib.Flags += -v + VERBOSE := 1 +endif + # Adjust settings for verbose mode ifndef VERBOSE Verb := @ @@ -268,7 +276,7 @@ $(CompileCommonOpts) $(LD.Flags) $(Strip) Relink = $(LIBTOOL) $(LibTool.Flags) --mode=link $(CXX) $(CPP.Flags) \ $(CompileCommonOpts) -BCLinkLib = $(LLVMGCC) -shared -nostdlib +BCLinkLib = $(LLVMGCC) -shared -nostdlib $(BCLinkLib.Flags) LTInstall = $(LIBTOOL) $(LibTool.Flags) --mode=install $(INSTALL) Burg = $(BURG) -I $(BUILD_SRC_DIR) TableGen = $(TBLGEN) -I $(BUILD_SRC_DIR) From reid at x10sys.com Mon Nov 8 11:32:23 2004 From: reid at x10sys.com (Reid Spencer) Date: Mon, 8 Nov 2004 11:32:23 -0600 Subject: [llvm-commits] CVS: llvm/docs/MakefileGuide.html Message-ID: <200411081732.LAA09434@zion.cs.uiuc.edu> Changes in directory llvm/docs: MakefileGuide.html updated: 1.11 -> 1.12 --- Log message: Implement and document the TOOL_VERBOSE option that asks each tool invoked to be verbose about its actions too. --- Diffs of the changes: (+7 -1) Index: llvm/docs/MakefileGuide.html diff -u llvm/docs/MakefileGuide.html:1.11 llvm/docs/MakefileGuide.html:1.12 --- llvm/docs/MakefileGuide.html:1.11 Sun Nov 7 16:42:37 2004 +++ llvm/docs/MakefileGuide.html Mon Nov 8 11:32:12 2004 @@ -563,6 +563,12 @@

TOOLNAME
Specifies the name of the tool that the current directory should build.
+
TOOL_VERBOSE
+
Implies VERBOSE and also tells each tool invoked to be verbose. This is + handy when you're trying to see the sub-tools invoked by each tool invoked + by the makefile. For example, this will pass -v to the GCC + compilers which causes it to print out the command lines it uses to invoke + sub-tools (compiler, assembler, linker).
USEDLIBS
Specifies the list of project libraries that will be linked into the tool or library.
@@ -847,7 +853,7 @@ Reid Spencer
The LLVM Compiler Infrastructure
- Last modified: $Date: 2004/11/07 22:42:37 $ + Last modified: $Date: 2004/11/08 17:32:12 $ From reid at x10sys.com Mon Nov 8 11:35:45 2004 From: reid at x10sys.com (Reid Spencer) Date: Mon, 8 Nov 2004 11:35:45 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Bytecode/WriteBytecodePass.h Message-ID: <200411081735.LAA09482@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Bytecode: WriteBytecodePass.h updated: 1.12 -> 1.13 --- Log message: Make writing compressed bytecode the default. --- Diffs of the changes: (+1 -1) Index: llvm/include/llvm/Bytecode/WriteBytecodePass.h diff -u llvm/include/llvm/Bytecode/WriteBytecodePass.h:1.12 llvm/include/llvm/Bytecode/WriteBytecodePass.h:1.13 --- llvm/include/llvm/Bytecode/WriteBytecodePass.h:1.12 Sat Nov 6 23:30:43 2004 +++ llvm/include/llvm/Bytecode/WriteBytecodePass.h Mon Nov 8 11:35:34 2004 @@ -28,7 +28,7 @@ public: WriteBytecodePass() : Out(&std::cout), DeleteStream(false), CompressFile(true) {} - WriteBytecodePass(std::ostream *o, bool DS = false, bool CF = false ) + WriteBytecodePass(std::ostream *o, bool DS = false, bool CF = true ) : Out(o), DeleteStream(DS), CompressFile(CF) {} inline ~WriteBytecodePass() { From reid at x10sys.com Mon Nov 8 11:37:14 2004 From: reid at x10sys.com (Reid Spencer) Date: Mon, 8 Nov 2004 11:37:14 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccas/gccas.cpp Message-ID: <200411081737.LAA09512@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccas: gccas.cpp updated: 1.101 -> 1.102 --- Log message: Add a --disable-compression option to gccas so the default compression of bytecode can be defeated. --- Diffs of the changes: (+4 -1) Index: llvm/tools/gccas/gccas.cpp diff -u llvm/tools/gccas/gccas.cpp:1.101 llvm/tools/gccas/gccas.cpp:1.102 --- llvm/tools/gccas/gccas.cpp:1.101 Wed Oct 6 23:11:26 2004 +++ llvm/tools/gccas/gccas.cpp Mon Nov 8 11:37:04 2004 @@ -49,6 +49,9 @@ cl::opt DisableDSE("disable-dse", cl::desc("Do not run dead store elimination")); + cl::opt + NoCompress("disable-compression", cl::init(false), + cl::desc("Don't ompress the generated bytecode")); } @@ -182,7 +185,7 @@ Passes.add(createVerifierPass()); // Write bytecode to file... - Passes.add(new WriteBytecodePass(Out)); + Passes.add(new WriteBytecodePass(Out,false,!NoCompress)); // Run our queue of passes all at once now, efficiently. Passes.run(*M.get()); From lattner at cs.uiuc.edu Mon Nov 8 12:46:23 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 Nov 2004 12:46:23 -0600 Subject: [llvm-commits] CVS: llvm/win32/Transforms/Transforms.vcproj Message-ID: <200411081846.iA8IkNmx031890@apoc.cs.uiuc.edu> Changes in directory llvm/win32/Transforms: Transforms.vcproj updated: 1.2 -> 1.3 --- Log message: This file is gone --- Diffs of the changes: (+0 -3) Index: llvm/win32/Transforms/Transforms.vcproj diff -u llvm/win32/Transforms/Transforms.vcproj:1.2 llvm/win32/Transforms/Transforms.vcproj:1.3 --- llvm/win32/Transforms/Transforms.vcproj:1.2 Sat Nov 6 11:07:36 2004 +++ llvm/win32/Transforms/Transforms.vcproj Mon Nov 8 12:46:09 2004 @@ -251,9 +251,6 @@ RelativePath="..\..\lib\Transforms\Scalar\DeadStoreElimination.cpp"> - - Changes in directory poolalloc/test: TEST.poolalloc.Makefile updated: 1.31 -> 1.32 --- Log message: only elide numbers for configurations that are broken --- Diffs of the changes: (+11 -8) Index: poolalloc/test/TEST.poolalloc.Makefile diff -u poolalloc/test/TEST.poolalloc.Makefile:1.31 poolalloc/test/TEST.poolalloc.Makefile:1.32 --- poolalloc/test/TEST.poolalloc.Makefile:1.31 Mon Nov 8 00:58:16 2004 +++ poolalloc/test/TEST.poolalloc.Makefile Mon Nov 8 12:54:40 2004 @@ -220,25 +220,28 @@ Output/%.onlyoverhead.diff-cbe \ Output/%.LOC.txt @echo > $@ - @-if test -f Output/$*.poolalloc.diff-cbe; then \ + @-if test -f Output/$*.nonpa.diff-cbe; then \ printf "CBE-RUN-TIME-NORMAL: " >> $@;\ grep "^program" Output/$*.nonpa.out-cbe.time >> $@;\ - \ + fi + @-if test -f Output/$*.mallocrepl.diff-cbe; then \ printf "CBE-RUN-TIME-MALLOCREPL: " >> $@;\ grep "^program" Output/$*.mallocrepl.out-cbe.time >> $@;\ - \ + fi + @-if test -f Output/$*.onlyoverhead.diff-cbe; then \ printf "CBE-RUN-TIME-ONLYOVERHEAD: " >> $@;\ grep "^program" Output/$*.onlyoverhead.out-cbe.time >> $@;\ - \ + fi + @-if test -f Output/$*.allnodes.diff-cbe; then \ printf "CBE-RUN-TIME-ALLNODES: " >> $@;\ grep "^program" Output/$*.allnodes.out-cbe.time >> $@;\ - \ + fi + @-if test -f Output/$*.poolalloc.diff-cbe; then \ printf "CBE-RUN-TIME-POOLALLOC: " >> $@;\ grep "^program" Output/$*.poolalloc.out-cbe.time >> $@;\ - printf "LOC: " >> $@;\ - cat Output/$*.LOC.txt >> $@;\ fi - + printf "LOC: " >> $@ + cat Output/$*.LOC.txt >> $@ @cat Output/$*.$(TEST).allnodes.bc.info >> $@ @#cat Output/$*.$(TEST).allnodes.bc.out >> $@ From brukman at cs.uiuc.edu Mon Nov 8 13:01:14 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon, 8 Nov 2004 13:01:14 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Bytecode/WriteBytecodePass.h Message-ID: <200411081901.NAA29763@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Bytecode: WriteBytecodePass.h updated: 1.13 -> 1.14 --- Log message: Remove extra spaces --- Diffs of the changes: (+2 -2) Index: llvm/include/llvm/Bytecode/WriteBytecodePass.h diff -u llvm/include/llvm/Bytecode/WriteBytecodePass.h:1.13 llvm/include/llvm/Bytecode/WriteBytecodePass.h:1.14 --- llvm/include/llvm/Bytecode/WriteBytecodePass.h:1.13 Mon Nov 8 11:35:34 2004 +++ llvm/include/llvm/Bytecode/WriteBytecodePass.h Mon Nov 8 13:01:03 2004 @@ -28,8 +28,8 @@ public: WriteBytecodePass() : Out(&std::cout), DeleteStream(false), CompressFile(true) {} - WriteBytecodePass(std::ostream *o, bool DS = false, bool CF = true ) - : Out(o), DeleteStream(DS), CompressFile(CF) {} + WriteBytecodePass(std::ostream *o, bool DS = false, bool CF = true) + : Out(o), DeleteStream(DS), CompressFile(CF) {} inline ~WriteBytecodePass() { if (DeleteStream) delete Out; From gaeke at cs.uiuc.edu Mon Nov 8 14:59:50 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon, 8 Nov 2004 14:59:50 -0600 (CST) Subject: [llvm-commits] CVS: reopt/include/reopt/TraceJIT.h Message-ID: <200411082059.OAA01880@kain.cs.uiuc.edu> Changes in directory reopt/include/reopt: TraceJIT.h updated: 1.3 -> 1.4 --- Log message: Add freeMachineCodeForFunction to the TraceJIT, which does nothing, just like the real JIT's version. --- Diffs of the changes: (+6 -0) Index: reopt/include/reopt/TraceJIT.h diff -u reopt/include/reopt/TraceJIT.h:1.3 reopt/include/reopt/TraceJIT.h:1.4 --- reopt/include/reopt/TraceJIT.h:1.3 Fri Sep 24 16:22:39 2004 +++ reopt/include/reopt/TraceJIT.h Mon Nov 8 14:59:38 2004 @@ -94,6 +94,12 @@ /// void *recompileAndRelinkFunction(Function *F); + + /// freeMachineCodeForFunction - release machine code memory for + /// given Function + /// + void freeMachineCodeForFunction(Function *F); + uint64_t compileTraceFunction (TraceFunction *TF); MachineCodeEmitter *getEmitter() { return MCE; } From gaeke at cs.uiuc.edu Mon Nov 8 14:59:50 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon, 8 Nov 2004 14:59:50 -0600 (CST) Subject: [llvm-commits] CVS: reopt/tools/ttftest/ttftest.cpp Message-ID: <200411082059.OAA01882@kain.cs.uiuc.edu> Changes in directory reopt/tools/ttftest: ttftest.cpp updated: 1.9 -> 1.10 --- Log message: Add an option to print out the # of uses of each arg (live-in or live-out). This makes it easy to find dead args that we're generating. --- Diffs of the changes: (+15 -0) Index: reopt/tools/ttftest/ttftest.cpp diff -u reopt/tools/ttftest/ttftest.cpp:1.9 reopt/tools/ttftest/ttftest.cpp:1.10 --- reopt/tools/ttftest/ttftest.cpp:1.9 Thu Sep 2 11:55:46 2004 +++ reopt/tools/ttftest/ttftest.cpp Mon Nov 8 14:59:40 2004 @@ -36,6 +36,8 @@ cl::opt PrintLiveSets("print-live", cl::desc("Print live-in/out sets to stdout"), cl::init(false)); cl::opt Quiet("q", cl::desc("Be quiet"), cl::init(false)); + cl::opt PrintArgUses("print-arguses", + cl::desc("Print # uses of each arg"), cl::init(false)); }; void printLiveSet (std::ostream &OS, const std::string Banner, @@ -72,6 +74,16 @@ printLiveSet (std::cout, "Live-out set:\n", TF->LiveOutVector, TF); } +void printArgUses (TraceFunction *TF) { + unsigned acount = 0; + for (Function::aiterator i = TF->TraceFn->abegin (), e = TF->TraceFn->aend (); + i != e; ++i) { + Argument &a (*i); + std::cout << "Argument #" << acount << " (" << a << ") has " << a.use_size() << " uses\n"; + ++acount; + } +} + int main (int argc, char **argv) { // Get command line arguments. cl::ParseCommandLineOptions(argc, argv, " trace-to-function tester\n"); @@ -110,5 +122,8 @@ if (PrintLiveSets) printLiveSets (TF); + if (PrintArgUses) + printArgUses (TF); + return 0; } From gaeke at cs.uiuc.edu Mon Nov 8 14:59:51 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon, 8 Nov 2004 14:59:51 -0600 (CST) Subject: [llvm-commits] CVS: reopt/lib/TraceJIT/TraceJIT.cpp Message-ID: <200411082059.OAA01888@kain.cs.uiuc.edu> Changes in directory reopt/lib/TraceJIT: TraceJIT.cpp updated: 1.7 -> 1.8 --- Log message: Add freeMachineCodeForFunction to the TraceJIT, which does nothing, just like the real JIT's version. --- Diffs of the changes: (+6 -0) Index: reopt/lib/TraceJIT/TraceJIT.cpp diff -u reopt/lib/TraceJIT/TraceJIT.cpp:1.7 reopt/lib/TraceJIT/TraceJIT.cpp:1.8 --- reopt/lib/TraceJIT/TraceJIT.cpp:1.7 Thu Sep 2 11:55:45 2004 +++ reopt/lib/TraceJIT/TraceJIT.cpp Mon Nov 8 14:59:39 2004 @@ -242,6 +242,12 @@ return Addr; } +/// freeMachineCodeForFunction - release machine code memory for given Function +/// +void TraceJIT::freeMachineCodeForFunction(Function *F) { + // currently a no-op +} + /// create - Create and return a new TraceJIT compiler, or 0 if /// there is an error. /// From criswell at cs.uiuc.edu Mon Nov 8 15:06:38 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 8 Nov 2004 15:06:38 -0600 Subject: [llvm-commits] CVS: llvm-test/GenerateReport.pl Message-ID: <200411082106.PAA01549@choi.cs.uiuc.edu> Changes in directory llvm-test: GenerateReport.pl updated: 1.23 -> 1.24 --- Log message: Add a comment about the -csv option. --- Diffs of the changes: (+1 -1) Index: llvm-test/GenerateReport.pl diff -u llvm-test/GenerateReport.pl:1.23 llvm-test/GenerateReport.pl:1.24 --- llvm-test/GenerateReport.pl:1.23 Wed Nov 3 15:57:44 2004 +++ llvm-test/GenerateReport.pl Mon Nov 8 15:06:21 2004 @@ -11,7 +11,7 @@ # and descriptions for the columns of interest. In reads the raw log # input from stdin and writes the table to stdout. # -# Syntax: GenerateReport.pl [-html] [-latex] [-graphs] +# Syntax: GenerateReport.pl [-html] [-latex] [-graphs] [-csv] # < Input > Output # From lattner at cs.uiuc.edu Mon Nov 8 15:09:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 Nov 2004 15:09:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Message-ID: <200411082109.iA8L90wK001989@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.83 -> 1.84 --- Log message: Fix a bug that was preventing povray and namd from pool allocating correctly. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.83 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.84 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.83 Sun Oct 31 15:54:51 2004 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Mon Nov 8 15:08:46 2004 @@ -205,7 +205,7 @@ } // Clean up the graph before we start inlining a bunch again... - SCCGraph->removeDeadNodes(DSGraph::RemoveUnreachableGlobals); + SCCGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals); // Now that we have one big happy family, resolve all of the call sites in // the graph... From lattner at cs.uiuc.edu Mon Nov 8 15:09:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 Nov 2004 15:09:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Local.cpp Message-ID: <200411082109.iA8L9B2o001995@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Local.cpp updated: 1.117 -> 1.118 --- Log message: Handle assert_fail special --- Diffs of the changes: (+7 -0) Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.117 llvm/lib/Analysis/DataStructure/Local.cpp:1.118 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.117 Wed Nov 3 12:51:26 2004 +++ llvm/lib/Analysis/DataStructure/Local.cpp Mon Nov 8 15:08:28 2004 @@ -888,6 +888,13 @@ if (DSNode *N = H.getNode()) N->setReadMarker(); return; + } else if (F->getName() == "__assert_fail") { + for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end(); + AI != E; ++AI) + if (isPointerType((*AI)->getType())) + if (DSNode *N = getValueDest(**AI).getNode()) + N->setReadMarker(); + return; } else if (F->getName() == "modf" && CS.arg_end()-CS.arg_begin() == 2) { // This writes its second argument, and forces it to double. DSNodeHandle H = getValueDest(**--CS.arg_end()); From gaeke at cs.uiuc.edu Mon Nov 8 15:28:28 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon, 8 Nov 2004 15:28:28 -0600 (CST) Subject: [llvm-commits] CVS: reopt/lib/WholeReoptimizer/Makefile Message-ID: <200411082128.PAA03624@kain.cs.uiuc.edu> Changes in directory reopt/lib/WholeReoptimizer: Makefile updated: 1.5 -> 1.6 --- Log message: Unbreak this makefile again...many variables seem to have changed names --- Diffs of the changes: (+22 -24) Index: reopt/lib/WholeReoptimizer/Makefile diff -u reopt/lib/WholeReoptimizer/Makefile:1.5 reopt/lib/WholeReoptimizer/Makefile:1.6 --- reopt/lib/WholeReoptimizer/Makefile:1.5 Thu Oct 28 11:14:27 2004 +++ reopt/lib/WholeReoptimizer/Makefile Mon Nov 8 15:28:17 2004 @@ -2,38 +2,36 @@ include $(LEVEL)/Makefile.common -REOPTLIBDIR = $(BUILD_OBJ_ROOT)/lib/$(CONFIGURATION) - -REOPTIMIZER_OBJS = $(REOPTLIBDIR)/firstTrigger.o \ - $(REOPTLIBDIR)/tracecache.o $(REOPTLIBDIR)/mapinfo.o \ - $(REOPTLIBDIR)/scratchmemory.o $(REOPTLIBDIR)/tracetofunction.o \ - $(REOPTLIBDIR)/tracejit.o $(REOPTLIBDIR)/traceio.o +REOPTIMIZER_OBJS = $(LibDir)/firstTrigger.o \ + $(LibDir)/tracecache.o $(LibDir)/mapinfo.o \ + $(LibDir)/scratchmemory.o $(LibDir)/tracetofunction.o \ + $(LibDir)/tracejit.o $(LibDir)/traceio.o # Object files that contain common LLVM code the Reoptimizer depends on -REOPTIMIZER_LLVMOBJS = $(LLVMLIBDIR)/LLVMCore.o $(LLVMLIBDIR)/LLVMBCReader.o \ - $(LLVMLIBDIR)/LLVMBCWriter.o $(LLVMLIBDIR)/LLVMSparcV9.o \ - $(LLVMLIBDIR)/LLVMSparcV9LiveVar.o $(LLVMLIBDIR)/LLVMSparcV9InstrSched.o \ - $(LLVMLIBDIR)/LLVMCodeGen.o $(LLVMLIBDIR)/LLVMExecutionEngine.o \ - $(LLVMLIBDIR)/LLVMJIT.o $(LLVMLIBDIR)/LLVMInterpreter.o +REOPTIMIZER_LLVMOBJS = $(LLVMLibDir)/LLVMCore.o $(LLVMLibDir)/LLVMBCReader.o \ + $(LLVMLibDir)/LLVMBCWriter.o $(LLVMLibDir)/LLVMSparcV9.o \ + $(LLVMLibDir)/LLVMSparcV9LiveVar.o $(LLVMLibDir)/LLVMSparcV9InstrSched.o \ + $(LLVMLibDir)/LLVMCodeGen.o $(LLVMLibDir)/LLVMExecutionEngine.o \ + $(LLVMLibDir)/LLVMJIT.o $(LLVMLibDir)/LLVMInterpreter.o # Library archive files that contain common LLVM code the Reoptimizer depends on -REOPTIMIZER_LLVMLIBS = $(LLVMLIBDIR)/libLLVMSparcV9RegAlloc.a \ - $(LLVMLIBDIR)/libLLVMTarget.a $(LLVMLIBDIR)/libLLVMScalarOpts.a \ - $(LLVMLIBDIR)/libLLVMTransformUtils.a $(LLVMLIBDIR)/libLLVMAnalysis.a \ - $(LLVMLIBDIR)/libLLVMSupport.a $(LLVMLIBDIR)/libLLVMSystem.a +REOPTIMIZER_LLVMLIBS = $(LLVMLibDir)/libLLVMSparcV9RegAlloc.a \ + $(LLVMLibDir)/libLLVMTarget.a $(LLVMLibDir)/libLLVMScalarOpts.a \ + $(LLVMLibDir)/libLLVMTransformUtils.a $(LLVMLibDir)/libLLVMAnalysis.a \ + $(LLVMLibDir)/libLLVMSupport.a $(LLVMLibDir)/libLLVMSystem.a -WHOLE_REOPTIMIZER_LIB = $(BUILD_OBJ_ROOT)/lib/$(CONFIGURATION)/libwholereoptimizer.a +WHOLE_REOPTIMIZER_LIB = $(LibDir)/libwholereoptimizer.a all:: $(WHOLE_REOPTIMIZER_LIB) $(WHOLE_REOPTIMIZER_LIB): $(REOPTIMIZER_OBJS) $(REOPTIMIZER_LLVMOBJS) $(REOPTIMIZER_LLVMLIBS) - $(VERB) rm -f $@ - @$(ECHO) "Building $(WHOLE_REOPTIMIZER_LIB)" - @$(ECHO) "Adding reoptimizer .o files to libwholereoptimizer.a" - $(VERB) ar rc $@ $(REOPTIMIZER_OBJS) $(REOPTIMIZER_LLVMOBJS) - $(VERB) @for lib in $(REOPTIMIZER_LLVMLIBS); \ + $(Verb) rm -f $@ + @$(Echo) "Building $(WHOLE_REOPTIMIZER_LIB)" + @$(Echo) "Adding reoptimizer .o files to libwholereoptimizer.a" + $(Verb) ar rc $@ $(REOPTIMIZER_OBJS) $(REOPTIMIZER_LLVMOBJS) + $(Verb) @for lib in $(REOPTIMIZER_LLVMLIBS); \ do \ - $(ECHO) "Adding files from $${lib} to libwholereoptimizer.a"; \ + $(EchoCmd) "Adding files from $${lib} to libwholereoptimizer.a"; \ d=`basename $${lib}`x; \ mkdir $${d}; \ cd $${d}; \ @@ -42,8 +40,8 @@ cd ..; \ rm -rf $${d}; \ done - @$(ECHO) "======= Finished building libwholereoptimizer.a" + @$(Echo) "======= Finished building libwholereoptimizer.a" clean:: - $(VERB) rm -f $(WHOLE_REOPTIMIZER_LIB) + $(Verb) rm -f $(WHOLE_REOPTIMIZER_LIB) From brukman at cs.uiuc.edu Mon Nov 8 16:03:21 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon, 8 Nov 2004 16:03:21 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccld/Linker.cpp Message-ID: <200411082203.QAA28615@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: Linker.cpp updated: 1.28 -> 1.29 --- Log message: Don't silently ignore invalid files: tell the user! --- Diffs of the changes: (+2 -0) Index: llvm/tools/gccld/Linker.cpp diff -u llvm/tools/gccld/Linker.cpp:1.28 llvm/tools/gccld/Linker.cpp:1.29 --- llvm/tools/gccld/Linker.cpp:1.28 Wed Sep 1 17:55:37 2004 +++ llvm/tools/gccld/Linker.cpp Mon Nov 8 16:03:10 2004 @@ -345,6 +345,8 @@ << Pathname << "': " << ErrorMessage << "\n"; return true; } + } else { + std::cerr << "Warning: invalid file `" << Pathname << "' ignored.\n"; } } From brukman at cs.uiuc.edu Mon Nov 8 16:03:43 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon, 8 Nov 2004 16:03:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/FileUtilities.cpp Message-ID: <200411082203.QAA28801@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: FileUtilities.cpp updated: 1.26 -> 1.27 --- Log message: Handle headers for compressed bytecode files --- Diffs of the changes: (+1 -1) Index: llvm/lib/Support/FileUtilities.cpp diff -u llvm/lib/Support/FileUtilities.cpp:1.26 llvm/lib/Support/FileUtilities.cpp:1.27 --- llvm/lib/Support/FileUtilities.cpp:1.26 Sun Sep 19 23:13:43 2004 +++ llvm/lib/Support/FileUtilities.cpp Mon Nov 8 16:03:32 2004 @@ -52,7 +52,7 @@ bool llvm::IsBytecode(const std::string &FN) { // Inspect the beginning of the file to see if it contains the LLVM // bytecode format magic string. - return CheckMagic (FN, "llvm"); + return CheckMagic(FN, "llvm") || CheckMagic(FN, "llvc"); } /// IsSharedObject - Returns trus IFF the file named FN appears to be a shared From criswell at cs.uiuc.edu Mon Nov 8 19:24:10 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 8 Nov 2004 19:24:10 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200411090124.TAA10690@choi.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.140 -> 1.141 --- Log message: Added support for generating CSV files. This should allow us to easily load results into spreadsheets. --- Diffs of the changes: (+6 -1) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.140 llvm-test/Makefile.programs:1.141 --- llvm-test/Makefile.programs:1.140 Sat Nov 6 14:40:57 2004 +++ llvm-test/Makefile.programs Mon Nov 8 19:23:52 2004 @@ -572,6 +572,9 @@ report.$(TEST).tex: report.$(TEST).raw.out $(TestReport) $(GENERATEREPORT) $(GENERATEREPORT) -latex $(TestReport) < $< > $@ +report.$(TEST).csv: report.$(TEST).raw.out $(TestReport) $(GENERATEREPORT) + $(GENERATEREPORT) -csv $(TestReport) < $< > $@ + report.graphs: report.$(TEST).raw.out $(TestReport) $(TestGnuPlot) $(GENERATEREPORT) $(GENERATEREPORT) -graphs $(TestReport) < $< gnuplot $(TestGnuPlot) @@ -581,9 +584,11 @@ report.html: report.$(TEST).html +report.csv: report.$(TEST).csv + report.tex: report.$(TEST).tex @cat $< endif clean:: - rm -f report.*.raw.out report.*.txt report.*.html report.*.tex + rm -f report.*.raw.out report.*.txt report.*.html report.*.tex report.*.csv From criswell at cs.uiuc.edu Mon Nov 8 21:34:00 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 8 Nov 2004 21:34:00 -0600 Subject: [llvm-commits] CVS: poolalloc/test/Makefile TEST.perf.Makefile TEST.perf.report Message-ID: <200411090334.VAA14314@choi.cs.uiuc.edu> Changes in directory poolalloc/test: Makefile updated: 1.24 -> 1.25 TEST.perf.Makefile updated: 1.11 -> 1.12 TEST.perf.report updated: 1.1 -> 1.2 --- Log message: Update the list of automatic tests to match what Chris is using for the current paper. Add runtimes to the list of stuff reported by the perf targets. Create CSV files for cache statistics; it seems getting it to work properly for poolalloc runtimes needs a little bit more work yet. --- Diffs of the changes: (+45 -29) Index: poolalloc/test/Makefile diff -u poolalloc/test/Makefile:1.24 poolalloc/test/Makefile:1.25 --- poolalloc/test/Makefile:1.24 Sat Nov 6 16:33:14 2004 +++ poolalloc/test/Makefile Mon Nov 8 21:33:49 2004 @@ -12,17 +12,21 @@ include $(LEVEL)/Makefile.common LARGE_PROBLEM_SIZE_DIRS := \ - MultiSource/Benchmarks/Olden \ - MultiSource/Benchmarks/FreeBench/analyzer \ - MultiSource/Benchmarks/llubenchmark + MultiSource/Benchmarks/llubenchmark \ + MultiSource/Benchmarks/FreeBench \ + MultiSource/Benchmarks/Ptrdist \ + MultiSource/Benchmarks/MallocBench/cfrac \ + SingleSource/Benchmarks/McGill LARGE_PROBLEM_SIZE_DIRS := \ $(addprefix $(LLVM_OBJ_ROOT)/projects/llvm-test/,$(LARGE_PROBLEM_SIZE_DIRS)) NORMAL_PROBLEM_SIZE_DIRS := \ - MultiSource/Benchmarks/Ptrdist \ + MultiSource/Benchmarks/SciMark2-C/scimark2 \ + External/Povray \ + External/FPGrowth \ + External/Namd \ External/SPEC/CINT2000 - #MultiSource/Benchmarks/MallocBench/cfrac NORMAL_PROBLEM_SIZE_DIRS := \ $(addprefix $(LLVM_OBJ_ROOT)/projects/llvm-test/,$(NORMAL_PROBLEM_SIZE_DIRS)) @@ -58,22 +62,22 @@ for dir in $(LARGE_PROBLEM_SIZE_DIRS); do \ (cd $$dir; \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -j1 TEST=perf \ - LARGE_PROBLEM_SIZE=1 report.html) \ + LARGE_PROBLEM_SIZE=1 report.html report.csv) \ done for dir in $(NORMAL_PROBLEM_SIZE_DIRS); do \ (cd $$dir; \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -j1 TEST=perf \ - report.html) \ + report.html report.csv) \ done @for dir in $(LARGE_PROBLEM_SIZE_DIRS); do \ (cd $$dir; \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -s -j1 TEST=perf \ - LARGE_PROBLEM_SIZE=1 report) \ + LARGE_PROBLEM_SIZE=1 report report.csv) \ done @for dir in $(NORMAL_PROBLEM_SIZE_DIRS); do \ (cd $$dir; \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -s -j1 TEST=perf \ - report) \ + report report.csv) \ done @printf "\a"; sleep 1; printf "\a"; sleep 1; printf "\a" @@ -81,22 +85,22 @@ for dir in $(LARGE_PROBLEM_SIZE_DIRS); do \ (cd $$dir; \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -j1 TEST=p4perf \ - LARGE_PROBLEM_SIZE=1 report.html) \ + LARGE_PROBLEM_SIZE=1 report.html report.csv) \ done for dir in $(NORMAL_PROBLEM_SIZE_DIRS); do \ (cd $$dir; \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -j1 TEST=p4perf \ - report.html) \ + report.html report.csv) \ done @for dir in $(LARGE_PROBLEM_SIZE_DIRS); do \ (cd $$dir; \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -s -j1 TEST=p4perf \ - LARGE_PROBLEM_SIZE=1 report) \ + LARGE_PROBLEM_SIZE=1 report report.csv) \ done @for dir in $(NORMAL_PROBLEM_SIZE_DIRS); do \ (cd $$dir; \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -s -j1 TEST=p4perf \ - report) \ + report report.csv) \ done @printf "\a"; sleep 1; printf "\a"; sleep 1; printf "\a" @@ -104,22 +108,22 @@ for dir in $(LARGE_PROBLEM_SIZE_DIRS); do \ (cd $$dir; \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -j1 TEST=cputrack \ - LARGE_PROBLEM_SIZE=1 report.html) \ + LARGE_PROBLEM_SIZE=1 report.html report.csv) \ done for dir in $(NORMAL_PROBLEM_SIZE_DIRS); do \ (cd $$dir; \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -j1 TEST=cputrack \ - report.html) \ + report.html report.csv) \ done @for dir in $(LARGE_PROBLEM_SIZE_DIRS); do \ (cd $$dir; \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -s -j1 TEST=cputrack \ - LARGE_PROBLEM_SIZE=1 report) \ + LARGE_PROBLEM_SIZE=1 report report.csv) \ done @for dir in $(NORMAL_PROBLEM_SIZE_DIRS); do \ (cd $$dir; \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -s -j1 TEST=cputrack \ - report) \ + report report.csv) \ done @printf "\a"; sleep 1; printf "\a"; sleep 1; printf "\a" @@ -139,19 +143,19 @@ vtl:: (cd $(LLVM_OBJ_ROOT)/projects/llvm-test/$(SUBDIR); \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -j1 TEST=pavtl \ - test report) + test report report.csv) @printf "\a"; sleep 1; printf "\a"; sleep 1; printf "\a" perf:: (cd $(LLVM_OBJ_ROOT)/projects/llvm-test/$(SUBDIR); \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -j1 TEST=perf \ - test report) + test report report.csv) @printf "\a"; sleep 1; printf "\a"; sleep 1; printf "\a" p4perf:: (cd $(LLVM_OBJ_ROOT)/projects/llvm-test/$(SUBDIR); \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -j1 TEST=p4perf \ - test report) + test report report.csv) @printf "\a"; sleep 1; printf "\a"; sleep 1; printf "\a" strace:: @@ -163,6 +167,6 @@ cputrack:: (cd $(LLVM_OBJ_ROOT)/projects/llvm-test/$(SUBDIR); \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -j1 TEST=cputrack \ - report) + report report.csv) @printf "\a"; sleep 1; printf "\a"; sleep 1; printf "\a" Index: poolalloc/test/TEST.perf.Makefile diff -u poolalloc/test/TEST.perf.Makefile:1.11 poolalloc/test/TEST.perf.Makefile:1.12 --- poolalloc/test/TEST.perf.Makefile:1.11 Fri Nov 5 12:08:50 2004 +++ poolalloc/test/TEST.perf.Makefile Mon Nov 8 21:33:50 2004 @@ -167,6 +167,14 @@ @printf "CBE-L1-Cache-Misses: %lld\n" `cat Output/$(TEST).L1Misses.$*` >> $@ @printf "CBE-PA-L2-Cache-Misses: %lld\n" `cat Output/$(TEST).L2Misses.pa.$*` >> $@ @printf "CBE-L2-Cache-Misses: %lld\n" `cat Output/$(TEST).L2Misses.$*` >> $@ + @printf "CBE-RUN-TIME-NORMAL-USER: " >> $@ + @grep "^user" Output/$*.nonpa.out-cbe.time >> $@ + @printf "CBE-RUN-TIME-NORMAL-SYS: " >> $@ + @grep "^sys" Output/$*.nonpa.out-cbe.time >> $@ + @printf "CBE-RUN-TIME-POOLALLOC-USER: " >> $@ + @grep "^user" Output/$*.poolalloc.out-cbe.time >> $@ + @printf "CBE-RUN-TIME-POOLALLOC-SYS: " >> $@ + @grep "^sys" Output/$*.poolalloc.out-cbe.time >> $@ endif ifeq ($(EVENTS),$(P4_EVENTS)) Index: poolalloc/test/TEST.perf.report diff -u poolalloc/test/TEST.perf.report:1.1 poolalloc/test/TEST.perf.report:1.2 --- poolalloc/test/TEST.perf.report:1.1 Thu Mar 4 17:16:18 2004 +++ poolalloc/test/TEST.perf.report Mon Nov 8 21:33:50 2004 @@ -78,15 +78,19 @@ ["Name:" , '\'([^\']+)\' Program'], [], # Times - ["NormalCacheAccess", 'CBE-Cache-Accesses: ([0-9]+)'], - ["NormalCacheMisses", 'CBE-Cache-Misses: ([0-9]+)'], - ["NormalRefillFromL2", 'CBE-L1-Cache-Misses: ([0-9]+)'], - ["NormalRefillFromSystem", 'CBE-L2-Cache-Misses: ([.0-9]+)'], + ["NormUserTime", 'CBE-RUN-TIME-NORMAL-USER: user\s*([.0-9m:]+)', \&FormatTime], + ["NormSysTime", 'CBE-RUN-TIME-NORMAL-SYS: sys\s*([.0-9m:]+)', \&FormatTime], + ["NormCacheAccess", 'CBE-Cache-Accesses: ([0-9]+)'], + ["NormCacheMisses", 'CBE-Cache-Misses: ([0-9]+)'], + ["NormRefillFromL2", 'CBE-L1-Cache-Misses: ([0-9]+)'], + ["NormRefillFromSys", 'CBE-L2-Cache-Misses: ([.0-9]+)'], - ["PoolAllocCacheAccess", 'CBE-PA-Cache-Accesses: ([0-9]+)'], - ["PoolAllocCacheMisses", 'CBE-PA-Cache-Misses: ([0-9]+)'], - ["PoolAllocRefillFromL2", 'CBE-PA-L1-Cache-Misses: ([0-9]+)'], - ["PoolAllocRefillFromSystem", 'CBE-PA-L2-Cache-Misses: ([.0-9]+)'], + ["PAUserTime", 'CBE-RUN-TIME-POOLALLOC-USER: user\s*([.0-9m:]+)', \&FormatTime], + ["PASysTime", 'CBE-RUN-TIME-POOLALLOC-SYS: sys\s*([.0-9m:]+)', \&FormatTime], + ["PACacheAccess", 'CBE-PA-Cache-Accesses: ([0-9]+)'], + ["PACacheMisses", 'CBE-PA-Cache-Misses: ([0-9]+)'], + ["PARefillFromL2", 'CBE-PA-L1-Cache-Misses: ([0-9]+)'], + ["PARefillFromSys", 'CBE-PA-L2-Cache-Misses: ([.0-9]+)'], [] ); From natebegeman at mac.com Mon Nov 8 22:01:29 2004 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 8 Nov 2004 22:01:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/ToolRunner.cpp Message-ID: <200411090401.WAA12444@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: ToolRunner.cpp updated: 1.31 -> 1.32 --- Log message: Allow hbd to be bugpointable on darwin by fixing common and linkonce codegen --- Diffs of the changes: (+0 -1) Index: llvm/lib/Support/ToolRunner.cpp diff -u llvm/lib/Support/ToolRunner.cpp:1.31 llvm/lib/Support/ToolRunner.cpp:1.32 --- llvm/lib/Support/ToolRunner.cpp:1.31 Sun Oct 17 18:03:32 2004 +++ llvm/lib/Support/ToolRunner.cpp Mon Nov 8 22:01:18 2004 @@ -411,7 +411,6 @@ #elif (defined(__POWERPC__) || defined(__ppc__)) && defined(__APPLE__) "-single_module", // link all source files into a single module "-dynamiclib", // `-dynamiclib' for MacOS X/PowerPC - "-fno-common", // allow global vars w/o initializers to live "-undefined", // in data segment, rather than generating "dynamic_lookup", // blocks. dynamic_lookup requires that you set // MACOSX_DEPLOYMENT_TARGET=10.3 in your env. From natebegeman at mac.com Mon Nov 8 22:01:29 2004 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 8 Nov 2004 22:01:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Message-ID: <200411090401.WAA12447@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCAsmPrinter.cpp updated: 1.65 -> 1.66 --- Log message: Allow hbd to be bugpointable on darwin by fixing common and linkonce codegen --- Diffs of the changes: (+4 -3) Index: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.65 llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.66 --- llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.65 Tue Oct 26 01:02:38 2004 +++ llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Mon Nov 8 22:01:18 2004 @@ -367,8 +367,8 @@ } // External or weakly linked global variables need non-lazily-resolved stubs - if ((GV->isExternal() || GV->hasWeakLinkage()) && - getTM().AddressTaken.count(GV)) { + if ((GV->isExternal() || GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) + && getTM().AddressTaken.count(GV)) { GVStubs.insert(Name); O << "L" << Name << "$non_lazy_ptr"; return; @@ -472,7 +472,8 @@ unsigned Align = TD.getTypeAlignmentShift(C->getType()); if (C->isNullValue() && /* FIXME: Verify correct */ - (I->hasInternalLinkage() || I->hasWeakLinkage())) { + (I->hasInternalLinkage() || I->hasWeakLinkage() || + I->hasLinkOnceLinkage())) { SwitchSection(O, CurSection, ".data"); if (I->hasInternalLinkage()) O << ".lcomm " << name << "," << TD.getTypeSize(C->getType()) From brukman at cs.uiuc.edu Mon Nov 8 22:25:10 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon, 8 Nov 2004 22:25:10 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccld/Linker.cpp Message-ID: <200411090425.WAA12971@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: Linker.cpp updated: 1.29 -> 1.30 --- Log message: Output the program name (in this case, gccld) with warning about invalid files --- Diffs of the changes: (+2 -1) Index: llvm/tools/gccld/Linker.cpp diff -u llvm/tools/gccld/Linker.cpp:1.29 llvm/tools/gccld/Linker.cpp:1.30 --- llvm/tools/gccld/Linker.cpp:1.29 Mon Nov 8 16:03:10 2004 +++ llvm/tools/gccld/Linker.cpp Mon Nov 8 22:24:59 2004 @@ -346,7 +346,8 @@ return true; } } else { - std::cerr << "Warning: invalid file `" << Pathname << "' ignored.\n"; + std::cerr << progname << ": Warning: invalid file `" << Pathname + << "' ignored.\n"; } } From brukman at cs.uiuc.edu Mon Nov 8 22:27:30 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon, 8 Nov 2004 22:27:30 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/Annotation.cpp Message-ID: <200411090427.WAA13125@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: Annotation.cpp updated: 1.15 -> 1.16 --- Log message: * Convert tabs to spaces * Order #includes according to style guide * Remove extraneous blank lines --- Diffs of the changes: (+6 -10) Index: llvm/lib/Support/Annotation.cpp diff -u llvm/lib/Support/Annotation.cpp:1.15 llvm/lib/Support/Annotation.cpp:1.16 --- llvm/lib/Support/Annotation.cpp:1.15 Wed Sep 1 17:55:35 2004 +++ llvm/lib/Support/Annotation.cpp Mon Nov 8 22:27:19 2004 @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include #include "llvm/Support/Annotation.h" +#include using namespace llvm; Annotation::~Annotation() {} // Designed to be subclassed @@ -26,7 +26,6 @@ } } - typedef std::map IDMapType; static unsigned IDCounter = 0; // Unique ID counter @@ -65,13 +64,12 @@ // getID - Name -> ID + registration of a factory function for demand driven // annotation support. AnnotationID AnnotationManager::getID(const std::string &Name, Factory Fact, - void *Data) { + void *Data) { AnnotationID Result(getID(Name)); registerAnnotationFactory(Result, Fact, Data); - return Result; + return Result; } - // getName - This function is especially slow, but that's okay because it should // only be used for debugging. // @@ -83,14 +81,12 @@ } } - // registerAnnotationFactory - This method is used to register a callback // function used to create an annotation on demand if it is needed by the // Annotable::findOrCreateAnnotation method. // -void AnnotationManager::registerAnnotationFactory(AnnotationID ID, - AnnFactory F, - void *ExtraData) { +void AnnotationManager::registerAnnotationFactory(AnnotationID ID, AnnFactory F, + void *ExtraData) { if (F) getFactMap()[ID.ID] = std::make_pair(F, ExtraData); else @@ -101,7 +97,7 @@ // specified object, using a register annotation creation function. // Annotation *AnnotationManager::createAnnotation(AnnotationID ID, - const Annotable *Obj) { + const Annotable *Obj) { FactMapType::iterator I = getFactMap().find(ID.ID); if (I == getFactMap().end()) return 0; return I->second.first(ID, Obj, I->second.second); From lattner at cs.uiuc.edu Mon Nov 8 23:06:37 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 Nov 2004 23:06:37 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/RaiseAllocations/test.ll Message-ID: <200411090506.iA956bVg022786@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/RaiseAllocations: test.ll added (r1.1) --- Log message: Hrm, don't ask how I ran into this bug --- Diffs of the changes: (+10 -0) Index: llvm/test/Regression/Transforms/RaiseAllocations/test.ll diff -c /dev/null llvm/test/Regression/Transforms/RaiseAllocations/test.ll:1.1 *** /dev/null Mon Nov 8 23:06:33 2004 --- llvm/test/Regression/Transforms/RaiseAllocations/test.ll Mon Nov 8 23:06:23 2004 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as < %s | opt -raiseallocs -disable-output + implementation ; Functions: + + void %main() { + %tmp.13 = call int (...)* %free( int 32 ) + %tmp.14 = cast int %tmp.13 to int* + ret void + } + + declare int %free(...) From lattner at cs.uiuc.edu Mon Nov 8 23:07:12 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 Nov 2004 23:07:12 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/RaiseAllocations/2004-11-08-FreeUseCrash.ll test.ll Message-ID: <200411090507.iA957Ci3022801@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/RaiseAllocations: 2004-11-08-FreeUseCrash.ll added (r1.1) test.ll (r1.1) removed --- Log message: Name file properly --- Diffs of the changes: (+10 -0) Index: llvm/test/Regression/Transforms/RaiseAllocations/2004-11-08-FreeUseCrash.ll diff -c /dev/null llvm/test/Regression/Transforms/RaiseAllocations/2004-11-08-FreeUseCrash.ll:1.1 *** /dev/null Mon Nov 8 23:07:11 2004 --- llvm/test/Regression/Transforms/RaiseAllocations/2004-11-08-FreeUseCrash.ll Mon Nov 8 23:07:01 2004 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as < %s | opt -raiseallocs -disable-output + implementation ; Functions: + + void %main() { + %tmp.13 = call int (...)* %free( int 32 ) + %tmp.14 = cast int %tmp.13 to int* + ret void + } + + declare int %free(...) From lattner at cs.uiuc.edu Mon Nov 8 23:11:08 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 Nov 2004 23:11:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/RaiseAllocations.cpp Message-ID: <200411090511.iA95B8BN023066@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: RaiseAllocations.cpp updated: 1.26 -> 1.27 --- Log message: Fix bug: 2004-11-08-FreeUseCrash.ll --- Diffs of the changes: (+3 -1) Index: llvm/lib/Transforms/IPO/RaiseAllocations.cpp diff -u llvm/lib/Transforms/IPO/RaiseAllocations.cpp:1.26 llvm/lib/Transforms/IPO/RaiseAllocations.cpp:1.27 --- llvm/lib/Transforms/IPO/RaiseAllocations.cpp:1.26 Sun Sep 19 23:43:34 2004 +++ llvm/lib/Transforms/IPO/RaiseAllocations.cpp Mon Nov 8 23:10:56 2004 @@ -201,7 +201,9 @@ new BranchInst(II->getNormalDest(), I); // Delete the old call site - I->getParent()->getInstList().erase(I); + if (I->getType() != Type::VoidTy) + I->replaceAllUsesWith(UndefValue::get(I->getType())); + I->eraseFromParent(); Changed = true; ++NumRaised; } From reid at x10sys.com Tue Nov 9 00:28:43 2004 From: reid at x10sys.com (Reid Spencer) Date: Tue, 9 Nov 2004 00:28:43 -0600 Subject: [llvm-commits] CVS: llvm/test/Makefile Message-ID: <200411090628.AAA20207@zion.cs.uiuc.edu> Changes in directory llvm/test: Makefile updated: 1.65 -> 1.66 --- Log message: Add a quick-test target that uses QUICKTEST variable to quickly run a portion of the test suite. e.g.: make quck-test QUICKTEST=Regression/Bytecode --- Diffs of the changes: (+7 -0) Index: llvm/test/Makefile diff -u llvm/test/Makefile:1.65 llvm/test/Makefile:1.66 --- llvm/test/Makefile:1.65 Sun Nov 7 23:44:05 2004 +++ llvm/test/Makefile Tue Nov 9 00:28:32 2004 @@ -149,3 +149,10 @@ @test ! -f site.exp || mv site.exp site.bak @mv site.tmp site.exp +quick-test: + @if test -d "${QUICKTEST}" ; then \ + cd $(LLVM_SRC_ROOT)/test/$(QUICKTEST) ; \ + find . -name \*.ll -print -exec $(LLVM_SRC_ROOT)/test/TestRunner.sh {} \; ; \ + else \ + echo "Set QUICKTEST= Changes in directory llvm/test: Makefile updated: 1.66 -> 1.67 --- Log message: Document quick-test target. --- Diffs of the changes: (+6 -0) Index: llvm/test/Makefile diff -u llvm/test/Makefile:1.66 llvm/test/Makefile:1.67 --- llvm/test/Makefile:1.66 Tue Nov 9 00:28:32 2004 +++ llvm/test/Makefile Tue Nov 9 00:32:58 2004 @@ -149,6 +149,12 @@ @test ! -f site.exp || mv site.exp site.bak @mv site.tmp site.exp +#===------------------------------------------------------------------------===# +# quick-test utility. Just runs TestRunner.sh on all the *.ll files in a +# directory. Use like this: +# cd llvm/test ; make quick-test QUICKTEST=Regression/Bytecode +# where QUICKTEST specifies the directory you want to run the tests on. +#===------------------------------------------------------------------------===# quick-test: @if test -d "${QUICKTEST}" ; then \ cd $(LLVM_SRC_ROOT)/test/$(QUICKTEST) ; \ From lattner at cs.uiuc.edu Tue Nov 9 00:41:32 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 Nov 2004 00:41:32 -0600 Subject: [llvm-commits] CVS: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp PoolAllocator.h Message-ID: <200411090641.iA96fWea024404@apoc.cs.uiuc.edu> Changes in directory poolalloc/runtime/FL2Allocator: FreeListAllocator.cpp updated: 1.23 -> 1.24 PoolAllocator.h updated: 1.11 -> 1.12 --- Log message: More improvements to trace output, allowing us to trace mallocrepl. Two bugfixes: 1. On X86, make sure to align all returned pointers to 8 byte boundaries. In particular, things with doubles in them REALLY want memory to be aligned, though we don't get bus errors on X86. In the future, an argument to pool init can be used to relax this. 2. Do not allocate "large" objects out of the pool slab even if we have enough space to do so in a slab. --- Diffs of the changes: (+80 -52) Index: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp diff -u poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.23 poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.24 --- poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.23 Sun Nov 7 19:45:55 2004 +++ poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp Tue Nov 9 00:41:22 2004 @@ -22,12 +22,12 @@ #define INITIAL_SLAB_SIZE 4096 #define LARGE_SLAB_SIZE 4096 - +#ifndef NDEBUG // Configuration macros. Define up to one of these. //#define PRINT_NUM_POOLS // Print use dynamic # pools info //#define PRINT_POOLDESTROY_STATS // When pools are destroyed, print stats -//#define PRINT_POOL_TRACE // Print a full trace - +#define PRINT_POOL_TRACE // Print a full trace +#endif //===----------------------------------------------------------------------===// // Pool Debugging stuff. @@ -175,16 +175,26 @@ Size = (Size+SizeHint-1) / SizeHint * SizeHint; PoolSlab *PS = (PoolSlab*)malloc(Size+sizeof(PoolSlab) + sizeof(NodeHeader) + sizeof(FreedNodeHeader)); + char *PoolBody = (char*)(PS+1); - // Add the body of the slab to the free list... - FreedNodeHeader *SlabBody = (FreedNodeHeader*)(PS+1); + // If the Alignment is greater than the size of the FreedNodeHeader, skip over + // some space so that the a "free pointer + sizeof(FreedNodeHeader)" is always + // aligned. + unsigned Alignment = Pool->Alignment; + if (Alignment > sizeof(FreedNodeHeader)) { + PoolBody += Alignment-sizeof(FreedNodeHeader); + Size -= Alignment-sizeof(FreedNodeHeader); + } + + // Add the body of the slab to the free list. + FreedNodeHeader *SlabBody = (FreedNodeHeader*)PoolBody; SlabBody->Header.Size = Size; AddNodeToFreeList(Pool, SlabBody); // Make sure to add a marker at the end of the slab to prevent the coallescer // from trying to merge off the end of the page. FreedNodeHeader *End = - (FreedNodeHeader*)((char*)SlabBody + sizeof(NodeHeader) + Size); + (FreedNodeHeader*)(PoolBody + sizeof(NodeHeader) + Size); End->Header.Size = ~0; // Looks like an allocated chunk // Add the slab to the list... @@ -210,6 +220,7 @@ memset(Pool, 0, sizeof(PoolTy)); Pool->AllocSize = INITIAL_SLAB_SIZE; Pool->DeclaredSize = DeclaredSize; + Pool->Alignment = __alignof(double); DO_IF_TRACE(fprintf(stderr, "[%d] poolinit(0x%X, %d)\n", addPoolNumber(Pool), Pool, DeclaredSize)); @@ -255,23 +266,33 @@ // If a null pool descriptor is passed in, this is not a pool allocated data // structure. Hand off to the system malloc. - if (Pool == 0) return malloc(NumBytes); - if (NumBytes == 0) NumBytes = 1; - unsigned PtrSize = sizeof(int*); - NumBytes = (NumBytes+(PtrSize-1)) & ~(PtrSize-1); // Round up to 4/8 bytes... + if (Pool == 0) { + void *Result = malloc(NumBytes); + DO_IF_TRACE(fprintf(stderr, "0x%X [malloc]\n", Result)); + return Result; + } + DO_IF_PNP(if (Pool->NumObjects == 0) ++PoolCounter); // Track # pools. // Objects must be at least 8 bytes to hold the FreedNodeHeader object when - // they are freed. + // they are freed. This also handles allocations of 0 bytes. if (NumBytes < (sizeof(FreedNodeHeader)-sizeof(NodeHeader))) NumBytes = sizeof(FreedNodeHeader)-sizeof(NodeHeader); - DO_IF_PNP(if (Pool->NumObjects == 0) ++PoolCounter); // Track # pools. + // Adjust the size so that memory allocated from the pool is always on the + // proper alignment boundary. + unsigned Alignment = Pool->Alignment; + NumBytes = NumBytes+sizeof(FreedNodeHeader)+(Alignment-1); // Round up + NumBytes = (NumBytes & ~(Alignment-1))-sizeof(FreedNodeHeader); // Truncate ++Pool->NumObjects; Pool->BytesAllocated += NumBytes; + if (NumBytes >= LARGE_SLAB_SIZE-sizeof(PoolSlab)-sizeof(NodeHeader)) + goto LargeObject; + // Figure out which size class to start scanning from. - unsigned SizeClass = getSizeClass(NumBytes); + unsigned SizeClass; + SizeClass = getSizeClass(NumBytes); // Scan for a class that has entries! while (SizeClass < 3 && Pool->FreeNodeLists[SizeClass] == 0) @@ -305,46 +326,45 @@ // Perform a search of the free list, taking the front of the first free chunk // that is big enough. - if (NumBytes <= LARGE_SLAB_SIZE-sizeof(PoolSlab)-sizeof(NodeHeader)) { - do { - FreedNodeHeader **FN = &Pool->FreeNodeLists[SizeClass]; - FreedNodeHeader *FNN = *FN; - - // Search the list for the first-fit - while (FNN && FNN->Header.Size < NumBytes) - FN = &FNN->Next, FNN = *FN; - - if (FNN) { - // We found a slab big enough. If it's a perfect fit, just unlink from - // the free list, otherwise, slice a little bit off and adjust the free - // list. - if (FNN->Header.Size > 2*NumBytes+sizeof(NodeHeader)) { - UnlinkFreeNode(FNN); - - // Put the remainder back on the list... - FreedNodeHeader *NextNodes = - (FreedNodeHeader*)((char*)FNN + sizeof(NodeHeader) + NumBytes); - NextNodes->Header.Size = FNN->Header.Size-NumBytes-sizeof(NodeHeader); - AddNodeToFreeList(Pool, NextNodes); - } else { - UnlinkFreeNode(FNN); - NumBytes = FNN->Header.Size; - } - FNN->Header.Size = NumBytes|1; // Mark as allocated - DO_IF_TRACE(fprintf(stderr, "0x%X\n", &FNN->Header+1)); - return &FNN->Header+1; - } + do { + FreedNodeHeader **FN = &Pool->FreeNodeLists[SizeClass]; + FreedNodeHeader *FNN = *FN; + + // Search the list for the first-fit + while (FNN && FNN->Header.Size < NumBytes) + FN = &FNN->Next, FNN = *FN; + + if (FNN) { + // We found a slab big enough. If it's a perfect fit, just unlink from + // the free list, otherwise, slice a little bit off and adjust the free + // list. + if (FNN->Header.Size > 2*NumBytes+sizeof(NodeHeader)) { + UnlinkFreeNode(FNN); - if (SizeClass < LargeFreeList) { - ++SizeClass; + // Put the remainder back on the list... + FreedNodeHeader *NextNodes = + (FreedNodeHeader*)((char*)FNN + sizeof(NodeHeader) + NumBytes); + NextNodes->Header.Size = FNN->Header.Size-NumBytes-sizeof(NodeHeader); + AddNodeToFreeList(Pool, NextNodes); } else { - // Oops, we didn't find anything on the free list big enough! Allocate - // another slab and try again. - PoolSlab::create(Pool, NumBytes); + UnlinkFreeNode(FNN); + NumBytes = FNN->Header.Size; } - } while (1); - } + FNN->Header.Size = NumBytes|1; // Mark as allocated + DO_IF_TRACE(fprintf(stderr, "0x%X\n", &FNN->Header+1)); + return &FNN->Header+1; + } + + if (SizeClass < LargeFreeList) { + ++SizeClass; + } else { + // Oops, we didn't find anything on the free list big enough! Allocate + // another slab and try again. + PoolSlab::create(Pool, NumBytes); + } + } while (1); +LargeObject: // Otherwise, the allocation is a large array. Since we're not going to be // able to help much for this allocation, simply pass it on to malloc. LargeArrayHeader *LAH = (LargeArrayHeader*)malloc(sizeof(LargeArrayHeader) + @@ -357,13 +377,17 @@ } void poolfree(PoolTy *Pool, void *Node) { + if (Node == 0) return; DO_IF_TRACE(fprintf(stderr, "[%d] poolfree(0x%X) ", getPoolNumber(Pool), Node)); // If a null pool descriptor is passed in, this is not a pool allocated data // structure. Hand off to the system free. - if (Pool == 0) { free(Node); return; } - if (Node == 0) return; + if (Pool == 0) { + free(Node); + DO_IF_TRACE(fprintf(stderr, "[free]\n")); + return; + } // Check to see how many elements were allocated to this node... FreedNodeHeader *FNH = (FreedNodeHeader*)((char*)Node-sizeof(NodeHeader)); @@ -385,7 +409,8 @@ // If there are already nodes on the freelist, see if these blocks can be // coallesced into one of the early blocks on the front of the list. This is - // a simple check that prevents many horrible forms of fragmentation. + // a simple check that prevents many horrible forms of fragmentation, + // particularly when freeing objects in allocation order. // for (unsigned SizeClass = 0; SizeClass <= LargeFreeList; ++SizeClass) if (FreedNodeHeader *CurFrontNode = Pool->FreeNodeLists[SizeClass]) Index: poolalloc/runtime/FL2Allocator/PoolAllocator.h diff -u poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.11 poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.12 --- poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.11 Sun Nov 7 19:44:13 2004 +++ poolalloc/runtime/FL2Allocator/PoolAllocator.h Tue Nov 9 00:41:22 2004 @@ -86,6 +86,9 @@ // The free node lists for objects of various sizes. FreedNodeHeader *FreeNodeLists[4]; + // Alignment - The required alignment of allocations the pool in bytes. + unsigned Alignment; + // NumObjects - the number of poolallocs for this pool. unsigned NumObjects; From lattner at cs.uiuc.edu Tue Nov 9 02:05:38 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 Nov 2004 02:05:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/InlineSimple.cpp Message-ID: <200411090805.iA985cv1025898@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: InlineSimple.cpp updated: 1.66 -> 1.67 --- Log message: Change this back so that I get stable numbers to reflect the change from the nightly testers --- Diffs of the changes: (+1 -1) Index: llvm/lib/Transforms/IPO/InlineSimple.cpp diff -u llvm/lib/Transforms/IPO/InlineSimple.cpp:1.66 llvm/lib/Transforms/IPO/InlineSimple.cpp:1.67 --- llvm/lib/Transforms/IPO/InlineSimple.cpp:1.66 Sun Nov 7 15:46:47 2004 +++ llvm/lib/Transforms/IPO/InlineSimple.cpp Tue Nov 9 02:05:23 2004 @@ -193,7 +193,7 @@ // make it almost guaranteed to be inlined. // if (Callee->hasInternalLinkage() && Callee->hasOneUse()) - InlineCost -= 5000; + InlineCost -= 30000; // Get information about the callee... FunctionInfo &CalleeFI = CachedFunctionInfo[Callee]; From reid at x10sys.com Tue Nov 9 11:58:19 2004 From: reid at x10sys.com (Reid Spencer) Date: Tue, 9 Nov 2004 11:58:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/Compressor.cpp Message-ID: <200411091758.LAA15765@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: Compressor.cpp updated: 1.4 -> 1.5 --- Log message: Tune compression: bzip2: block size 9 -> 5, reduces memory by 400Kbytes, doesn't affect speed or compression ratio on all but the largest bytecode files (>1MB) zip: level 9 -> 6, this speeds up compression time by ~30% but only degrades the compressed size by a few bytes per megabyte. Those few bytes aren't worth the effort. --- Diffs of the changes: (+2 -2) Index: llvm/lib/Support/Compressor.cpp diff -u llvm/lib/Support/Compressor.cpp:1.4 llvm/lib/Support/Compressor.cpp:1.5 --- llvm/lib/Support/Compressor.cpp:1.4 Mon Oct 4 12:45:44 2004 +++ llvm/lib/Support/Compressor.cpp Tue Nov 9 11:58:09 2004 @@ -136,7 +136,7 @@ bzdata.avail_in = size; bzdata.next_out = 0; bzdata.avail_out = 0; - switch ( BZ2_bzCompressInit(&bzdata, 9, 0, 100) ) { + switch ( BZ2_bzCompressInit(&bzdata, 5, 0, 100) ) { case BZ_CONFIG_ERROR: throw std::string("bzip2 library mis-compiled"); case BZ_PARAM_ERROR: throw std::string("Compressor internal error"); case BZ_MEM_ERROR: throw std::string("Out of memory"); @@ -190,7 +190,7 @@ zdata.opaque = Z_NULL; zdata.next_in = reinterpret_cast(in); zdata.avail_in = size; - if (Z_OK != deflateInit(&zdata,Z_BEST_COMPRESSION)) + if (Z_OK != deflateInit(&zdata,6)) throw std::string(zdata.msg ? zdata.msg : "zlib error"); if (0 != getdata((char*&)(zdata.next_out), zdata.avail_out,cb,context)) { From criswell at cs.uiuc.edu Tue Nov 9 13:37:22 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 9 Nov 2004 13:37:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/ArchiveReader.cpp Message-ID: <200411091937.NAA18642@choi.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: ArchiveReader.cpp updated: 1.19 -> 1.20 --- Log message: Recognize compressed LLVM bytecode files. This should fix the problem of not being able to link compressed LLVM bytecode files from LLVM libraries. --- Diffs of the changes: (+3 -0) Index: llvm/lib/Bytecode/Reader/ArchiveReader.cpp diff -u llvm/lib/Bytecode/Reader/ArchiveReader.cpp:1.19 llvm/lib/Bytecode/Reader/ArchiveReader.cpp:1.20 --- llvm/lib/Bytecode/Reader/ArchiveReader.cpp:1.19 Wed Sep 1 17:55:35 2004 +++ llvm/lib/Bytecode/Reader/ArchiveReader.cpp Tue Nov 9 13:37:07 2004 @@ -58,6 +58,9 @@ if (Size >= 4 && !memcmp(MemberData, "llvm", 4)) return UserObject; + if (Size >= 4 && !memcmp(MemberData, "llvc", 4)) + return UserObject; + return Unknown; } From criswell at cs.uiuc.edu Tue Nov 9 13:42:26 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 9 Nov 2004 13:42:26 -0600 Subject: [llvm-commits] CVS: poolalloc/test/Makefile Message-ID: <200411091942.NAA20718@choi.cs.uiuc.edu> Changes in directory poolalloc/test: Makefile updated: 1.25 -> 1.26 --- Log message: Remove SPEC benchmarks that Chris no longer wants to use for the current paper. --- Diffs of the changes: (+7 -1) Index: poolalloc/test/Makefile diff -u poolalloc/test/Makefile:1.25 poolalloc/test/Makefile:1.26 --- poolalloc/test/Makefile:1.25 Mon Nov 8 21:33:49 2004 +++ poolalloc/test/Makefile Tue Nov 9 13:42:15 2004 @@ -26,7 +26,13 @@ External/Povray \ External/FPGrowth \ External/Namd \ - External/SPEC/CINT2000 + External/SPEC/CINT2000/164.gzip \ + External/SPEC/CINT2000/175.vpr \ + External/SPEC/CINT2000/176.gcc \ + External/SPEC/CINT2000/252.eon \ + External/SPEC/CINT2000/253.perlbmk \ + External/SPEC/CINT2000/254.gap \ + External/SPEC/CINT2000/300.twolf NORMAL_PROBLEM_SIZE_DIRS := \ $(addprefix $(LLVM_OBJ_ROOT)/projects/llvm-test/,$(NORMAL_PROBLEM_SIZE_DIRS)) From lattner at cs.uiuc.edu Tue Nov 9 14:16:36 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 Nov 2004 14:16:36 -0600 Subject: [llvm-commits] CVS: poolalloc/lib/PoolAllocate/Heuristic.cpp PoolAllocate.cpp Message-ID: <200411092016.iA9KGasM020900@apoc.cs.uiuc.edu> Changes in directory poolalloc/lib/PoolAllocate: Heuristic.cpp updated: 1.2 -> 1.3 PoolAllocate.cpp updated: 1.88 -> 1.89 --- Log message: Count number of type-safe pools correctly, pass an extra argument to poolinit (though for now it's always dynamically zero). --- Diffs of the changes: (+29 -14) Index: poolalloc/lib/PoolAllocate/Heuristic.cpp diff -u poolalloc/lib/PoolAllocate/Heuristic.cpp:1.2 poolalloc/lib/PoolAllocate/Heuristic.cpp:1.3 --- poolalloc/lib/PoolAllocate/Heuristic.cpp:1.2 Mon Nov 8 00:49:14 2004 +++ poolalloc/lib/PoolAllocate/Heuristic.cpp Tue Nov 9 14:16:25 2004 @@ -86,15 +86,23 @@ Function *F, DSGraph &G, std::vector &ResultPools) { // Build a set of all nodes that are reachable from another node in the - // graph. + // graph. Here we ignore scalar nodes that are only globals as they are + // often global pointers to big arrays. std::set ReachableFromMemory; for (DSGraph::node_iterator I = G.node_begin(), E = G.node_end(); I != E; ++I) { DSNode *N = *I; - for (DSNode::iterator NI = N->begin(), E = N->end(); NI != E; ++NI) - for (df_ext_iterator - DI = df_ext_begin(*NI, ReachableFromMemory), - E = df_ext_end(*NI, ReachableFromMemory); DI != E; ++DI) + // Ignore nodes that are just globals and not arrays. + /* + if (N->isArray() || N->isHeapNode() || N->isAllocaNode() || + N->isUnknownNode()) + */ + // If a node is marked, all children are too. + if (!ReachableFromMemory.count(N)) + for (DSNode::iterator NI = N->begin(), E = N->end(); NI != E; ++NI) + for (df_ext_iterator + DI = df_ext_begin(*NI, ReachableFromMemory), + E = df_ext_end(*NI, ReachableFromMemory); DI != E; ++DI) /*empty*/; } Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.88 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.89 --- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.88 Mon Nov 8 00:32:31 2004 +++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp Tue Nov 9 14:16:25 2004 @@ -146,7 +146,8 @@ // Get poolinit function. PoolInit = CurModule->getOrInsertFunction("poolinit", Type::VoidTy, - PoolDescPtrTy, Type::UIntTy, 0); + PoolDescPtrTy, Type::UIntTy, + Type::UIntTy, 0); // Get pooldestroy function. PoolDestroy = CurModule->getOrInsertFunction("pooldestroy", Type::VoidTy, @@ -406,8 +407,13 @@ for (unsigned i = 0, e = ResultPools.size(); i != e; ++i) { Heuristic::OnePool &Pool = ResultPools[i]; Value *PoolDesc = Pool.PoolDesc; - if (PoolDesc == 0) + if (PoolDesc == 0) { PoolDesc = CreateGlobalPool(Pool.PoolSize); + + if (Pool.NodesInPool.size() == 1 && + !Pool.NodesInPool[0]->isNodeCompletelyFolded()) + ++NumTSPools; + } for (unsigned N = 0, e = Pool.NodesInPool.size(); N != e; ++N) { GlobalNodes[Pool.NodesInPool[N]] = PoolDesc; GlobalHeapNodes.erase(Pool.NodesInPool[N]); // Handled! @@ -436,8 +442,11 @@ BasicBlock::iterator InsertPt = MainFunc->getEntryBlock().begin(); while (isa(InsertPt)) ++InsertPt; + unsigned Alignment = 0; Value *ElSize = ConstantUInt::get(Type::UIntTy, RecSize); - new CallInst(PoolInit, make_vector((Value*)GV, ElSize, 0), "", InsertPt); + Value *Align = ConstantUInt::get(Type::UIntTy, Alignment); + new CallInst(PoolInit, make_vector((Value*)GV, ElSize, Align, 0), + "", InsertPt); ++NumPools; return GV; } @@ -767,15 +776,13 @@ DEBUG(std::cerr << "\n Init in blocks: "); // Insert the calls to initialize the pool. - unsigned ElSizeV = 0; - if (!Node->isArray() && Node->getType()->isSized()) - ElSizeV = TD.getTypeSize(Node->getType()); - if (ElSizeV == 1) ElSizeV = 0; + unsigned ElSizeV = Heuristic::getRecommendedSize(Node); Value *ElSize = ConstantUInt::get(Type::UIntTy, ElSizeV); + Value *Align = ConstantUInt::get(Type::UIntTy, 0); for (unsigned i = 0, e = PoolInitPoints.size(); i != e; ++i) { - new CallInst(PoolInit, make_vector((Value*)PD, ElSize, 0), "", - PoolInitPoints[i]); + new CallInst(PoolInit, make_vector((Value*)PD, ElSize, Align, 0), + "", PoolInitPoints[i]); DEBUG(std::cerr << PoolInitPoints[i]->getParent()->getName() << " "); } if (!DisableInitDestroyOpt) From lattner at cs.uiuc.edu Tue Nov 9 14:17:15 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 Nov 2004 14:17:15 -0600 Subject: [llvm-commits] CVS: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp PoolAllocator.h Message-ID: <200411092017.iA9KHFRG020915@apoc.cs.uiuc.edu> Changes in directory poolalloc/runtime/FL2Allocator: FreeListAllocator.cpp updated: 1.24 -> 1.25 PoolAllocator.h updated: 1.12 -> 1.13 --- Log message: Allow an extra argument to be passed to poolinit to control the alignment of objects allocated from the pool (giving alignment control to the pool allocator). --- Diffs of the changes: (+4 -3) Index: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp diff -u poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.24 poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.25 --- poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.24 Tue Nov 9 00:41:22 2004 +++ poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp Tue Nov 9 14:17:05 2004 @@ -215,12 +215,13 @@ // poolinit - Initialize a pool descriptor to empty // -void poolinit(PoolTy *Pool, unsigned DeclaredSize) { +void poolinit(PoolTy *Pool, unsigned DeclaredSize, unsigned ObjAlignment) { assert(Pool && "Null pool pointer passed into poolinit!\n"); memset(Pool, 0, sizeof(PoolTy)); Pool->AllocSize = INITIAL_SLAB_SIZE; Pool->DeclaredSize = DeclaredSize; - Pool->Alignment = __alignof(double); + if (ObjAlignment < 4) ObjAlignment = __alignof(double); + Pool->Alignment = ObjAlignment; DO_IF_TRACE(fprintf(stderr, "[%d] poolinit(0x%X, %d)\n", addPoolNumber(Pool), Pool, DeclaredSize)); Index: poolalloc/runtime/FL2Allocator/PoolAllocator.h diff -u poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.12 poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.13 --- poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.12 Tue Nov 9 00:41:22 2004 +++ poolalloc/runtime/FL2Allocator/PoolAllocator.h Tue Nov 9 14:17:05 2004 @@ -108,7 +108,7 @@ }; extern "C" { - void poolinit(PoolTy *Pool, unsigned DeclaredSize); + void poolinit(PoolTy *Pool, unsigned DeclaredSize, unsigned ObjAlignment); void poolmakeunfreeable(PoolTy *Pool); void pooldestroy(PoolTy *Pool); void *poolalloc(PoolTy *Pool, unsigned NumBytes); From reid at x10sys.com Tue Nov 9 14:21:36 2004 From: reid at x10sys.com (Reid Spencer) Date: Tue, 9 Nov 2004 14:21:36 -0600 Subject: [llvm-commits] CVS: llvm/tools/llee/ExecveHandler.c Message-ID: <200411092021.OAA18502@zion.cs.uiuc.edu> Changes in directory llvm/tools/llee: ExecveHandler.c updated: 1.9 -> 1.10 --- Log message: Make sure llee can deal with compressed bytecode too. --- Diffs of the changes: (+7 -5) Index: llvm/tools/llee/ExecveHandler.c diff -u llvm/tools/llee/ExecveHandler.c:1.9 llvm/tools/llee/ExecveHandler.c:1.10 --- llvm/tools/llee/ExecveHandler.c:1.9 Wed Sep 1 17:55:37 2004 +++ llvm/tools/llee/ExecveHandler.c Tue Nov 9 14:21:25 2004 @@ -21,10 +21,11 @@ #include /* - * This is the expected header for all valid LLVM bytecode files. - * The first four characters must be exactly this. + * These are the expected headers for all valid LLVM bytecode files. + * The first four characters must be one of these. */ -static const char llvmHeader[] = "llvm"; +static const char llvmHeaderUncompressed[] = "llvm"; +static const char llvmHeaderCompressed[] = "llvc"; /* * This replacement execve() function first checks the file to be executed @@ -34,7 +35,7 @@ int execve(const char *filename, char *const argv[], char *const envp[]) { /* Open the file, test to see if first four characters are "llvm" */ - size_t headerSize = strlen(llvmHeader); + size_t headerSize = strlen(llvmHeaderCompressed); char header[headerSize]; char* realFilename = 0; /* @@ -57,7 +58,8 @@ ssize_t bytesRead = read(file, header, headerSize); close(file); if (bytesRead != (ssize_t)headerSize) return EIO; - if (!memcmp(llvmHeader, header, headerSize)) { + if (!memcmp(llvmHeaderCompressed, header, headerSize) || + !memcmp(llvmHeaderUncompressed, header, headerSize)) { /* * This is a bytecode file, so execute the JIT with the program and * parameters. From lattner at cs.uiuc.edu Tue Nov 9 14:25:49 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 Nov 2004 14:25:49 -0600 Subject: [llvm-commits] CVS: poolalloc/lib/PoolAllocate/PoolAllocate.cpp PoolAllocate.h Message-ID: <200411092025.iA9KPnoQ021697@apoc.cs.uiuc.edu> Changes in directory poolalloc/lib/PoolAllocate: PoolAllocate.cpp updated: 1.89 -> 1.90 PoolAllocate.h updated: 1.29 -> 1.30 --- Log message: Tidy up code generated by pool allocator a bit to insert poolinit's in order instead of in reverse order. --- Diffs of the changes: (+14 -9) Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.89 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.90 --- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.89 Tue Nov 9 14:16:25 2004 +++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp Tue Nov 9 14:25:39 2004 @@ -389,12 +389,8 @@ return true; } - BasicBlock::iterator InsertPt = MainFunc->getEntryBlock().begin(); - while (isa(InsertPt)) ++InsertPt; - TargetData &TD = getAnalysis(); - std::cerr << "Pool allocating " << GlobalHeapNodes.size() << " global nodes!\n"; @@ -403,12 +399,15 @@ std::vector ResultPools; CurHeuristic->AssignToPools(NodesToPA, 0, GG, ResultPools); + BasicBlock::iterator InsertPt = MainFunc->getEntryBlock().begin(); + while (isa(InsertPt)) ++InsertPt; + // Perform all global assignments as specified. for (unsigned i = 0, e = ResultPools.size(); i != e; ++i) { Heuristic::OnePool &Pool = ResultPools[i]; Value *PoolDesc = Pool.PoolDesc; if (PoolDesc == 0) { - PoolDesc = CreateGlobalPool(Pool.PoolSize); + PoolDesc = CreateGlobalPool(Pool.PoolSize, InsertPt); if (Pool.NodesInPool.size() == 1 && !Pool.NodesInPool[0]->isNodeCompletelyFolded()) @@ -430,7 +429,8 @@ return false; } -GlobalVariable *PoolAllocate::CreateGlobalPool(unsigned RecSize) { +GlobalVariable *PoolAllocate::CreateGlobalPool(unsigned RecSize, + Instruction *IPHint) { GlobalVariable *GV = new GlobalVariable(PoolDescType, false, GlobalValue::InternalLinkage, Constant::getNullValue(PoolDescType), "GlobalPool", @@ -439,8 +439,13 @@ Function *MainFunc = CurModule->getMainFunction(); assert(MainFunc && "No main in program??"); - BasicBlock::iterator InsertPt = MainFunc->getEntryBlock().begin(); - while (isa(InsertPt)) ++InsertPt; + BasicBlock::iterator InsertPt; + if (IPHint) + InsertPt = IPHint; + else { + InsertPt = MainFunc->getEntryBlock().begin(); + while (isa(InsertPt)) ++InsertPt; + } unsigned Alignment = 0; Value *ElSize = ConstantUInt::get(Type::UIntTy, RecSize); Index: poolalloc/lib/PoolAllocate/PoolAllocate.h diff -u poolalloc/lib/PoolAllocate/PoolAllocate.h:1.29 poolalloc/lib/PoolAllocate/PoolAllocate.h:1.30 --- poolalloc/lib/PoolAllocate/PoolAllocate.h:1.29 Mon Nov 8 00:18:07 2004 +++ poolalloc/lib/PoolAllocate/PoolAllocate.h Tue Nov 9 14:25:39 2004 @@ -137,7 +137,7 @@ /// CreateGlobalPool - Create a global pool descriptor, initialize it in main, /// and return a pointer to the global for it. - GlobalVariable *CreateGlobalPool(unsigned RecSize); + GlobalVariable *CreateGlobalPool(unsigned RecSize, Instruction *IPHint = 0); private: From reid at x10sys.com Tue Nov 9 14:26:42 2004 From: reid at x10sys.com (Reid Spencer) Date: Tue, 9 Nov 2004 14:26:42 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/System/Path.h Message-ID: <200411092026.OAA18645@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: Path.h updated: 1.7 -> 1.8 --- Log message: * Implement getStatusInfo for getting stat(2) like information * Implement createTemporaryFile for mkstemp(3) functionality * Fix isBytecodeFile to accept llvc magic # (compressed) as bytecode. --- Diffs of the changes: (+30 -0) Index: llvm/include/llvm/System/Path.h diff -u llvm/include/llvm/System/Path.h:1.7 llvm/include/llvm/System/Path.h:1.8 --- llvm/include/llvm/System/Path.h:1.7 Fri Nov 5 16:15:35 2004 +++ llvm/include/llvm/System/Path.h Tue Nov 9 14:26:31 2004 @@ -16,6 +16,7 @@ #include #include +#include "llvm/System/TimeValue.h" namespace llvm { namespace sys { @@ -306,6 +307,24 @@ /// @brief Get the base name of the path std::string getBasename() const; + /// This structure provides basic file system information about a file. + /// The structure is filled in by the getStatusInfo method. + /// @brief File status structure + struct StatusInfo { + StatusInfo() : modTime(0,0) { fileSize=0; mode=0; user=0; group=0; } + size_t fileSize; ///< Size of the file in bytes + TimeValue modTime; ///< Time of file's modification + uint64_t mode; ///< Mode of the file, if applicable + uint64_t user; ///< User ID of owner, if applicable + uint64_t group; ///< Group ID of owner, if applicable + }; + + /// This function returns status information about the file. + /// @returns nothing + /// @throws std::string if an error occurs. + /// @brief Get file status. + void getStatusInfo(StatusInfo& stat) const; + /// @returns a c string containing the path name. /// @brief Returns the path as a C string. const char* const c_str() const { return path.c_str(); } @@ -425,6 +444,17 @@ /// @brief Create the file this Path refers to. bool createFile(); + /// This is like createFile except that it creates a temporary file. A + /// unique temporary file name is generated based on the contents of + /// \p this before the call. The new name is assigned to \p this and the + /// file is created. Note that this will both change the Path object + /// *and* create the corresponding file. The path of \p this will have + /// six characters added to it (per mkstemp(3)) that ensure the file + /// name is unique. + /// @throws std::string if there is an error + /// @brief Create a temporary file + bool createTemporaryFile(); + /// This method attempts to destroy the directory named by the last in /// the Path name. If \p remove_contents is false, an attempt will be /// made to remove just the directory that this Path object refers to From reid at x10sys.com Tue Nov 9 14:26:42 2004 From: reid at x10sys.com (Reid Spencer) Date: Tue, 9 Nov 2004 14:26:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Path.cpp Message-ID: <200411092026.OAA18648@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Path.cpp updated: 1.9 -> 1.10 --- Log message: * Implement getStatusInfo for getting stat(2) like information * Implement createTemporaryFile for mkstemp(3) functionality * Fix isBytecodeFile to accept llvc magic # (compressed) as bytecode. --- Diffs of the changes: (+39 -5) Index: llvm/lib/System/Unix/Path.cpp diff -u llvm/lib/System/Unix/Path.cpp:1.9 llvm/lib/System/Unix/Path.cpp:1.10 --- llvm/lib/System/Unix/Path.cpp:1.9 Fri Nov 5 16:15:36 2004 +++ llvm/lib/System/Unix/Path.cpp Tue Nov 9 14:26:31 2004 @@ -164,10 +164,13 @@ bool Path::isBytecodeFile() const { - if (readable()) { - return hasMagicNumber("llvm"); - } - return false; + char buffer[ 4]; + buffer[0] = 0; + std::ifstream f(path.c_str()); + f.read(buffer, 4); + if (f.bad()) + ThrowErrno("can't read file signature"); + return 0 == memcmp(buffer,"llvc",4) || 0 == memcmp(buffer,"llvm",4); } bool @@ -220,6 +223,19 @@ return path.substr(pos+1); } +void +Path::getStatusInfo(StatusInfo& info) const { + struct stat buf; + if (0 != stat(path.c_str(), &buf)) { + ThrowErrno(std::string("Can't get status: ")+path); + } + info.fileSize = buf.st_size; + info.modTime.fromPosixTime(buf.st_mtime); + info.mode = buf.st_mode; + info.user = buf.st_uid; + info.group = buf.st_gid; +} + bool Path::setDirectory(const std::string& a_path) { if (a_path.size() == 0) @@ -379,13 +395,31 @@ // Create the file int fd = ::creat(path.c_str(), S_IRUSR | S_IWUSR); if (fd < 0) - ThrowErrno(std::string(path.c_str()) + ": Can't create file"); + ThrowErrno(path + ": Can't create file"); ::close(fd); return true; } bool +Path::createTemporaryFile() { + // Make sure we're dealing with a file + if (!isFile()) return false; + + // Append the filename filler + char pathname[MAXPATHLEN]; + path.copy(pathname,MAXPATHLEN); + strcat(pathname,"XXXXXX"); + int fd = ::mkstemp(pathname); + if (fd < 0) { + ThrowErrno(path + ": Can't create temporary file"); + } + path = pathname; + ::close(fd); + return true; +} + +bool Path::destroyDirectory(bool remove_contents) { // Make sure we're dealing with a directory if (!isDirectory()) return false; From reid at x10sys.com Tue Nov 9 14:27:33 2004 From: reid at x10sys.com (Reid Spencer) Date: Tue, 9 Nov 2004 14:27:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/Path.cpp Message-ID: <200411092027.OAA18685@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: Path.cpp updated: 1.5 -> 1.6 --- Log message: Fix isBytecodeFile to correctly recognized compressed bytecode too. --- Diffs of the changes: (+7 -4) Index: llvm/lib/System/Win32/Path.cpp diff -u llvm/lib/System/Win32/Path.cpp:1.5 llvm/lib/System/Win32/Path.cpp:1.6 --- llvm/lib/System/Win32/Path.cpp:1.5 Fri Nov 5 16:15:36 2004 +++ llvm/lib/System/Win32/Path.cpp Tue Nov 9 14:27:23 2004 @@ -242,10 +242,13 @@ bool Path::isBytecodeFile() const { - if (readable()) { - return hasMagicNumber("llvm"); - } - return false; + char buffer[ 4]; + buffer[0] = 0; + std::ifstream f(path.c_str()); + f.read(buffer, 4); + if (f.bad()) + ThrowErrno("can't read file signature"); + return 0 == memcmp(buffer,"llvc",4) || 0 == memcmp(buffer,"llvm",4); } bool From reid at x10sys.com Tue Nov 9 14:29:21 2004 From: reid at x10sys.com (Reid Spencer) Date: Tue, 9 Nov 2004 14:29:21 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/System/TimeValue.h Message-ID: <200411092029.OAA18787@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: TimeValue.h updated: 1.6 -> 1.7 --- Log message: Provide conversion from posix time. --- Diffs of the changes: (+9 -0) Index: llvm/include/llvm/System/TimeValue.h diff -u llvm/include/llvm/System/TimeValue.h:1.6 llvm/include/llvm/System/TimeValue.h:1.7 --- llvm/include/llvm/System/TimeValue.h:1.6 Tue Oct 26 13:00:03 2004 +++ llvm/include/llvm/System/TimeValue.h Tue Nov 9 14:29:10 2004 @@ -315,6 +315,15 @@ this->normalize(); } + /// Converts the \p seconds argument from PosixTime to the corresponding + /// TimeValue and assigns that value to \p this. + /// @brief Convert seconds form PosixTime to TimeValue + void fromPosixTime( SecondsType seconds ) { + seconds_ = seconds + PosixZeroTime.seconds_; + nanos_ = 0; + this->normalize(); + } + /// @} /// @name Implementation /// @{ From lattner at cs.uiuc.edu Tue Nov 9 14:47:44 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 Nov 2004 14:47:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Message-ID: <200411092047.iA9KliKA022078@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: IPConstantPropagation.cpp updated: 1.9 -> 1.10 --- Log message: Do not let dead constant expressions hanging off of functions prevent IPCP. This allows to elimination of a bunch of global pool descriptor args from programs being pool allocated (and is also generally useful!) --- Diffs of the changes: (+3 -0) Index: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp diff -u llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.9 llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.10 --- llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.9 Sun Sep 19 23:43:34 2004 +++ llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Tue Nov 9 14:47:30 2004 @@ -62,6 +62,9 @@ bool IPCP::processFunction(Function &F) { if (F.aempty() || F.use_empty()) return false; // No arguments? Early exit. + // Delete any klingons. + F.removeDeadConstantUsers(); + std::vector > ArgumentConstants; ArgumentConstants.resize(F.asize()); From gaeke at cs.uiuc.edu Tue Nov 9 15:39:33 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue, 9 Nov 2004 15:39:33 -0600 (CST) Subject: [llvm-commits] CVS: reopt/test/TEST.reopt.Makefile Message-ID: <200411092139.PAA10869@kain.cs.uiuc.edu> Changes in directory reopt/test: TEST.reopt.Makefile updated: 1.28 -> 1.29 --- Log message: Because we have to link in the compressor, we also have to link in -lz. --- Diffs of the changes: (+1 -1) Index: reopt/test/TEST.reopt.Makefile diff -u reopt/test/TEST.reopt.Makefile:1.28 reopt/test/TEST.reopt.Makefile:1.29 --- reopt/test/TEST.reopt.Makefile:1.28 Fri Oct 15 14:37:43 2004 +++ reopt/test/TEST.reopt.Makefile Tue Nov 9 15:39:21 2004 @@ -31,7 +31,7 @@ REOPTIMIZER_LIB = $(REOPTLIBDIR)/libwholereoptimizer.a # Solaris libraries that the Reoptimizer depends on -REOPTIMIZER_SOLARISLIBS = -lcpc -lm -lrt -lmalloc -ldl +REOPTIMIZER_SOLARISLIBS = -lcpc -lm -lrt -lmalloc -ldl -lz .PRECIOUS: Output/%.out-reopt-llc From gaeke at cs.uiuc.edu Tue Nov 9 15:40:57 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue, 9 Nov 2004 15:40:57 -0600 (CST) Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Message-ID: <200411092140.PAA10890@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: RuntimeOptimizations.cpp updated: 1.56 -> 1.57 --- Log message: Add a comment. --- Diffs of the changes: (+1 -0) Index: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp diff -u reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.56 reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.57 --- reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.56 Fri Oct 15 14:31:20 2004 +++ reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Tue Nov 9 15:40:47 2004 @@ -96,6 +96,7 @@ // Turn the vector of basic blocks into a Trace. Trace T (vBB); + // Currently we can't optimize traces that contain calls. if (TraceContainsCall (T)) return false; From gaeke at cs.uiuc.edu Tue Nov 9 15:41:05 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue, 9 Nov 2004 15:41:05 -0600 (CST) Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/SecondTrigger.cpp Message-ID: <200411092141.PAA10896@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: SecondTrigger.cpp updated: 1.36 -> 1.37 --- Log message: Add some statistics. --- Diffs of the changes: (+7 -0) Index: reopt/lib/LightWtProfiling/SecondTrigger.cpp diff -u reopt/lib/LightWtProfiling/SecondTrigger.cpp:1.36 reopt/lib/LightWtProfiling/SecondTrigger.cpp:1.37 --- reopt/lib/LightWtProfiling/SecondTrigger.cpp:1.36 Mon Oct 4 15:15:27 2004 +++ reopt/lib/LightWtProfiling/SecondTrigger.cpp Tue Nov 9 15:40:55 2004 @@ -19,6 +19,7 @@ #include "ReoptimizerInternal.h" #include "RegSaveRestore.h" #include "llvm/ADT/SetVector.h" +#include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" #include "llvm/Function.h" #include "llvm/Instructions.h" @@ -50,6 +51,10 @@ static std::map > backOffCounters; std::map firstTriggerAddr; + +static Statistic FoundTraces ("reopt", "Number of traces found"); +static Statistic RejectedTraces ("reopt", + "Number of traces rejected by trace optimizer"); extern "C" void llvm_time_start(){ cpc_count_usr_events(1); @@ -552,12 +557,14 @@ // Check whether to use the new trace optimizer which works on // vectors of llvm basic blocks, or the old trace layout engine // which works on SPARC instructions. + ++FoundTraces; if (enable_trace_optimizer) { //use path 0 to form vBB std::vector vBB; constructFullVBB (paths, start, vBB); if (vBB.empty()) return; if (!optimizeTrace (vBB, firstLevelTraceStartAddr)) { + ++RejectedTraces; // give up. tr->patchTrace(firstLevelTraceStartAddr); vm->writeBranchInstruction(firstLevelTraceStartAddr, start); From criswell at cs.uiuc.edu Tue Nov 9 22:48:29 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 9 Nov 2004 22:48:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200411100448.WAA10126@choi.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.111 -> 1.112 --- Log message: Correct the name of stosd for the AT&T syntax: It's stosl (l for long == 32 bit). --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.111 llvm/lib/Target/X86/X86InstrInfo.td:1.112 --- llvm/lib/Target/X86/X86InstrInfo.td:1.111 Wed Oct 6 09:31:50 2004 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Nov 9 22:48:15 2004 @@ -248,7 +248,7 @@ Imp<[AL,ECX,EDI], [ECX,EDI]>, REP; def REP_STOSW : I<0xAB, RawFrm, (ops), "{rep;stosw|rep stosw}">, Imp<[AX,ECX,EDI], [ECX,EDI]>, REP, OpSize; -def REP_STOSD : I<0xAB, RawFrm, (ops), "{rep;stosd|rep stosd}">, +def REP_STOSD : I<0xAB, RawFrm, (ops), "{rep;stosl|rep stosd}">, Imp<[EAX,ECX,EDI], [ECX,EDI]>, REP; From lattner at cs.uiuc.edu Tue Nov 9 23:11:20 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 Nov 2004 23:11:20 -0600 Subject: [llvm-commits] CVS: poolalloc/test/TEST.perf.Makefile TEST.perf.report Message-ID: <200411100511.XAA10573@choi.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.perf.Makefile updated: 1.12 -> 1.13 TEST.perf.report updated: 1.2 -> 1.3 --- Log message: Change the report to print L1,L2, and TLB misses. Since we have an extra slot, print out information about misaligned data refs. --- Diffs of the changes: (+44 -36) Index: poolalloc/test/TEST.perf.Makefile diff -u poolalloc/test/TEST.perf.Makefile:1.12 poolalloc/test/TEST.perf.Makefile:1.13 --- poolalloc/test/TEST.perf.Makefile:1.12 Mon Nov 8 21:33:50 2004 +++ poolalloc/test/TEST.perf.Makefile Tue Nov 9 23:11:09 2004 @@ -17,12 +17,15 @@ # # Events for the AMD K7 (Athlon) processors # -K7_REFILL_SYSTEM := 0x00411F43 -K7_REFILL_L2 := 0x00411F42 -K7_CACHE_MISSES := 0x00410041 -K7_CACHE_ACCESSES := 0x00410040 +K7_REFILL_SYSTEM := 0x00411F43 +K7_REFILL_L2 := 0x00411F42 +#K7_CACHE_MISSES := 0x00410041 +#K7_CACHE_ACCESSES := 0x00410040 +K7_TLB_MISSES := 0x00410046 +K7_MISALIGNED_DATA := 0x00410047 -K7_EVENTS := -e $(K7_REFILL_SYSTEM) -e $(K7_REFILL_L2) -e $(K7_CACHE_MISSES) -e $(K7_CACHE_ACCESSES) +K7_EVENTS := -e $(K7_REFILL_SYSTEM) -e $(K7_REFILL_L2) \ + -e $(K7_MISALIGNED_DATA) -e $(K7_TLB_MISSES) # # Events for the Pentium 4/Xeon processors @@ -49,6 +52,14 @@ Output/$(TEST).cacheaccesses.pa.%: Output/test.$(TEST).pa.% $(VERB) grep $(K7_CACHE_ACCESSES) $< | awk '{print $$(NF)}' > $@ +$(PROGRAMS_TO_TEST:%=Output/$(TEST).tlbmisses.%): \ +Output/$(TEST).tlbmisses.%: Output/test.$(TEST).% + $(VERB) grep $(K7_TLB_MISSES) $< | awk '{print $$(NF)}' > $@ + +$(PROGRAMS_TO_TEST:%=Output/$(TEST).tlbmisses.pa.%): \ +Output/$(TEST).tlbmisses.pa.%: Output/test.$(TEST).pa.% + $(VERB) grep $(K7_TLB_MISSES) $< | awk '{print $$(NF)}' > $@ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).cachemisses.%): \ Output/$(TEST).cachemisses.%: Output/test.$(TEST).% $(VERB) grep $(K7_CACHE_MISSES) $< | awk '{print $$(NF)}' > $@ @@ -57,6 +68,14 @@ Output/$(TEST).cachemisses.pa.%: Output/test.$(TEST).pa.% $(VERB) grep $(K7_CACHE_MISSES) $< | awk '{print $$(NF)}' > $@ +$(PROGRAMS_TO_TEST:%=Output/$(TEST).misaligned.%): \ +Output/$(TEST).misaligned.%: Output/test.$(TEST).% + $(VERB) grep $(K7_MISALIGNED_DATA) $< | awk '{print $$(NF)}' > $@ + +$(PROGRAMS_TO_TEST:%=Output/$(TEST).misaligned.pa.%): \ +Output/$(TEST).misaligned.pa.%: Output/test.$(TEST).pa.% + $(VERB) grep $(K7_MISALIGNED_DATA) $< | awk '{print $$(NF)}' > $@ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).L1Misses.%): \ Output/$(TEST).L1Misses.%: Output/test.$(TEST).% $(VERB) grep $(K7_REFILL_SYSTEM) $< | awk '{print $$(NF)}' > $@ @@ -106,11 +125,7 @@ Output/test.$(TEST).pa.%: Output/%.poolalloc.cbe Output/test.$(TEST).% @echo "=========================================" @echo "Running '$(TEST)' test on '$(TESTNAME)' program" -ifeq ($(RUN_OPTIONS),) - $(VERB) cat $(STDIN_FILENAME) | $(PERFEX) -o $@ $(EVENTS) $< > /dev/null -else - $(VERB) cat $(STDIN_FILENAME) | $(PERFEX) -o $@ $(EVENTS) $< $(RUN_OPTIONS) > /dev/null -endif + -$(PERFEX) -o $@ $(EVENTS) $< $(RUN_OPTIONS) > /dev/null < $(STDIN_FILENAME) # # Generate events for CBE @@ -119,11 +134,7 @@ Output/test.$(TEST).%: Output/%.nonpa.cbe @echo "=========================================" @echo "Running '$(TEST)' test on '$(TESTNAME)' program" -ifeq ($(RUN_OPTIONS),) - $(VERB) cat $(STDIN_FILENAME) | $(PERFEX) -o $@ $(EVENTS) $< > /dev/null -else - $(VERB) cat $(STDIN_FILENAME) | $(PERFEX) -o $@ $(EVENTS) $< $(RUN_OPTIONS) > /dev/null -endif + -$(PERFEX) -o $@ $(EVENTS) $< $(RUN_OPTIONS) > /dev/null < $(STDIN_FILENAME) else @@ -149,20 +160,20 @@ ############################################################################ ifeq ($(EVENTS),$(K7_EVENTS)) $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ -Output/%.$(TEST).report.txt: $(PROGRAMS_TO_TEST:%=Output/$(TEST).cacheaccesses.%) \ - $(PROGRAMS_TO_TEST:%=Output/$(TEST).cacheaccesses.pa.%) \ - $(PROGRAMS_TO_TEST:%=Output/$(TEST).cachemisses.%) \ - $(PROGRAMS_TO_TEST:%=Output/$(TEST).cachemisses.pa.%) \ +Output/%.$(TEST).report.txt: $(PROGRAMS_TO_TEST:%=Output/$(TEST).tlbmisses.%) \ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).tlbmisses.pa.%) \ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).misaligned.%) \ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).misaligned.pa.%) \ $(PROGRAMS_TO_TEST:%=Output/$(TEST).L1Misses.%) \ $(PROGRAMS_TO_TEST:%=Output/$(TEST).L1Misses.pa.%) \ $(PROGRAMS_TO_TEST:%=Output/$(TEST).L2Misses.%) \ $(PROGRAMS_TO_TEST:%=Output/$(TEST).L2Misses.pa.%) @echo "Program:" $* > $@ @echo "-------------------------------------------------------------" >> $@ - @printf "CBE-PA-Cache-Accesses: %lld\n" `cat Output/$(TEST).cacheaccesses.pa.$*` >> $@ - @printf "CBE-Cache-Accesses: %lld\n" `cat Output/$(TEST).cacheaccesses.$*` >> $@ - @printf "CBE-PA-Cache-Misses: %lld\n" `cat Output/$(TEST).cachemisses.pa.$*` >> $@ - @printf "CBE-Cache-Misses: %lld\n" `cat Output/$(TEST).cachemisses.$*` >> $@ + @printf "CBE-PA-TLB-Misses: %lld\n" `cat Output/$(TEST).tlbmisses.pa.$*` >> $@ + @printf "CBE-TLB-Misses: %lld\n" `cat Output/$(TEST).tlbmisses.$*` >> $@ + @printf "CBE-PA-Misaligned: %lld\n" `cat Output/$(TEST).misaligned.pa.$*` >> $@ + @printf "CBE-Misaligned: %lld\n" `cat Output/$(TEST).misaligned.$*` >> $@ @printf "CBE-PA-L1-Cache-Misses: %lld\n" `cat Output/$(TEST).L1Misses.pa.$*` >> $@ @printf "CBE-L1-Cache-Misses: %lld\n" `cat Output/$(TEST).L1Misses.$*` >> $@ @printf "CBE-PA-L2-Cache-Misses: %lld\n" `cat Output/$(TEST).L2Misses.pa.$*` >> $@ Index: poolalloc/test/TEST.perf.report diff -u poolalloc/test/TEST.perf.report:1.2 poolalloc/test/TEST.perf.report:1.3 --- poolalloc/test/TEST.perf.report:1.2 Mon Nov 8 21:33:50 2004 +++ poolalloc/test/TEST.perf.report Tue Nov 9 23:11:09 2004 @@ -78,19 +78,16 @@ ["Name:" , '\'([^\']+)\' Program'], [], # Times - ["NormUserTime", 'CBE-RUN-TIME-NORMAL-USER: user\s*([.0-9m:]+)', \&FormatTime], - ["NormSysTime", 'CBE-RUN-TIME-NORMAL-SYS: sys\s*([.0-9m:]+)', \&FormatTime], - ["NormCacheAccess", 'CBE-Cache-Accesses: ([0-9]+)'], - ["NormCacheMisses", 'CBE-Cache-Misses: ([0-9]+)'], - ["NormRefillFromL2", 'CBE-L1-Cache-Misses: ([0-9]+)'], - ["NormRefillFromSys", 'CBE-L2-Cache-Misses: ([.0-9]+)'], - - ["PAUserTime", 'CBE-RUN-TIME-POOLALLOC-USER: user\s*([.0-9m:]+)', \&FormatTime], - ["PASysTime", 'CBE-RUN-TIME-POOLALLOC-SYS: sys\s*([.0-9m:]+)', \&FormatTime], - ["PACacheAccess", 'CBE-PA-Cache-Accesses: ([0-9]+)'], - ["PACacheMisses", 'CBE-PA-Cache-Misses: ([0-9]+)'], - ["PARefillFromL2", 'CBE-PA-L1-Cache-Misses: ([0-9]+)'], - ["PARefillFromSys", 'CBE-PA-L2-Cache-Misses: ([.0-9]+)'], + ["L1 Misses", 'CBE-L1-Cache-Misses: ([0-9]+)'], + ["L2 Misses", 'CBE-L2-Cache-Misses: ([.0-9]+)'], + ["TLBMisses", 'CBE-TLB-Misses: ([0-9]+)'], + ["Misaligned", 'CBE-Misaligned: ([0-9]+)'], + [], +# ["PACacheMisses", 'CBE-PA-Cache-Misses: ([0-9]+)'], + ["PA L1 Misses", 'CBE-PA-L1-Cache-Misses: ([0-9]+)'], + ["PA L2 Misses", 'CBE-PA-L2-Cache-Misses: ([.0-9]+)'], + ["PA TLB Misses", 'CBE-PA-TLB-Misses: ([0-9]+)'], + ["PA Misaligned", 'CBE-PA-Misaligned: ([0-9]+)'], [] ); From lattner at cs.uiuc.edu Tue Nov 9 23:49:47 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 Nov 2004 23:49:47 -0600 Subject: [llvm-commits] CVS: poolalloc/test/TEST.perf.Makefile TEST.perf.report Message-ID: <200411100549.iAA5nlci027872@apoc.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.perf.Makefile updated: 1.13 -> 1.14 TEST.perf.report updated: 1.3 -> 1.4 --- Log message: Add run time into the table, discard stderr output --- Diffs of the changes: (+12 -15) Index: poolalloc/test/TEST.perf.Makefile diff -u poolalloc/test/TEST.perf.Makefile:1.13 poolalloc/test/TEST.perf.Makefile:1.14 --- poolalloc/test/TEST.perf.Makefile:1.13 Tue Nov 9 23:11:09 2004 +++ poolalloc/test/TEST.perf.Makefile Tue Nov 9 23:49:37 2004 @@ -125,7 +125,7 @@ Output/test.$(TEST).pa.%: Output/%.poolalloc.cbe Output/test.$(TEST).% @echo "=========================================" @echo "Running '$(TEST)' test on '$(TESTNAME)' program" - -$(PERFEX) -o $@ $(EVENTS) $< $(RUN_OPTIONS) > /dev/null < $(STDIN_FILENAME) + -$(PERFEX) -o $@ $(EVENTS) $< $(RUN_OPTIONS) > /dev/null 2>&1 < $(STDIN_FILENAME) # # Generate events for CBE @@ -134,7 +134,7 @@ Output/test.$(TEST).%: Output/%.nonpa.cbe @echo "=========================================" @echo "Running '$(TEST)' test on '$(TESTNAME)' program" - -$(PERFEX) -o $@ $(EVENTS) $< $(RUN_OPTIONS) > /dev/null < $(STDIN_FILENAME) + -$(PERFEX) -o $@ $(EVENTS) $< $(RUN_OPTIONS) > /dev/null 2>&1 < $(STDIN_FILENAME) else @@ -178,14 +178,10 @@ @printf "CBE-L1-Cache-Misses: %lld\n" `cat Output/$(TEST).L1Misses.$*` >> $@ @printf "CBE-PA-L2-Cache-Misses: %lld\n" `cat Output/$(TEST).L2Misses.pa.$*` >> $@ @printf "CBE-L2-Cache-Misses: %lld\n" `cat Output/$(TEST).L2Misses.$*` >> $@ - @printf "CBE-RUN-TIME-NORMAL-USER: " >> $@ - @grep "^user" Output/$*.nonpa.out-cbe.time >> $@ - @printf "CBE-RUN-TIME-NORMAL-SYS: " >> $@ - @grep "^sys" Output/$*.nonpa.out-cbe.time >> $@ - @printf "CBE-RUN-TIME-POOLALLOC-USER: " >> $@ - @grep "^user" Output/$*.poolalloc.out-cbe.time >> $@ - @printf "CBE-RUN-TIME-POOLALLOC-SYS: " >> $@ - @grep "^sys" Output/$*.poolalloc.out-cbe.time >> $@ + @printf "CBE-RUN-TIME: " >> $@ + @grep "^program" Output/$*.nonpa.out-cbe.time >> $@ + @printf "CBE-PA-RUN-TIME: " >> $@ + @grep "^program" Output/$*.poolalloc.out-cbe.time >> $@ endif ifeq ($(EVENTS),$(P4_EVENTS)) Index: poolalloc/test/TEST.perf.report diff -u poolalloc/test/TEST.perf.report:1.3 poolalloc/test/TEST.perf.report:1.4 --- poolalloc/test/TEST.perf.report:1.3 Tue Nov 9 23:11:09 2004 +++ poolalloc/test/TEST.perf.report Tue Nov 9 23:49:37 2004 @@ -78,16 +78,17 @@ ["Name:" , '\'([^\']+)\' Program'], [], # Times + ["Time", 'CBE-RUN-TIME: ([0-9]+)'], ["L1 Misses", 'CBE-L1-Cache-Misses: ([0-9]+)'], ["L2 Misses", 'CBE-L2-Cache-Misses: ([.0-9]+)'], ["TLBMisses", 'CBE-TLB-Misses: ([0-9]+)'], ["Misaligned", 'CBE-Misaligned: ([0-9]+)'], [], -# ["PACacheMisses", 'CBE-PA-Cache-Misses: ([0-9]+)'], - ["PA L1 Misses", 'CBE-PA-L1-Cache-Misses: ([0-9]+)'], - ["PA L2 Misses", 'CBE-PA-L2-Cache-Misses: ([.0-9]+)'], - ["PA TLB Misses", 'CBE-PA-TLB-Misses: ([0-9]+)'], - ["PA Misaligned", 'CBE-PA-Misaligned: ([0-9]+)'], + ["PA Time", 'CBE-PA-RUN-TIME: ([0-9]+)'], + ["PA L1 Misses", 'CBE-PA-L1-Cache-Misses: ([0-9]+)'], + ["PA L2 Misses", 'CBE-PA-L2-Cache-Misses: ([.0-9]+)'], + ["PA TLB Misses", 'CBE-PA-TLB-Misses: ([0-9]+)'], + ["PA Misaligned", 'CBE-PA-Misaligned: ([0-9]+)'], [] ); From lattner at cs.uiuc.edu Wed Nov 10 00:44:49 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 00:44:49 -0600 Subject: [llvm-commits] CVS: poolalloc/test/TEST.perf.Makefile TEST.perf.report Message-ID: <200411100644.iAA6in7v028808@apoc.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.perf.Makefile updated: 1.14 -> 1.15 TEST.perf.report updated: 1.4 -> 1.5 --- Log message: Print time correctly in the report --- Diffs of the changes: (+5 -3) Index: poolalloc/test/TEST.perf.Makefile diff -u poolalloc/test/TEST.perf.Makefile:1.14 poolalloc/test/TEST.perf.Makefile:1.15 --- poolalloc/test/TEST.perf.Makefile:1.14 Tue Nov 9 23:49:37 2004 +++ poolalloc/test/TEST.perf.Makefile Wed Nov 10 00:44:39 2004 @@ -167,7 +167,9 @@ $(PROGRAMS_TO_TEST:%=Output/$(TEST).L1Misses.%) \ $(PROGRAMS_TO_TEST:%=Output/$(TEST).L1Misses.pa.%) \ $(PROGRAMS_TO_TEST:%=Output/$(TEST).L2Misses.%) \ - $(PROGRAMS_TO_TEST:%=Output/$(TEST).L2Misses.pa.%) + $(PROGRAMS_TO_TEST:%=Output/$(TEST).L2Misses.pa.%) \ + $(PROGRAMS_TO_TEST:%=Output/%.poolalloc.out-cbe.time) \ + $(PROGRAMS_TO_TEST:%=Output/%.nonpa.out-cbe.time) @echo "Program:" $* > $@ @echo "-------------------------------------------------------------" >> $@ @printf "CBE-PA-TLB-Misses: %lld\n" `cat Output/$(TEST).tlbmisses.pa.$*` >> $@ Index: poolalloc/test/TEST.perf.report diff -u poolalloc/test/TEST.perf.report:1.4 poolalloc/test/TEST.perf.report:1.5 --- poolalloc/test/TEST.perf.report:1.4 Tue Nov 9 23:49:37 2004 +++ poolalloc/test/TEST.perf.report Wed Nov 10 00:44:39 2004 @@ -78,13 +78,13 @@ ["Name:" , '\'([^\']+)\' Program'], [], # Times - ["Time", 'CBE-RUN-TIME: ([0-9]+)'], + ["Time", 'CBE-RUN-TIME: program\s*([0-9.m]+)'], ["L1 Misses", 'CBE-L1-Cache-Misses: ([0-9]+)'], ["L2 Misses", 'CBE-L2-Cache-Misses: ([.0-9]+)'], ["TLBMisses", 'CBE-TLB-Misses: ([0-9]+)'], ["Misaligned", 'CBE-Misaligned: ([0-9]+)'], [], - ["PA Time", 'CBE-PA-RUN-TIME: ([0-9]+)'], + ["PA Time", 'CBE-PA-RUN-TIME: program\s*([0-9.m]+)'], ["PA L1 Misses", 'CBE-PA-L1-Cache-Misses: ([0-9]+)'], ["PA L2 Misses", 'CBE-PA-L2-Cache-Misses: ([.0-9]+)'], ["PA TLB Misses", 'CBE-PA-TLB-Misses: ([0-9]+)'], From lattner at cs.uiuc.edu Wed Nov 10 02:08:52 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 02:08:52 -0600 Subject: [llvm-commits] CVS: poolalloc/test/TEST.perf.Makefile Message-ID: <200411100808.iAA88pC5029647@apoc.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.perf.Makefile updated: 1.15 -> 1.16 --- Log message: Make sure to rerun the perf test if the pool alloc test results changed! --- Diffs of the changes: (+2 -0) Index: poolalloc/test/TEST.perf.Makefile diff -u poolalloc/test/TEST.perf.Makefile:1.15 poolalloc/test/TEST.perf.Makefile:1.16 --- poolalloc/test/TEST.perf.Makefile:1.15 Wed Nov 10 00:44:39 2004 +++ poolalloc/test/TEST.perf.Makefile Wed Nov 10 02:08:41 2004 @@ -209,3 +209,5 @@ @echo "---------------------------------------------------------------" @cat $< +REPORT_DEPENDENCIES := $(PROGRAMS_TO_TEST:%=Output/%.poolalloc.out-cbe.time) \ + $(PROGRAMS_TO_TEST:%=Output/%.nonpa.out-cbe.time) From lattner at cs.uiuc.edu Wed Nov 10 02:43:16 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 02:43:16 -0600 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/anagram.c Message-ID: <200411100843.iAA8hGdx029829@apoc.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Benchmarks/Ptrdist/anagram: anagram.c updated: 1.1 -> 1.2 --- Log message: Reduce the amount of pointless IO this program does --- Diffs of the changes: (+4 -1) Index: llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/anagram.c diff -u llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/anagram.c:1.1 llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/anagram.c:1.2 --- llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/anagram.c:1.1 Fri Feb 14 13:57:03 2003 +++ llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/anagram.c Wed Nov 10 02:43:01 2004 @@ -479,7 +479,10 @@ ) /* End of debug code */ void DumpWords(void) { - int i; +static int X; + int i; + X = (X+1) & 1023; + if (X != 0) return; for (i = 0; i < cpwLast; i++) wprint(apwSol[i]->pchWord); printf("\n"); } From lattner at cs.uiuc.edu Wed Nov 10 02:43:59 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 02:43:59 -0600 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/Makefile Message-ID: <200411100843.iAA8hxcs029845@apoc.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Benchmarks/Ptrdist/anagram: Makefile updated: 1.8 -> 1.9 --- Log message: Increase the problem size for this a bit --- Diffs of the changes: (+1 -1) Index: llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/Makefile diff -u llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/Makefile:1.8 llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/Makefile:1.9 --- llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/Makefile:1.8 Fri Nov 5 15:47:55 2004 +++ llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/Makefile Wed Nov 10 02:43:47 2004 @@ -4,7 +4,7 @@ PROG = anagram #OBJS = anagram.o -RUN_OPTIONS = $(BUILD_SRC_DIR)/words +RUN_OPTIONS = $(BUILD_SRC_DIR)/words 2 STDIN_FILENAME = $(BUILD_SRC_DIR)/input.OUT include $(LEVEL)/MultiSource/Makefile.multisrc From lattner at cs.uiuc.edu Wed Nov 10 13:43:36 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 13:43:36 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/IPConstantProp/ Message-ID: <200411101943.iAAJhahi002156@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/IPConstantProp: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/test/Regression/Transforms/IPConstantProp added to the repository --- Diffs of the changes: (+0 -0) From lattner at cs.uiuc.edu Wed Nov 10 13:43:45 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 13:43:45 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/IPConstantProp/recursion.ll Message-ID: <200411101943.iAAJhjNI002166@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/IPConstantProp: recursion.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: (+14 -0) Index: llvm/test/Regression/Transforms/IPConstantProp/recursion.ll diff -c /dev/null llvm/test/Regression/Transforms/IPConstantProp/recursion.ll:1.1 *** /dev/null Wed Nov 10 13:43:41 2004 --- llvm/test/Regression/Transforms/IPConstantProp/recursion.ll Wed Nov 10 13:43:31 2004 *************** *** 0 **** --- 1,14 ---- + ; RUN: llvm-as < %s | opt -ipconstprop -deadargelim | llvm-dis | not grep %X + + implementation + + internal int %foo(int %X) { + %Y = call int %foo( int %X ) + %Z = add int %Y, 1 + ret int %Z + } + + void %bar() { + call int %foo( int 17 ) ; :0 [#uses=0] + ret void + } From lattner at cs.uiuc.edu Wed Nov 10 13:44:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 13:44:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Message-ID: <200411101944.iAAJiBve002177@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: IPConstantPropagation.cpp updated: 1.10 -> 1.11 --- Log message: Make IP Constant prop more aggressive about handling self recursive calls. This implements IPConstantProp/recursion.ll --- Diffs of the changes: (+4 -2) Index: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp diff -u llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.10 llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.11 --- llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.10 Tue Nov 9 14:47:30 2004 +++ llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Wed Nov 10 13:43:59 2004 @@ -81,7 +81,9 @@ // Check out all of the potentially constant arguments CallSite::arg_iterator AI = CS.arg_begin(); - for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) { + Function::aiterator Arg = F.abegin(); + for (unsigned i = 0, e = ArgumentConstants.size(); i != e; + ++i, ++AI, ++Arg) { if (*AI == &F) return false; // Passes the function into itself if (!ArgumentConstants[i].second) { @@ -94,7 +96,7 @@ ++NumNonconstant; if (NumNonconstant == ArgumentConstants.size()) return false; } - } else { + } else if (*AI != &*Arg) { // Ignore recursive calls with same arg // This is not a constant argument. Mark the argument as // non-constant. ArgumentConstants[i].second = true; From criswell at cs.uiuc.edu Wed Nov 10 13:49:43 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed, 10 Nov 2004 13:49:43 -0600 (CST) Subject: [llvm-commits] CVS: llvm-test/RunSafelyAndStable.sh Message-ID: <200411101949.NAA07592@kain.cs.uiuc.edu> Changes in directory llvm-test: RunSafelyAndStable.sh updated: 1.2 -> 1.3 --- Log message: Solaris sed doesn't like comments. --- Diffs of the changes: (+2 -2) Index: llvm-test/RunSafelyAndStable.sh diff -u llvm-test/RunSafelyAndStable.sh:1.2 llvm-test/RunSafelyAndStable.sh:1.3 --- llvm-test/RunSafelyAndStable.sh:1.2 Sun Nov 7 15:28:32 2004 +++ llvm-test/RunSafelyAndStable.sh Wed Nov 10 13:49:27 2004 @@ -76,7 +76,7 @@ (time -p sh -c "$PROGRAM $* > $OUTFILE 2>&1 < $INFILE") 2>&1 | awk -- '\ BEGIN { cpu = 0.0; } -/^real/ { /* IGNORE */; print } +/^real/ { print } /^user/ { cpu += $2; print } /^sys/ { cpu += $2; print } !/^real/ && !/^user/ && !/^sys/ { print } @@ -87,7 +87,7 @@ (time -p sh -c "$PROGRAM $* > $OUTFILE 2>&1 < $INFILE") 2>&1 | awk -- '\ BEGIN { cpu = 0.0; } -/^real/ { /* IGNORE */; print } +/^real/ { print } /^user/ { cpu += $2; print } /^sys/ { cpu += $2; print } !/^real/ && !/^user/ && !/^sys/ { print } From lattner at cs.uiuc.edu Wed Nov 10 15:13:58 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 15:13:58 -0600 Subject: [llvm-commits] CVS: poolalloc/lib/PoolAllocate/Heuristic.cpp Heuristic.h PoolAllocate.cpp PoolAllocate.h Message-ID: <200411102113.iAALDvGQ003764@apoc.cs.uiuc.edu> Changes in directory poolalloc/lib/PoolAllocate: Heuristic.cpp updated: 1.3 -> 1.4 Heuristic.h updated: 1.1 -> 1.2 PoolAllocate.cpp updated: 1.90 -> 1.91 PoolAllocate.h updated: 1.30 -> 1.31 --- Log message: Make intelligent alignment decisions. In particular, align a pool to 8 bytes (like malloc would) unless we can tell that there is no data in the pool that requires 8-byte alignment. In this case, only request 4-byte alignment. --- Diffs of the changes: (+63 -13) Index: poolalloc/lib/PoolAllocate/Heuristic.cpp diff -u poolalloc/lib/PoolAllocate/Heuristic.cpp:1.3 poolalloc/lib/PoolAllocate/Heuristic.cpp:1.4 --- poolalloc/lib/PoolAllocate/Heuristic.cpp:1.3 Tue Nov 9 14:16:25 2004 +++ poolalloc/lib/PoolAllocate/Heuristic.cpp Wed Nov 10 15:13:47 2004 @@ -19,6 +19,7 @@ #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetData.h" +#include using namespace llvm; using namespace PA; @@ -51,13 +52,53 @@ unsigned Heuristic::getRecommendedSize(DSNode *N) { unsigned PoolSize = 0; if (!N->isArray() && N->getType()->isSized()) { - DSGraph *G = N->getParentGraph(); - PoolSize = G->getTargetData().getTypeSize(N->getType()); + PoolSize = N->getParentGraph()->getTargetData().getTypeSize(N->getType()); } if (PoolSize == 1) PoolSize = 0; return PoolSize; } +/// Wants8ByteAlignment - FIXME: this is a complete hack for X86 right now. +static bool Wants8ByteAlignment(const Type *Ty, unsigned Offs, + const TargetData &TD) { + if (Ty == Type::DoubleTy && (Offs & 7) == 0) + return true; + if (Ty->isPrimitiveType() || isa(Ty)) + return false; + + if (const StructType *STy = dyn_cast(Ty)) { + const StructLayout *SL = TD.getStructLayout(STy); + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + if (Wants8ByteAlignment(STy->getElementType(i), + Offs+SL->MemberOffsets[i], TD)) + return true; + } + } else if (const SequentialType *STy = dyn_cast(Ty)) { + return Wants8ByteAlignment(STy->getElementType(), Offs, TD); + } else { + std::cerr << *Ty << "\n"; + assert(0 && "Unknown type!"); + } + return false; +} + + + +/// getRecommendedAlignment - Return the recommended object alignment for this +/// DSNode. +/// +unsigned Heuristic::getRecommendedAlignment(DSNode *N) { + if (N->getType() == Type::VoidTy) // Is this void or collapsed? + return 0; // No known alignment, let runtime decide. + + const TargetData &TD = N->getParentGraph()->getTargetData(); + + // If there are no doubles on an 8-byte boundary in this structure, there is + // no reason to 8-byte align objects in the pool. + return Wants8ByteAlignment(N->getType(), 0, TD) ? 8 : 4; +} + + //===-- AllNodes Heuristic ------------------------------------------------===// // // This heuristic pool allocates everything possible into separate pools. @@ -337,7 +378,7 @@ Function *F, DSGraph &G, std::vector &ResultPools) { if (TheGlobalPD == 0) - TheGlobalPD = PA->CreateGlobalPool(0); + TheGlobalPD = PA->CreateGlobalPool(0, 0); // All nodes allocate from the same global pool. OnePool Pool; Index: poolalloc/lib/PoolAllocate/Heuristic.h diff -u poolalloc/lib/PoolAllocate/Heuristic.h:1.1 poolalloc/lib/PoolAllocate/Heuristic.h:1.2 --- poolalloc/lib/PoolAllocate/Heuristic.h:1.1 Mon Nov 8 00:18:07 2004 +++ poolalloc/lib/PoolAllocate/Heuristic.h Wed Nov 10 15:13:47 2004 @@ -58,13 +58,16 @@ // PoolSize - If the pool is to be created, indicate the "recommended // size" for the pool here. This gets passed into poolinit. unsigned PoolSize; + unsigned PoolAlignment; - OnePool() : PoolDesc(0), PoolSize(0) {} + OnePool() : PoolDesc(0), PoolSize(0), PoolAlignment(0) {} - OnePool(DSNode *N) : PoolDesc(0), PoolSize(getRecommendedSize(N)) { + OnePool(DSNode *N) : PoolDesc(0), PoolSize(getRecommendedSize(N)), + PoolAlignment(getRecommendedAlignment(N)) { NodesInPool.push_back(N); } - OnePool(DSNode *N, Value *PD) : PoolDesc(PD), PoolSize(0) { + OnePool(DSNode *N, Value *PD) : PoolDesc(PD), PoolSize(0), + PoolAlignment(0) { NodesInPool.push_back(N); } }; @@ -83,6 +86,11 @@ /// static unsigned getRecommendedSize(DSNode *N); + /// getRecommendedAlignment - Return the recommended object alignment for + /// this DSNode. + /// + static unsigned getRecommendedAlignment(DSNode *N); + /// create - This static ctor creates the heuristic, based on the command /// line argument to choose the heuristic. static Heuristic *create(); Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.90 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.91 --- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.90 Tue Nov 9 14:25:39 2004 +++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp Wed Nov 10 15:13:47 2004 @@ -407,7 +407,7 @@ Heuristic::OnePool &Pool = ResultPools[i]; Value *PoolDesc = Pool.PoolDesc; if (PoolDesc == 0) { - PoolDesc = CreateGlobalPool(Pool.PoolSize, InsertPt); + PoolDesc = CreateGlobalPool(Pool.PoolSize, Pool.PoolAlignment, InsertPt); if (Pool.NodesInPool.size() == 1 && !Pool.NodesInPool[0]->isNodeCompletelyFolded()) @@ -429,7 +429,7 @@ return false; } -GlobalVariable *PoolAllocate::CreateGlobalPool(unsigned RecSize, +GlobalVariable *PoolAllocate::CreateGlobalPool(unsigned RecSize, unsigned Align, Instruction *IPHint) { GlobalVariable *GV = new GlobalVariable(PoolDescType, false, GlobalValue::InternalLinkage, @@ -447,10 +447,9 @@ while (isa(InsertPt)) ++InsertPt; } - unsigned Alignment = 0; Value *ElSize = ConstantUInt::get(Type::UIntTy, RecSize); - Value *Align = ConstantUInt::get(Type::UIntTy, Alignment); - new CallInst(PoolInit, make_vector((Value*)GV, ElSize, Align, 0), + Value *AlignV = ConstantUInt::get(Type::UIntTy, Align); + new CallInst(PoolInit, make_vector((Value*)GV, ElSize, AlignV, 0), "", InsertPt); ++NumPools; return GV; @@ -783,7 +782,8 @@ // Insert the calls to initialize the pool. unsigned ElSizeV = Heuristic::getRecommendedSize(Node); Value *ElSize = ConstantUInt::get(Type::UIntTy, ElSizeV); - Value *Align = ConstantUInt::get(Type::UIntTy, 0); + unsigned AlignV = Heuristic::getRecommendedAlignment(Node); + Value *Align = ConstantUInt::get(Type::UIntTy, AlignV); for (unsigned i = 0, e = PoolInitPoints.size(); i != e; ++i) { new CallInst(PoolInit, make_vector((Value*)PD, ElSize, Align, 0), Index: poolalloc/lib/PoolAllocate/PoolAllocate.h diff -u poolalloc/lib/PoolAllocate/PoolAllocate.h:1.30 poolalloc/lib/PoolAllocate/PoolAllocate.h:1.31 --- poolalloc/lib/PoolAllocate/PoolAllocate.h:1.30 Tue Nov 9 14:25:39 2004 +++ poolalloc/lib/PoolAllocate/PoolAllocate.h Wed Nov 10 15:13:47 2004 @@ -137,7 +137,8 @@ /// CreateGlobalPool - Create a global pool descriptor, initialize it in main, /// and return a pointer to the global for it. - GlobalVariable *CreateGlobalPool(unsigned RecSize, Instruction *IPHint = 0); + GlobalVariable *CreateGlobalPool(unsigned RecSize, unsigned Alignment, + Instruction *IPHint = 0); private: From lattner at cs.uiuc.edu Wed Nov 10 16:02:08 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 16:02:08 -0600 Subject: [llvm-commits] CVS: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp PoolAllocator.h Message-ID: <200411102202.iAAM28S3008490@apoc.cs.uiuc.edu> Changes in directory poolalloc/runtime/FL2Allocator: FreeListAllocator.cpp updated: 1.25 -> 1.26 PoolAllocator.h updated: 1.13 -> 1.14 --- Log message: Add a new API for a simple bump-pointer based allocator. --- Diffs of the changes: (+129 -10) Index: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp diff -u poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.25 poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.26 --- poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.25 Tue Nov 9 14:17:05 2004 +++ poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp Wed Nov 10 16:01:58 2004 @@ -18,6 +18,8 @@ #include #include +typedef long intptr_t; + // Performance tweaking macros. #define INITIAL_SLAB_SIZE 4096 #define LARGE_SLAB_SIZE 4096 @@ -121,6 +123,14 @@ PoolsInited, PoolCounter); } +static void InitPrintNumPools() { + static bool Initialized = 0; + if (!Initialized) { + Initialized = 1; + atexit(PoolCountPrinter); + } +} + #define DO_IF_PNP(X) X #else #define DO_IF_PNP(X) @@ -163,6 +173,7 @@ public: static void create(PoolTy *Pool, unsigned SizeHint); + static void *create_for_bp(PoolTy *Pool); void destroy(); PoolSlab *getNext() const { return Next; } @@ -202,10 +213,118 @@ Pool->Slabs = PS; } +/// create_for_bp - This creates a slab for a bump-pointer pool. +void *PoolSlab::create_for_bp(PoolTy *Pool) { + unsigned Size = Pool->AllocSize; + Pool->AllocSize <<= 1; + PoolSlab *PS = (PoolSlab*)malloc(Size+sizeof(PoolSlab)); + char *PoolBody = (char*)(PS+1); + + // Update the end pointer. + Pool->FreeNodeLists[1] = (FreedNodeHeader*)(PoolBody+Size); + + // Add the slab to the list... + PS->Next = Pool->Slabs; + Pool->Slabs = PS; + return PoolBody; +} + + void PoolSlab::destroy() { free(this); } +//===----------------------------------------------------------------------===// +// +// Bump-pointer pool allocator library implementation +// +//===----------------------------------------------------------------------===// + +void poolinit_bp(PoolTy *Pool, unsigned ObjAlignment) { + DO_IF_PNP(memset(Pool, 0, sizeof(PoolTy))); + Pool->Slabs = 0; + if (ObjAlignment < 4) ObjAlignment = __alignof(double); + Pool->AllocSize = INITIAL_SLAB_SIZE; + Pool->Alignment = ObjAlignment; + Pool->LargeArrays = 0; + Pool->FreeNodeLists[0] = 0; // This is our bump pointer. + Pool->FreeNodeLists[1] = 0; // This is our end pointer. + + DO_IF_TRACE(fprintf(stderr, "[%d] poolinit_bp(0x%X, %d)\n", addPoolNumber(Pool), + Pool, ObjAlignment)); + DO_IF_PNP(++PoolsInited); // Track # pools initialized + DO_IF_PNP(InitPrintNumPools()); +} + +void *poolalloc_bp(PoolTy *Pool, unsigned NumBytes) { + assert(Pool && "Bump pointer pool does not support null PD!"); + DO_IF_TRACE(fprintf(stderr, "[%d] poolalloc_bp(%d) -> ", + getPoolNumber(Pool), NumBytes)); + DO_IF_PNP(if (Pool->NumObjects == 0) ++PoolCounter); // Track # pools. + + if (NumBytes >= LARGE_SLAB_SIZE) + goto LargeObject; + + if (NumBytes < 1) NumBytes = 1; + + unsigned Alignment; + char *BumpPtr, *EndPtr; + Alignment = Pool->Alignment-1; + BumpPtr = (char*)Pool->FreeNodeLists[0]; // Get our bump pointer. + EndPtr = (char*)Pool->FreeNodeLists[1]; // Get our end pointer. + +TryAgain: + // Align the bump pointer to the required boundary. + BumpPtr = (char*)(intptr_t((BumpPtr+Alignment)) & ~Alignment); + + if (BumpPtr + NumBytes < EndPtr) { + void *Result = BumpPtr; + // Update bump ptr. + Pool->FreeNodeLists[0] = (FreedNodeHeader*)(BumpPtr+NumBytes); + DO_IF_TRACE(fprintf(stderr, "0x%X\n", Result)); + return Result; + } + + BumpPtr = (char*)PoolSlab::create_for_bp(Pool); + EndPtr = (char*)Pool->FreeNodeLists[1]; // Get our updated end pointer. + goto TryAgain; + +LargeObject: + // Otherwise, the allocation is a large array. Since we're not going to be + // able to help much for this allocation, simply pass it on to malloc. + LargeArrayHeader *LAH = (LargeArrayHeader*)malloc(sizeof(LargeArrayHeader) + + NumBytes); + LAH->Size = NumBytes; + LAH->Marker = ~0U; + LAH->LinkIntoList(&Pool->LargeArrays); + DO_IF_TRACE(fprintf(stderr, "0x%X [large]\n", LAH+1)); + return LAH+1; +} + +void pooldestroy_bp(PoolTy *Pool) { + assert(Pool && "Null pool pointer passed in to pooldestroy!\n"); + + DO_IF_TRACE(fprintf(stderr, "[%d] pooldestroy_bp", removePoolNumber(Pool))); + DO_IF_POOLDESTROY_STATS(PrintPoolStats(Pool)); + + // Free all allocated slabs. + PoolSlab *PS = Pool->Slabs; + while (PS) { + PoolSlab *Next = PS->getNext(); + PS->destroy(); + PS = Next; + } + + // Free all of the large arrays. + LargeArrayHeader *LAH = Pool->LargeArrays; + while (LAH) { + LargeArrayHeader *Next = LAH->Next; + free(LAH); + LAH = Next; + } +} + + //===----------------------------------------------------------------------===// // @@ -223,17 +342,10 @@ if (ObjAlignment < 4) ObjAlignment = __alignof(double); Pool->Alignment = ObjAlignment; - DO_IF_TRACE(fprintf(stderr, "[%d] poolinit(0x%X, %d)\n", addPoolNumber(Pool), - Pool, DeclaredSize)); + DO_IF_TRACE(fprintf(stderr, "[%d] poolinit(0x%X, %d, %d)\n", + addPoolNumber(Pool), Pool, DeclaredSize, ObjAlignment)); DO_IF_PNP(++PoolsInited); // Track # pools initialized - -#ifdef PRINT_NUM_POOLS - static bool Initialized = 0; - if (!Initialized) { - Initialized = 1; - atexit(PoolCountPrinter); - } -#endif + DO_IF_PNP(InitPrintNumPools()); } // pooldestroy - Release all memory allocated for a pool Index: poolalloc/runtime/FL2Allocator/PoolAllocator.h diff -u poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.13 poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.14 --- poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.13 Tue Nov 9 14:17:05 2004 +++ poolalloc/runtime/FL2Allocator/PoolAllocator.h Wed Nov 10 16:01:58 2004 @@ -121,6 +121,13 @@ /// future. :( /// unsigned poolobjsize(PoolTy *Pool, void *Node); + + // Bump pointer pool library. This is a pool implementation that does not + // support frees or reallocs to the pool. As such, it can be much more + // efficient and simpler than a general pool implementation. + void poolinit_bp(PoolTy *Pool, unsigned ObjAlignment); + void *poolalloc_bp(PoolTy *Pool, unsigned NumBytes); + void pooldestroy_bp(PoolTy *Pool); } #endif From lattner at cs.uiuc.edu Wed Nov 10 16:06:16 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 16:06:16 -0600 Subject: [llvm-commits] CVS: poolalloc/lib/PoolAllocate/PoolAllocate.cpp Message-ID: <200411102206.iAAM6GHu009938@apoc.cs.uiuc.edu> Changes in directory poolalloc/lib/PoolAllocate: PoolAllocate.cpp updated: 1.91 -> 1.92 --- Log message: Instead of making pools local to main have descriptors that are local to main, make them global. This lets IPCP eliminate a lot more of them. --- Diffs of the changes: (+15 -6) Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.91 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.92 --- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.91 Wed Nov 10 15:13:47 2004 +++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp Wed Nov 10 16:06:05 2004 @@ -471,17 +471,26 @@ std::set UnallocatedNodes(NodesToPA.begin(), NodesToPA.end()); - Instruction *InsertPoint = F.front().begin(); + BasicBlock::iterator InsertPoint = F.front().begin(); + while (isa(InsertPoint)) ++InsertPoint; + + // Is this main? If so, make the pool descriptors globals, not automatic + // vars. + bool IsMain = F.getName() == "main" && F.hasExternalLinkage(); // Perform all global assignments as specified. for (unsigned i = 0, e = ResultPools.size(); i != e; ++i) { Heuristic::OnePool &Pool = ResultPools[i]; Value *PoolDesc = Pool.PoolDesc; - if (PoolDesc == 0) - // Create a new alloca instruction for the pool. The poolinit will be - // inserted later. - PoolDesc = new AllocaInst(PoolDescType, 0, "PD", InsertPoint); - + if (PoolDesc == 0) { + // Create a pool descriptor for the pool. The poolinit will be inserted + // later. + if (!IsMain) + PoolDesc = new AllocaInst(PoolDescType, 0, "PD", InsertPoint); + else + PoolDesc = CreateGlobalPool(Pool.PoolSize, Pool.PoolAlignment, + InsertPoint); + } for (unsigned N = 0, e = Pool.NodesInPool.size(); N != e; ++N) { PoolDescriptors[Pool.NodesInPool[N]] = PoolDesc; UnallocatedNodes.erase(Pool.NodesInPool[N]); // Handled! From lattner at cs.uiuc.edu Wed Nov 10 17:39:22 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 17:39:22 -0600 Subject: [llvm-commits] CVS: poolalloc/test/TEST.poolalloc.Makefile TEST.poolalloc.report Message-ID: <200411102339.iAANdM4n018638@apoc.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.poolalloc.Makefile updated: 1.32 -> 1.33 TEST.poolalloc.report updated: 1.23 -> 1.24 --- Log message: Run the new pool optimize pass, report number of bump pointer pools --- Diffs of the changes: (+3 -2) Index: poolalloc/test/TEST.poolalloc.Makefile diff -u poolalloc/test/TEST.poolalloc.Makefile:1.32 poolalloc/test/TEST.poolalloc.Makefile:1.33 --- poolalloc/test/TEST.poolalloc.Makefile:1.32 Mon Nov 8 12:54:40 2004 +++ poolalloc/test/TEST.poolalloc.Makefile Wed Nov 10 17:39:08 2004 @@ -44,12 +44,12 @@ $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).poolalloc.bc): \ Output/%.$(TEST).poolalloc.bc: Output/%.llvm.bc $(PA_SO) $(LOPT) - at rm -f $(CURDIR)/$@.info - -$(OPT_PA_STATS) -poolalloc $(EXTRA_PA_FLAGS) $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out + -$(OPT_PA_STATS) -poolalloc $(EXTRA_PA_FLAGS) $(OPTZN_PASSES) -pooloptimize $< -o $@ -f 2>&1 > $@.out $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).allnodes.bc): \ Output/%.$(TEST).allnodes.bc: Output/%.llvm.bc $(PA_SO) $(LOPT) - at rm -f $(CURDIR)/$@.info - -$(OPT_PA_STATS) -poolalloc -poolalloc-heuristic=AllNodes $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out + -$(OPT_PA_STATS) -poolalloc -poolalloc-heuristic=AllNodes -pooloptimize $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).mallocrepl.bc): \ Index: poolalloc/test/TEST.poolalloc.report diff -u poolalloc/test/TEST.poolalloc.report:1.23 poolalloc/test/TEST.poolalloc.report:1.24 --- poolalloc/test/TEST.poolalloc.report:1.23 Mon Nov 8 00:58:16 2004 +++ poolalloc/test/TEST.poolalloc.report Wed Nov 10 17:39:08 2004 @@ -81,6 +81,7 @@ [], ["NumPools", '([0-9]+).*Number of pools allocated'], ["Typesafe", '([0-9]+).*Number of typesafe pools'], + ["BumpPtr", '([0-9]+).*Number of bump pointer pools'], ["NumArgs", '([0-9]+).*Number of function arguments added'], #["Nonprofit", '([0-9]+).*Number of DSNodes not profitable'], [] From lattner at cs.uiuc.edu Wed Nov 10 17:41:14 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 17:41:14 -0600 Subject: [llvm-commits] CVS: poolalloc/lib/PoolAllocate/PoolAllocate.cpp Message-ID: <200411102341.iAANfELg019431@apoc.cs.uiuc.edu> Changes in directory poolalloc/lib/PoolAllocate: PoolAllocate.cpp updated: 1.92 -> 1.93 --- Log message: These optimizations have been moved to the pooloptimize pass. --- Diffs of the changes: (+3 -10) Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.92 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.93 --- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.92 Wed Nov 10 16:06:05 2004 +++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp Wed Nov 10 17:41:04 2004 @@ -135,8 +135,11 @@ // AddPoolPrototypes - Add prototypes for the pool functions to the specified // module and update the Pool* instance variables to point to them. // +// NOTE: If these are changed, make sure to update PoolOptimize.cpp as well! +// void PoolAllocate::AddPoolPrototypes() { if (VoidPtrTy == 0) { + // NOTE: If these are changed, make sure to update PoolOptimize.cpp as well! VoidPtrTy = PointerType::get(Type::SByteTy); PoolDescType = ArrayType::get(VoidPtrTy, 16); PoolDescPtrTy = PointerType::get(PoolDescType); @@ -207,20 +210,10 @@ // poolalloc never returns null. Loop over all uses of the call looking for // set(eq|ne) X, null. OptimizePointerNotNull(CI); - - // poolalloc(null, X) -> malloc(X) - if (isa(CI->getOperand(0)) && - cast(CI->getOperand(0))->isNullValue()) - std::cerr << "Could turn into malloc: " << *CI; } // TODO: poolfree accepts a null pointer, so remove any check above it, like // 'if (P) poolfree(P)' - - // poolfree(null) -> noop - - // poolrealloc(null, X) -> malloc(X) - } From lattner at cs.uiuc.edu Wed Nov 10 17:41:30 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 17:41:30 -0600 Subject: [llvm-commits] CVS: poolalloc/lib/PoolAllocate/PoolOptimize.cpp Message-ID: <200411102341.iAANfU4w019447@apoc.cs.uiuc.edu> Changes in directory poolalloc/lib/PoolAllocate: PoolOptimize.cpp added (r1.1) --- Log message: This little pass improves pool allocated code in several little ways, including converting pools to use a bump pointer if there are no deallocations to it. --- Diffs of the changes: (+218 -0) Index: poolalloc/lib/PoolAllocate/PoolOptimize.cpp diff -c /dev/null poolalloc/lib/PoolAllocate/PoolOptimize.cpp:1.1 *** /dev/null Wed Nov 10 17:41:30 2004 --- poolalloc/lib/PoolAllocate/PoolOptimize.cpp Wed Nov 10 17:40:49 2004 *************** *** 0 **** --- 1,218 ---- + //===-- PoolOptimize.cpp - Optimize pool allocated program ----------------===// + // + // 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 simple pass optimizes a program that has been through pool allocation. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include "llvm/Instructions.h" + #include "llvm/Pass.h" + #include "llvm/Module.h" + #include "llvm/ADT/Statistic.h" + using namespace llvm; + + namespace { + Statistic<> NumBumpPtr("poolalloc", "Number of bump pointer pools"); + + struct PoolOptimize : public ModulePass { + bool runOnModule(Module &M); + }; + + RegisterOpt + X("pooloptimize", "Optimize a pool allocated program"); + } + + static void getCallsOf(Function *F, std::vector &Calls) { + Calls.clear(); + for (Value::use_iterator UI = F->use_begin(), E = F->use_end(); UI != E; ++UI) + Calls.push_back(cast(*UI)); + } + + bool PoolOptimize::runOnModule(Module &M) { + const Type *VoidPtrTy = PointerType::get(Type::SByteTy); + const Type *PoolDescPtrTy = PointerType::get(ArrayType::get(VoidPtrTy, 16)); + + + // Get poolinit function. + Function *PoolInit = M.getOrInsertFunction("poolinit", Type::VoidTy, + PoolDescPtrTy, Type::UIntTy, + Type::UIntTy, 0); + + // Get pooldestroy function. + Function *PoolDestroy = M.getOrInsertFunction("pooldestroy", Type::VoidTy, + PoolDescPtrTy, 0); + + // The poolalloc function. + Function *PoolAlloc = M.getOrInsertFunction("poolalloc", + VoidPtrTy, PoolDescPtrTy, + Type::UIntTy, 0); + + // The poolrealloc function. + Function *PoolRealloc = M.getOrInsertFunction("poolrealloc", + VoidPtrTy, PoolDescPtrTy, + VoidPtrTy, Type::UIntTy, 0); + + // Get the poolfree function. + Function *PoolFree = M.getOrInsertFunction("poolfree", Type::VoidTy, + PoolDescPtrTy, VoidPtrTy, 0); + + + // Get poolinit_bp function. + Function *PoolInitBP = M.getOrInsertFunction("poolinit_bp", Type::VoidTy, + PoolDescPtrTy, Type::UIntTy, 0); + + // Get pooldestroy_bp function. + Function *PoolDestroyBP = M.getOrInsertFunction("pooldestroy_bp",Type::VoidTy, + PoolDescPtrTy, 0); + + // The poolalloc_bp function. + Function *PoolAllocBP = M.getOrInsertFunction("poolalloc_bp", + VoidPtrTy, PoolDescPtrTy, + Type::UIntTy, 0); + + Function *Realloc = M.getOrInsertFunction("realloc", + VoidPtrTy, VoidPtrTy, Type::UIntTy, + 0); + + + // Optimize poolreallocs + std::vector Calls; + getCallsOf(PoolRealloc, Calls); + for (unsigned i = 0, e = Calls.size(); i != e; ++i) { + CallInst *CI = Calls[i]; + // poolrealloc(PD, null, X) -> poolalloc(PD, X) + if (isa(CI->getOperand(2))) { + std::vector Ops; + Ops.push_back(CI->getOperand(1)); + Ops.push_back(CI->getOperand(3)); + Value *New = new CallInst(PoolAlloc, Ops, CI->getName(), CI); + CI->replaceAllUsesWith(New); + CI->eraseFromParent(); + } else if (isa(CI->getOperand(3)) && + cast(CI->getOperand(3))->isNullValue()) { + // poolrealloc(PD, X, 0) -> poolfree(PD, X) + std::vector Ops; + Ops.push_back(CI->getOperand(1)); + Ops.push_back(CI->getOperand(2)); + new CallInst(PoolFree, Ops, "", CI); + CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); + CI->eraseFromParent(); + } else if (isa(CI->getOperand(1))) { + // poolrealloc(null, X, Y) -> realloc(X, Y) + std::vector Ops; + Ops.push_back(CI->getOperand(2)); + Ops.push_back(CI->getOperand(3)); + Value *New = new CallInst(Realloc, Ops, CI->getName(), CI); + CI->replaceAllUsesWith(New); + CI->eraseFromParent(); + } + } + + // Optimize poolallocs + getCallsOf(PoolAlloc, Calls); + for (unsigned i = 0, e = Calls.size(); i != e; ++i) { + CallInst *CI = Calls[i]; + // poolalloc(null, X) -> malloc(X) + if (isa(CI->getOperand(1)) && + cast(CI->getOperand(1))->isNullValue()) { + Value *New = new MallocInst(Type::SByteTy, CI->getOperand(2), + CI->getName(), CI); + CI->replaceAllUsesWith(New); + CI->eraseFromParent(); + } + } + + // Optimize poolfrees + getCallsOf(PoolFree, Calls); + for (unsigned i = 0, e = Calls.size(); i != e; ++i) { + CallInst *CI = Calls[i]; + // poolfree(PD, null) -> noop + if (isa(CI->getOperand(2))) + CI->eraseFromParent(); + else if (isa(CI->getOperand(1))) { + // poolfree(null, Ptr) -> free(Ptr) + new FreeInst(CI->getOperand(2), CI); + CI->eraseFromParent(); + } + } + + // Transform pools that only have poolinit/destroy/allocate uses into + // bump-pointer pools. Also, delete pools that are unused. Find pools by + // looking for pool inits in the program. + getCallsOf(PoolInit, Calls); + std::set Pools; + for (unsigned i = 0, e = Calls.size(); i != e; ++i) + Pools.insert(Calls[i]->getOperand(1)); + + // Loop over all of the pools processing each as we find it. + for (std::set::iterator PI = Pools.begin(), E = Pools.end(); + PI != E; ++PI) { + bool HasPoolAlloc = false, HasOtherUse = false; + Value *PoolDesc = *PI; + for (Value::use_iterator UI = PoolDesc->use_begin(), + E = PoolDesc->use_end(); UI != E; ++UI) { + if (CallInst *CI = dyn_cast(*UI)) { + if (CI->getCalledFunction() == PoolInit || + CI->getCalledFunction() == PoolDestroy) { + // ignore + } else if (CI->getCalledFunction() == PoolAlloc) { + HasPoolAlloc = true; + } else { + HasOtherUse = true; + break; + } + } else { + HasOtherUse = true; + break; + } + } + + // Can we optimize it? + if (!HasOtherUse) { + // Yes, if there are uses at all, nuke the pool init, destroy, and the PD. + if (!HasPoolAlloc) { + while (!PoolDesc->use_empty()) + cast(PoolDesc->use_back())->eraseFromParent(); + if (AllocaInst *AI = dyn_cast(PoolDesc)) + AI->eraseFromParent(); + else + cast(PoolDesc)->eraseFromParent(); + } else { + // Convert all of the pool descriptor users to the BumpPtr flavor. + std::vector PDUsers(PoolDesc->use_begin(), PoolDesc->use_end()); + + while (!PDUsers.empty()) { + CallInst *CI = cast(PDUsers.back()); + PDUsers.pop_back(); + std::vector Args; + if (CI->getCalledFunction() == PoolAlloc) { + Args.assign(CI->op_begin()+1, CI->op_end()); + Value *New = new CallInst(PoolAllocBP, Args, CI->getName(), CI); + CI->replaceAllUsesWith(New); + CI->eraseFromParent(); + } else if (CI->getCalledFunction() == PoolInit) { + Args.assign(CI->op_begin()+1, CI->op_end()); + Args.erase(Args.begin()+1); // Drop the size argument. + Value *New = new CallInst(PoolInitBP, Args, "", CI); + CI->eraseFromParent(); + } else { + assert(CI->getCalledFunction() == PoolDestroy); + Args.assign(CI->op_begin()+1, CI->op_end()); + Value *New = new CallInst(PoolDestroyBP, Args, "", CI); + CI->eraseFromParent(); + } + } + ++NumBumpPtr; + } + } + } + return true; + } From lattner at cs.uiuc.edu Wed Nov 10 18:32:55 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 18:32:55 -0600 Subject: [llvm-commits] CVS: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp Message-ID: <200411110032.iAB0Wt8p020354@apoc.cs.uiuc.edu> Changes in directory poolalloc/runtime/FL2Allocator: FreeListAllocator.cpp updated: 1.26 -> 1.27 --- Log message: Make some stuff only happen when we're debugging --- Diffs of the changes: (+7 -4) Index: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp diff -u poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.26 poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.27 --- poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.26 Wed Nov 10 16:01:58 2004 +++ poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp Wed Nov 10 18:32:45 2004 @@ -250,8 +250,8 @@ Pool->FreeNodeLists[0] = 0; // This is our bump pointer. Pool->FreeNodeLists[1] = 0; // This is our end pointer. - DO_IF_TRACE(fprintf(stderr, "[%d] poolinit_bp(0x%X, %d)\n", addPoolNumber(Pool), - Pool, ObjAlignment)); + DO_IF_TRACE(fprintf(stderr, "[%d] poolinit_bp(0x%X, %d)\n", + addPoolNumber(Pool), Pool, ObjAlignment)); DO_IF_PNP(++PoolsInited); // Track # pools initialized DO_IF_PNP(InitPrintNumPools()); } @@ -265,6 +265,9 @@ if (NumBytes >= LARGE_SLAB_SIZE) goto LargeObject; + DO_IF_PNP(++Pool->NumObjects); + DO_IF_PNP(Pool->BytesAllocated += NumBytes); + if (NumBytes < 1) NumBytes = 1; unsigned Alignment; @@ -397,8 +400,8 @@ NumBytes = NumBytes+sizeof(FreedNodeHeader)+(Alignment-1); // Round up NumBytes = (NumBytes & ~(Alignment-1))-sizeof(FreedNodeHeader); // Truncate - ++Pool->NumObjects; - Pool->BytesAllocated += NumBytes; + DO_IF_PNP(++Pool->NumObjects); + DO_IF_PNP(Pool->BytesAllocated += NumBytes); if (NumBytes >= LARGE_SLAB_SIZE-sizeof(PoolSlab)-sizeof(NodeHeader)) goto LargeObject; From lattner at cs.uiuc.edu Wed Nov 10 19:44:04 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 19:44:04 -0600 Subject: [llvm-commits] CVS: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp PoolAllocator.h Message-ID: <200411110144.iAB1i43B024116@apoc.cs.uiuc.edu> Changes in directory poolalloc/runtime/FL2Allocator: FreeListAllocator.cpp updated: 1.27 -> 1.28 PoolAllocator.h updated: 1.14 -> 1.15 --- Log message: Instead of maintaining 4 freelists (for object sizes 8,12,16 and other), only maintain 2 freelists: one for the inferred object size and one for 'other'. This dramatically simplifies the poolalloc allocation path and makes use of the information that PA can infer. --- Diffs of the changes: (+123 -115) Index: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp diff -u poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.27 poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.28 --- poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.27 Wed Nov 10 18:32:45 2004 +++ poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp Wed Nov 10 19:43:54 2004 @@ -140,18 +140,16 @@ // PoolSlab implementation //===----------------------------------------------------------------------===// -static inline unsigned getSizeClass(unsigned NumBytes) { - if (NumBytes <= FreeListOneSize) - return NumBytes > FreeListZeroSize; +static void AddNodeToFreeList(PoolTy *Pool, FreedNodeHeader *FreeNode) { + FreedNodeHeader **FreeList; + if (FreeNode->Header.Size == Pool->DeclaredSize) + FreeList = &Pool->ObjFreeList; else - return 2 + (NumBytes > FreeListTwoSize); -} + FreeList = &Pool->OtherFreeList; -static void AddNodeToFreeList(PoolTy *Pool, FreedNodeHeader *FreeNode) { - unsigned SizeClass = getSizeClass(FreeNode->Header.Size); - FreeNode->PrevP = &Pool->FreeNodeLists[SizeClass]; - FreeNode->Next = Pool->FreeNodeLists[SizeClass]; - Pool->FreeNodeLists[SizeClass] = FreeNode; + FreeNode->PrevP = FreeList; + FreeNode->Next = *FreeList; + *FreeList = FreeNode; if (FreeNode->Next) FreeNode->Next->PrevP = &FreeNode->Next; } @@ -181,6 +179,9 @@ // create - Create a new (empty) slab and add it to the end of the Pools list. void PoolSlab::create(PoolTy *Pool, unsigned SizeHint) { + if (Pool->DeclaredSize == 0) + Pool->DeclaredSize = SizeHint; + unsigned Size = Pool->AllocSize; Pool->AllocSize <<= 1; Size = (Size+SizeHint-1) / SizeHint * SizeHint; @@ -219,9 +220,11 @@ Pool->AllocSize <<= 1; PoolSlab *PS = (PoolSlab*)malloc(Size+sizeof(PoolSlab)); char *PoolBody = (char*)(PS+1); + if (sizeof(PoolSlab) == 4) + PoolBody += 4; // No reason to start out unaligned. // Update the end pointer. - Pool->FreeNodeLists[1] = (FreedNodeHeader*)(PoolBody+Size); + Pool->OtherFreeList = (FreedNodeHeader*)((char*)(PS+1)+Size); // Add the slab to the list... PS->Next = Pool->Slabs; @@ -247,8 +250,8 @@ Pool->AllocSize = INITIAL_SLAB_SIZE; Pool->Alignment = ObjAlignment; Pool->LargeArrays = 0; - Pool->FreeNodeLists[0] = 0; // This is our bump pointer. - Pool->FreeNodeLists[1] = 0; // This is our end pointer. + Pool->ObjFreeList = 0; // This is our bump pointer. + Pool->OtherFreeList = 0; // This is our end pointer. DO_IF_TRACE(fprintf(stderr, "[%d] poolinit_bp(0x%X, %d)\n", addPoolNumber(Pool), Pool, ObjAlignment)); @@ -273,8 +276,8 @@ unsigned Alignment; char *BumpPtr, *EndPtr; Alignment = Pool->Alignment-1; - BumpPtr = (char*)Pool->FreeNodeLists[0]; // Get our bump pointer. - EndPtr = (char*)Pool->FreeNodeLists[1]; // Get our end pointer. + BumpPtr = (char*)Pool->ObjFreeList; // Get our bump pointer. + EndPtr = (char*)Pool->OtherFreeList; // Get our end pointer. TryAgain: // Align the bump pointer to the required boundary. @@ -283,13 +286,13 @@ if (BumpPtr + NumBytes < EndPtr) { void *Result = BumpPtr; // Update bump ptr. - Pool->FreeNodeLists[0] = (FreedNodeHeader*)(BumpPtr+NumBytes); + Pool->ObjFreeList = (FreedNodeHeader*)(BumpPtr+NumBytes); DO_IF_TRACE(fprintf(stderr, "0x%X\n", Result)); return Result; } BumpPtr = (char*)PoolSlab::create_for_bp(Pool); - EndPtr = (char*)Pool->FreeNodeLists[1]; // Get our updated end pointer. + EndPtr = (char*)Pool->OtherFreeList; // Get our updated end pointer. goto TryAgain; LargeObject: @@ -341,10 +344,17 @@ assert(Pool && "Null pool pointer passed into poolinit!\n"); memset(Pool, 0, sizeof(PoolTy)); Pool->AllocSize = INITIAL_SLAB_SIZE; - Pool->DeclaredSize = DeclaredSize; + if (ObjAlignment < 4) ObjAlignment = __alignof(double); Pool->Alignment = ObjAlignment; + // Round the declared size up to an alignment boundary-header size, just like + // we have to do for objects. + DeclaredSize = DeclaredSize+sizeof(FreedNodeHeader)+(ObjAlignment-1); + DeclaredSize = (DeclaredSize & ~(ObjAlignment-1))-sizeof(FreedNodeHeader); + + Pool->DeclaredSize = DeclaredSize; + DO_IF_TRACE(fprintf(stderr, "[%d] poolinit(0x%X, %d, %d)\n", addPoolNumber(Pool), Pool, DeclaredSize, ObjAlignment)); DO_IF_PNP(++PoolsInited); // Track # pools initialized @@ -403,81 +413,81 @@ DO_IF_PNP(++Pool->NumObjects); DO_IF_PNP(Pool->BytesAllocated += NumBytes); + // Fast path - allocate objects off the object list. + if (NumBytes == Pool->DeclaredSize && Pool->ObjFreeList != 0) { + FreedNodeHeader *Node = Pool->ObjFreeList; + UnlinkFreeNode(Node); + assert(NumBytes == Node->Header.Size); + + Node->Header.Size = NumBytes|1; // Mark as allocated + DO_IF_TRACE(fprintf(stderr, "0x%X\n", &Node->Header+1)); + return &Node->Header+1; + } + if (NumBytes >= LARGE_SLAB_SIZE-sizeof(PoolSlab)-sizeof(NodeHeader)) goto LargeObject; - // Figure out which size class to start scanning from. - unsigned SizeClass; - SizeClass = getSizeClass(NumBytes); - - // Scan for a class that has entries! - while (SizeClass < 3 && Pool->FreeNodeLists[SizeClass] == 0) - ++SizeClass; - // Fast path. In the common case, we can allocate a portion of the node at // the front of the free list. - if (FreedNodeHeader *FirstNode = Pool->FreeNodeLists[SizeClass]) { - unsigned FirstNodeSize = FirstNode->Header.Size; - if (FirstNodeSize > NumBytes) { - if (FirstNodeSize >= 2*NumBytes+sizeof(NodeHeader)) { - // Put the remainder back on the list... - FreedNodeHeader *NextNodes = - (FreedNodeHeader*)((char*)FirstNode + sizeof(NodeHeader) + NumBytes); - - // Remove from list - UnlinkFreeNode(FirstNode); - - NextNodes->Header.Size = FirstNodeSize-NumBytes-sizeof(NodeHeader); - AddNodeToFreeList(Pool, NextNodes); - - } else { - UnlinkFreeNode(FirstNode); - NumBytes = FirstNodeSize; - } - FirstNode->Header.Size = NumBytes|1; // Mark as allocated - DO_IF_TRACE(fprintf(stderr, "0x%X\n", &FirstNode->Header+1)); - return &FirstNode->Header+1; - } - } - - // Perform a search of the free list, taking the front of the first free chunk - // that is big enough. do { - FreedNodeHeader **FN = &Pool->FreeNodeLists[SizeClass]; - FreedNodeHeader *FNN = *FN; + FreedNodeHeader *FirstNode = Pool->OtherFreeList; + if (FirstNode) { + unsigned FirstNodeSize = FirstNode->Header.Size; + if (FirstNodeSize >= NumBytes) { + if (FirstNodeSize >= 2*NumBytes+sizeof(NodeHeader)) { + // Put the remainder back on the list... + FreedNodeHeader *NextNodes = + (FreedNodeHeader*)((char*)FirstNode + sizeof(NodeHeader) +NumBytes); + + // Remove from list + UnlinkFreeNode(FirstNode); + + NextNodes->Header.Size = FirstNodeSize-NumBytes-sizeof(NodeHeader); + AddNodeToFreeList(Pool, NextNodes); + + } else { + UnlinkFreeNode(FirstNode); + NumBytes = FirstNodeSize; + } + FirstNode->Header.Size = NumBytes|1; // Mark as allocated + DO_IF_TRACE(fprintf(stderr, "0x%X\n", &FirstNode->Header+1)); + return &FirstNode->Header+1; + } - // Search the list for the first-fit - while (FNN && FNN->Header.Size < NumBytes) - FN = &FNN->Next, FNN = *FN; - - if (FNN) { - // We found a slab big enough. If it's a perfect fit, just unlink from - // the free list, otherwise, slice a little bit off and adjust the free - // list. - if (FNN->Header.Size > 2*NumBytes+sizeof(NodeHeader)) { - UnlinkFreeNode(FNN); - - // Put the remainder back on the list... - FreedNodeHeader *NextNodes = - (FreedNodeHeader*)((char*)FNN + sizeof(NodeHeader) + NumBytes); - NextNodes->Header.Size = FNN->Header.Size-NumBytes-sizeof(NodeHeader); - AddNodeToFreeList(Pool, NextNodes); - } else { - UnlinkFreeNode(FNN); - NumBytes = FNN->Header.Size; + // Perform a search of the free list, taking the front of the first free + // chunk that is big enough. + FreedNodeHeader **FN = &Pool->OtherFreeList; + FreedNodeHeader *FNN = FirstNode; + + // Search the list for the first-fit. + while (FNN && FNN->Header.Size < NumBytes) + FN = &FNN->Next, FNN = *FN; + + if (FNN) { + // We found a slab big enough. If it's a perfect fit, just unlink + // from the free list, otherwise, slice a little bit off and adjust + // the free list. + if (FNN->Header.Size > 2*NumBytes+sizeof(NodeHeader)) { + UnlinkFreeNode(FNN); + + // Put the remainder back on the list... + FreedNodeHeader *NextNodes = + (FreedNodeHeader*)((char*)FNN + sizeof(NodeHeader) + NumBytes); + NextNodes->Header.Size = FNN->Header.Size-NumBytes-sizeof(NodeHeader); + AddNodeToFreeList(Pool, NextNodes); + } else { + UnlinkFreeNode(FNN); + NumBytes = FNN->Header.Size; + } + FNN->Header.Size = NumBytes|1; // Mark as allocated + DO_IF_TRACE(fprintf(stderr, "0x%X\n", &FNN->Header+1)); + return &FNN->Header+1; } - FNN->Header.Size = NumBytes|1; // Mark as allocated - DO_IF_TRACE(fprintf(stderr, "0x%X\n", &FNN->Header+1)); - return &FNN->Header+1; } - if (SizeClass < LargeFreeList) { - ++SizeClass; - } else { - // Oops, we didn't find anything on the free list big enough! Allocate - // another slab and try again. - PoolSlab::create(Pool, NumBytes); - } + // Oops, we didn't find anything on the free list big enough! Allocate + // another slab and try again. + PoolSlab::create(Pool, NumBytes); } while (1); LargeObject: @@ -528,15 +538,23 @@ // a simple check that prevents many horrible forms of fragmentation, // particularly when freeing objects in allocation order. // - for (unsigned SizeClass = 0; SizeClass <= LargeFreeList; ++SizeClass) - if (FreedNodeHeader *CurFrontNode = Pool->FreeNodeLists[SizeClass]) - if ((char*)CurFrontNode + sizeof(NodeHeader) + CurFrontNode->Header.Size== - (char*)FNH) { - // This node immediately follows the node on the front of the free-list. - // No list manipulation is required. - CurFrontNode->Header.Size += Size+sizeof(NodeHeader); - return; - } + if (FreedNodeHeader *ObjFNH = Pool->ObjFreeList) + if ((char*)ObjFNH + sizeof(NodeHeader) + ObjFNH->Header.Size == (char*)FNH){ + // Merge this with a node that is already on the object size free list. + // Because the object is growing, we will never be able to find it if we + // leave it on the object freelist. + UnlinkFreeNode(ObjFNH); + ObjFNH->Header.Size += Size+sizeof(NodeHeader); + AddNodeToFreeList(Pool, ObjFNH); + return; + } + + if (FreedNodeHeader *OFNH = Pool->OtherFreeList) + if ((char*)OFNH + sizeof(NodeHeader) + OFNH->Header.Size == (char*)FNH) { + // Merge this with a node that is already on the object size free list. + OFNH->Header.Size += Size+sizeof(NodeHeader); + return; + } FNH->Header.Size = Size; AddNodeToFreeList(Pool, FNH); Index: poolalloc/runtime/FL2Allocator/PoolAllocator.h diff -u poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.14 poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.15 --- poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.14 Wed Nov 10 16:01:58 2004 +++ poolalloc/runtime/FL2Allocator/PoolAllocator.h Wed Nov 10 19:43:54 2004 @@ -68,33 +68,16 @@ }; -// FreeList*Size - These are size classes for each of the freelists in a pool. -// An object in a particular free list is guaranteed to be <= this size. -enum { - FreeListZeroSize = 8, - FreeListOneSize = 12, - FreeListTwoSize = 16, - - // There are four free lists. - LargeFreeList = 3 -}; - struct PoolTy { - // Lists - the list of slabs in this pool. - PoolSlab *Slabs; - // The free node lists for objects of various sizes. - FreedNodeHeader *FreeNodeLists[4]; + FreedNodeHeader *ObjFreeList; + FreedNodeHeader *OtherFreeList; // Alignment - The required alignment of allocations the pool in bytes. unsigned Alignment; - // NumObjects - the number of poolallocs for this pool. - unsigned NumObjects; - - // BytesAllocated - The total number of bytes ever allocated from this pool. - // Together with NumObjects, allows us to calculate average object size. - unsigned BytesAllocated; + // The declared size of the pool, just kept for the record. + unsigned DeclaredSize; // LargeArrays - A doubly linked list of large array chunks, dynamically // allocated with malloc. @@ -103,8 +86,15 @@ // The size to allocate for the next slab. unsigned AllocSize; - // The declared size of the pool, just kept for the record. - unsigned DeclaredSize; + // Lists - the list of slabs in this pool. + PoolSlab *Slabs; + + // NumObjects - the number of poolallocs for this pool. + unsigned NumObjects; + + // BytesAllocated - The total number of bytes ever allocated from this pool. + // Together with NumObjects, allows us to calculate average object size. + unsigned BytesAllocated; }; extern "C" { From lattner at cs.uiuc.edu Wed Nov 10 23:46:52 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 Nov 2004 23:46:52 -0600 Subject: [llvm-commits] CVS: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp Message-ID: <200411110546.XAA04015@choi.cs.uiuc.edu> Changes in directory poolalloc/runtime/FL2Allocator: FreeListAllocator.cpp updated: 1.28 -> 1.29 --- Log message: Fix some serious bugs infering pool desired size (don't infer a size that we can never match!) --- Diffs of the changes: (+13 -3) Index: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp diff -u poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.28 poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.29 --- poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.28 Wed Nov 10 19:43:54 2004 +++ poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp Wed Nov 10 23:46:41 2004 @@ -179,8 +179,14 @@ // create - Create a new (empty) slab and add it to the end of the Pools list. void PoolSlab::create(PoolTy *Pool, unsigned SizeHint) { - if (Pool->DeclaredSize == 0) + if (Pool->DeclaredSize == 0) { + unsigned Align = Pool->Alignment; + if (SizeHint < sizeof(FreedNodeHeader)-sizeof(NodeHeader)) + SizeHint = sizeof(FreedNodeHeader)-sizeof(NodeHeader); + SizeHint = SizeHint+sizeof(FreedNodeHeader)+(Align-1); + SizeHint = (SizeHint & ~(Align-1))-sizeof(FreedNodeHeader); Pool->DeclaredSize = SizeHint; + } unsigned Size = Pool->AllocSize; Pool->AllocSize <<= 1; @@ -350,8 +356,12 @@ // Round the declared size up to an alignment boundary-header size, just like // we have to do for objects. - DeclaredSize = DeclaredSize+sizeof(FreedNodeHeader)+(ObjAlignment-1); - DeclaredSize = (DeclaredSize & ~(ObjAlignment-1))-sizeof(FreedNodeHeader); + if (DeclaredSize) { + if (DeclaredSize < sizeof(FreedNodeHeader)-sizeof(NodeHeader)) + DeclaredSize = sizeof(FreedNodeHeader)-sizeof(NodeHeader); + DeclaredSize = DeclaredSize+sizeof(FreedNodeHeader)+(ObjAlignment-1); + DeclaredSize = (DeclaredSize & ~(ObjAlignment-1))-sizeof(FreedNodeHeader); + } Pool->DeclaredSize = DeclaredSize; From reid at x10sys.com Thu Nov 11 01:30:38 2004 From: reid at x10sys.com (Reid Spencer) Date: Thu, 11 Nov 2004 01:30:38 -0600 Subject: [llvm-commits] CVS: llvm/docs/CFEBuildInstrs.html GettingStarted.html Message-ID: <200411110730.BAA09826@zion.cs.uiuc.edu> Changes in directory llvm/docs: CFEBuildInstrs.html updated: 1.25 -> 1.26 GettingStarted.html updated: 1.71 -> 1.72 --- Log message: Fix documentation for Makefile target name change. install-bytecode is now just "install" in the runtime directory. --- Diffs of the changes: (+7 -7) Index: llvm/docs/CFEBuildInstrs.html diff -u llvm/docs/CFEBuildInstrs.html:1.25 llvm/docs/CFEBuildInstrs.html:1.26 --- llvm/docs/CFEBuildInstrs.html:1.25 Tue Oct 5 22:13:47 2004 +++ llvm/docs/CFEBuildInstrs.html Thu Nov 11 01:30:27 2004 @@ -228,7 +228,7 @@
  % gmake
  % mkdir $CFEINSTALL/bytecode-libs
- % gmake -C runtime install-bytecode
+ % gmake -C runtime install
  % setenv LLVM_LIB_SEARCH_PATH $CFEINSTALL/bytecode-libs
 
@@ -314,7 +314,7 @@ Brian Gaeke
LLVM Compiler Infrastructure
- Last modified: $Date: 2004/10/06 03:13:47 $ + Last modified: $Date: 2004/11/11 07:30:27 $ Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.71 llvm/docs/GettingStarted.html:1.72 --- llvm/docs/GettingStarted.html:1.71 Sun Nov 7 18:29:22 2004 +++ llvm/docs/GettingStarted.html Thu Nov 11 01:30:27 2004 @@ -748,11 +748,11 @@ ./configure --prefix=[dir], defaults to /usr/local.

-

gmake install-bytecode +
gmake -C runtime install
- Assuming you built LLVM into $OBJDIR, when this command is run in - $OBJDIR/runtime, it will install bytecode libraries into the GCC front end's - bytecode library directory. If you need to update your bytecode libraries, + Assuming you built LLVM into $OBJDIR, when this command is run, it will + install bytecode libraries into the GCC front end's bytecode library + directory. If you need to update your bytecode libraries, this is the target to use once you've built them.

@@ -1318,7 +1318,7 @@ Chris Lattner
Reid Spencer
The LLVM Compiler Infrastructure
- Last modified: $Date: 2004/11/08 00:29:22 $ + Last modified: $Date: 2004/11/11 07:30:27 $ From lattner at cs.uiuc.edu Thu Nov 11 01:46:25 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 11 Nov 2004 01:46:25 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/IPConstantProp/deadarg.ll Message-ID: <200411110746.iAB7kPFI029066@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/IPConstantProp: deadarg.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+7 -0) Index: llvm/test/Regression/Transforms/IPConstantProp/deadarg.ll diff -c /dev/null llvm/test/Regression/Transforms/IPConstantProp/deadarg.ll:1.1 *** /dev/null Thu Nov 11 01:46:21 2004 --- llvm/test/Regression/Transforms/IPConstantProp/deadarg.ll Thu Nov 11 01:46:11 2004 *************** *** 0 **** --- 1,7 ---- + ; RUN: llvm-as < %s | opt -ipconstprop -disable-output + implementation + + internal void %foo(int %X) { + call void %foo(int %X) + ret void + } From lattner at cs.uiuc.edu Thu Nov 11 01:46:41 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 11 Nov 2004 01:46:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Message-ID: <200411110746.iAB7keTm029078@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: IPConstantPropagation.cpp updated: 1.11 -> 1.12 --- Log message: Fix bug: IPConstantProp/deadarg.ll --- Diffs of the changes: (+2 -2) Index: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp diff -u llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.11 llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.12 --- llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.11 Wed Nov 10 13:43:59 2004 +++ llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Thu Nov 11 01:46:29 2004 @@ -113,9 +113,9 @@ bool MadeChange = false; for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) // Do we have a constant argument!? - if (!ArgumentConstants[i].second && !AI->use_empty()) { - assert(ArgumentConstants[i].first && "Unknown constant value!"); + if (!ArgumentConstants[i].second) { Value *V = ArgumentConstants[i].first; + if (V == 0) V = UndefValue::get(AI->getType()); AI->replaceAllUsesWith(V); ++NumArgumentsProped; MadeChange = true; From lattner at cs.uiuc.edu Thu Nov 11 01:48:07 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 11 Nov 2004 01:48:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Message-ID: <200411110748.iAB7m7ZV029185@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: IPConstantPropagation.cpp updated: 1.12 -> 1.13 --- Log message: Actually, leave the check in. This prevents us from counting dead arguments as IPCP opportunities. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp diff -u llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.12 llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.13 --- llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.12 Thu Nov 11 01:46:29 2004 +++ llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Thu Nov 11 01:47:54 2004 @@ -113,7 +113,7 @@ bool MadeChange = false; for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) // Do we have a constant argument!? - if (!ArgumentConstants[i].second) { + if (!ArgumentConstants[i].second && !AI->use_empty()) { Value *V = ArgumentConstants[i].first; if (V == 0) V = UndefValue::get(AI->getType()); AI->replaceAllUsesWith(V); From reid at x10sys.com Thu Nov 11 03:21:30 2004 From: reid at x10sys.com (Reid Spencer) Date: Thu, 11 Nov 2004 03:21:30 -0600 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/llvm-ar.pod Message-ID: <200411110921.DAA13789@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: llvm-ar.pod added (r1.1) --- Log message: First attempt at llvm-ar documentation. Modifiers need a little more explanation. --- Diffs of the changes: (+238 -0) Index: llvm/docs/CommandGuide/llvm-ar.pod diff -c /dev/null llvm/docs/CommandGuide/llvm-ar.pod:1.1 *** /dev/null Thu Nov 11 03:21:29 2004 --- llvm/docs/CommandGuide/llvm-ar.pod Thu Nov 11 03:21:18 2004 *************** *** 0 **** --- 1,238 ---- + =pod + + =head1 NAME + + llvm-ar - LLVM archiver + + =head1 SYNOPSIS + + B [-X32_64] [-]{dmpqrtx}[Rabfouz] [relpos] [count] [files...] + + + =head1 DESCRIPTION + + The B command is similar to the common Unix utility, C. It + archives several files together into a single file. The intent for this is + to produce archive libraries by LLVM bytecode that can be linked into an + LLVM program. However, the archive can contain any kind of file. If requested, + B can generate a symbol table that makes linking faster because + only the symbol table needs to be consulted, not each individual file member + of the archive. + + While the B command produces files that are similar to the format + used by older C implementations, it has several significant departures + in order to make the archive appropriate for LLVM. Consequently, archives + produced with B probably won't be readable or editable with any + C implementation unless the archive content is very simple. + + Here's where B departs from previous C implementations: + + =over + + =item I + + Since B is intended to archive bytecode files, the symbol table + won't make much sense to anything but LLVM. Consequently, the symbol table's + format has been simplified. It consists simply of a sequence of pairs + of a file member index number as an LSB 4byte integer and a null-terminated + string. + + =item I + + Some C implementations (SVR4) use a separate file member to record long + path names (> 15 characters). B takes the BSD 4.4 and Mac OS X + approach which is to simply store the full path name immediately preceding + the data for the file. The path name is null terminated and may contain the + slash (/) character. + + =item I + + B can compress the members of an archive to save space. The + compression used depends on what's available on the platform but favors + bzip2 and then zlib. Note that for very small files, bzip2 may increase + the file size but generally does about 10% better than zlib on LLVM + bytecode files. + + =item I + + Most C implementations do not recurse through directories but simply + ignore directories if they are presented to the program in the F + option. B, however, can recurse through directory structures and + add all the files under a directory, if requested. + + =item I + + When B prints out the verbose table of contents (C option), it + precedes the usual output with a character indicating the basic kind of + content in the file. A blank means the file is a regular file. A 'Z' means + the file is compressed. A 'B' means the file is an LLVM bytecode file. An + 'S' means the file is the symbol table. + + =back + + =head1 OPTIONS + + The options to B are compatible with other C implementations. + However, there are a few modifiers (F) that are not found in other + Cs. The options to B specify a single basic operation to + perform on the archive, a variety of modifiers for that operation, the + name of the archive file, and an optional list of file names. These options + are used to determine how B should process the archive file. + + The Operations and Modifiers are explained in the sections below. The minimal + set of options is at least one operator and the name of the archive. Typically + archive files end with a C<.a> suffix, but this is not required. Following + the F comes a list of F that indicate the specific members + of the archive to operate on. If the F option is not specified, it + generally means either "none" or "all" members, depending on the operation. + + =head2 Operations + + =over + + =item d + + Delete files from the archive. No modifiers are applicable to this operation. + The F options specify which members should be removed from the + archive. It is not an error if a specified file does not appear in the archive. + If no F are specified, the archive is not modified. + + =item m[abi] + + Move files from one location in the archive to another. The F, F, and + F modifiers apply to this operation. The F will all be moved + to the location given by the modifiers. If no modifiers are used, the files + will be moved to the end of the archive. If no F are specified, the + archive is not modified. + + =item p + + Print files to the standard output. No modifiers are applicable to this + operation. This operation simply prints the F indicated to the + standard output. If no F are specified, the entire archive is printed. + Printing bytecode files is ill-advised as they might confuse your terminal + settings. The F

operation never modifies the archive. + + =item q[Rfz] + + Quickly append files to the end of the archive. The F, F, and F + modifiers apply to this operation. This operation quickly adds the + F to the archive without checking for duplicates that shoud be + removed first. If no F are specified, the archive is not modified. + Becasue of the way that B constructs the archive file, its dubious + whether the F operation is any faster than the F operation. + + =item r[Rabfuz] + + Replace or insert file members. The F, F, F, F, F, and F + modifiers apply to this operation. This operation will replace existing + F or insert them at the end of the archive if they do not exist. If no + F are specified, the archive is not modified. + + =item t[v] + + Print the table of contents. Without any modifiers, this operation just prints + the names of the members to the standard output. With the F modifier, + B also prints out the file type (B=bytecode, Z=compressed, S=symbol + table, blank=regular file), the permission mode, the owner and group, the + size, and the date. If any F are specified, the listing is only for + those files. If no F are specified, the table of contents for the + whole archive is printed. + + =item x[o] + + Extract archive members back to files. The F modifier applies to this + operation. This operation retrieves the indicated F from the archive + and writes them back to the operating system's file system. If no + F are specified, the entire archive is extract. + + =back + + =head2 Modifiers (operation specific) + + =over + + =item [a] + + put F after [relpos] + + =item [b] + + put F before [relpos] (same as [i]) + + =item [f] + + truncate inserted file names + + =item [i] + + put file(s) before [relpos] (same as [b]) + + =item [N] + + use instance [count] of name + + =item [o] + + preserve original dates + + =item [P] + + use full path names when matching + + =item [R] + + recurse through directories when inserting + + =item [u] + + update only files newer than archive contents + + =item [z] + + compress/uncompress files before inserting/extracting + + =back + + =head2 Modifiers (generic) + + =over + + =item [c] + + do not warn if the library had to be created + + =item [s] + + create an archive index (cf. ranlib) + + =item [S] + + do not build a symbol table + + =item [R] + + recursively process directories + + =item [v] + + be verbose + + =back + + =head1 EXIT STATUS + + If B succeeds, it will exit with 0. A usage error, results + in an exit code of 1. A hard (file system typically) error results in an + exit code of 2. Miscellaneous or unknown errors result in an + exit code of 3. + + =head1 SEE ALSO + + L + + =head1 AUTHORS + + Maintained by the LLVM Team (L). + + =cut From reid at x10sys.com Thu Nov 11 03:29:47 2004 From: reid at x10sys.com (Reid Spencer) Date: Thu, 11 Nov 2004 03:29:47 -0600 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/index.html Message-ID: <200411110929.DAA21326@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: index.html updated: 1.18 -> 1.19 --- Log message: Add llvm-ar to the index. --- Diffs of the changes: (+4 -1) Index: llvm/docs/CommandGuide/index.html diff -u llvm/docs/CommandGuide/index.html:1.18 llvm/docs/CommandGuide/index.html:1.19 --- llvm/docs/CommandGuide/index.html:1.18 Sat Jul 10 16:43:12 2004 +++ llvm/docs/CommandGuide/index.html Thu Nov 11 03:29:36 2004 @@ -54,6 +54,9 @@

  • analyze - run LLVM analyses on a bytecode file and print the results
  • +
  • llvm-ar - + archive bytecode files
  • +
  • llvm-nm print out the names and types of symbols in a bytecode file
  • @@ -128,7 +131,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/07/10 21:43:12 $ + Last modified: $Date: 2004/11/11 09:29:36 $ From reid at x10sys.com Thu Nov 11 03:30:10 2004 From: reid at x10sys.com (Reid Spencer) Date: Thu, 11 Nov 2004 03:30:10 -0600 Subject: [llvm-commits] CVS: llvm/docs/index.html Message-ID: <200411110930.DAA21420@zion.cs.uiuc.edu> Changes in directory llvm/docs: index.html updated: 1.34 -> 1.35 --- Log message: Add llvm-ar to the index. --- Diffs of the changes: (+2 -1) Index: llvm/docs/index.html diff -u llvm/docs/index.html:1.34 llvm/docs/index.html:1.35 --- llvm/docs/index.html:1.34 Mon Nov 1 15:57:35 2004 +++ llvm/docs/index.html Thu Nov 11 03:30:00 2004 @@ -54,6 +54,7 @@
  • LLVM Command Guide - A reference manual for the LLVM command line utilities ("man" pages for LLVM tools).
    Current tools: + llvm-ar, llvm-as, llvm-dis, opt, @@ -228,6 +229,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/11/01 21:57:35 $ + Last modified: $Date: 2004/11/11 09:30:00 $ From lattner at cs.uiuc.edu Thu Nov 11 04:13:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 11 Nov 2004 04:13:11 -0600 Subject: [llvm-commits] CVS: poolalloc/test/TEST.optzn.Makefile TEST.optzn.report Makefile TEST.poolalloc.Makefile TEST.poolalloc.report Message-ID: <200411111013.iABADBTN029868@apoc.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.optzn.Makefile added (r1.1) TEST.optzn.report added (r1.1) Makefile updated: 1.26 -> 1.27 TEST.poolalloc.Makefile updated: 1.33 -> 1.34 TEST.poolalloc.report updated: 1.24 -> 1.25 --- Log message: Add an optimization report, tweak other reports --- Diffs of the changes: (+315 -7) Index: poolalloc/test/TEST.optzn.Makefile diff -c /dev/null poolalloc/test/TEST.optzn.Makefile:1.1 *** /dev/null Thu Nov 11 04:13:11 2004 --- poolalloc/test/TEST.optzn.Makefile Thu Nov 11 04:13:00 2004 *************** *** 0 **** --- 1,222 ---- + ##===- poolalloc/test/TEST.optzn.Makefile ------------------*- Makefile -*-===## + # + # This test runs the pool allocator on all of the Programs, producing some + # performance numbers and statistics. + # + ##===----------------------------------------------------------------------===## + + CFLAGS = -O2 -fno-strict-aliasing + + EXTRA_PA_FLAGS := + + # HEURISTIC can be set to: + # AllNodes + ifdef HEURISTIC + EXTRA_PA_FLAGS += -poolalloc-heuristic=$(HEURISTIC) + endif + + + CURDIR := $(shell cd .; pwd) + PROGDIR := $(shell cd $(LLVM_SRC_ROOT)/projects/llvm-test; pwd)/ + RELDIR := $(subst $(PROGDIR),,$(CURDIR)) + + # Pool allocator pass shared object + PA_SO := $(PROJECT_DIR)/lib/Debug/libpoolalloc$(SHLIBEXT) + + # Pool allocator runtime library + #PA_RT := $(PROJECT_DIR)/lib/Bytecode/libpoolalloc_fl_rt.bc + #PA_RT_O := $(PROJECT_DIR)/lib/$(CONFIGURATION)/poolalloc_rt.o + PA_RT_O := $(PROJECT_DIR)/lib/Release/poolalloc_rt.o + #PA_RT_O := $(PROJECT_DIR)/lib/Release/poolalloc_fl_rt.o + + # Command to run opt with the pool allocator pass loaded + OPT_PA := $(LOPT) -load $(PA_SO) + + # OPT_PA_STATS - Run opt with the -stats and -time-passes options, capturing the + # output to a file. + OPT_PA_STATS = $(OPT_PA) -info-output-file=$(CURDIR)/$@.info -stats -time-passes + + OPTZN_PASSES := -globaldce -ipconstprop -deadargelim -adce -instcombine -simplifycfg + + + # This rule runs the pool allocator on the .llvm.bc file to produce a new .bc + # file + $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).selectivepa.bc): \ + Output/%.$(TEST).selectivepa.bc: Output/%.llvm.bc $(PA_SO) $(LOPT) + - at rm -f $(CURDIR)/$@.info + -$(OPT_PA_STATS) -poolalloc -poolalloc-heuristic=AllNodes $(EXTRA_PA_FLAGS) $(OPTZN_PASSES) -pooloptimize $< -o $@ -f 2>&1 > $@.out + + $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).bumpptr.bc): \ + Output/%.$(TEST).bumpptr.bc: Output/%.llvm.bc $(PA_SO) $(LOPT) + - at rm -f $(CURDIR)/$@.info + -$(OPT_PA_STATS) -poolalloc $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out + + + $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).basepa.bc): \ + Output/%.$(TEST).basepa.bc: Output/%.llvm.bc $(PA_SO) $(LOPT) + - at rm -f $(CURDIR)/$@.info + -$(OPT_PA_STATS) -poolalloc -poolalloc-heuristic=AllNodes -poolalloc-force-all-poolfrees $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out + + + $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).freeelim.bc): \ + Output/%.$(TEST).freeelim.bc: Output/%.llvm.bc $(PA_SO) $(LOPT) + - at rm -f $(CURDIR)/$@.info + -$(OPT_PA_STATS) -poolalloc -poolalloc-force-all-poolfrees $(OPTZN_PASSES) -pooloptimize $< -o $@ -f 2>&1 > $@.out + + + # This rule compiles the new .bc file into a .c file using CBE + $(PROGRAMS_TO_TEST:%=Output/%.selectivepa.cbe.c): \ + Output/%.selectivepa.cbe.c: Output/%.$(TEST).selectivepa.bc $(LLC) + -$(LLC) -march=c -f $< -o $@ + + $(PROGRAMS_TO_TEST:%=Output/%.bumpptr.cbe.c): \ + Output/%.bumpptr.cbe.c: Output/%.$(TEST).bumpptr.bc $(LLC) + -$(LLC) -march=c -f $< -o $@ + + $(PROGRAMS_TO_TEST:%=Output/%.basepa.cbe.c): \ + Output/%.basepa.cbe.c: Output/%.$(TEST).basepa.bc $(LLC) + -$(LLC) -march=c -f $< -o $@ + + $(PROGRAMS_TO_TEST:%=Output/%.freeelim.cbe.c): \ + Output/%.freeelim.cbe.c: Output/%.$(TEST).freeelim.bc $(LLC) + -$(LLC) -march=c -f $< -o $@ + + + + $(PROGRAMS_TO_TEST:%=Output/%.selectivepa.cbe): \ + Output/%.selectivepa.cbe: Output/%.selectivepa.cbe.c $(PA_RT_O) + -$(CC) $(CFLAGS) $< $(PA_RT_O) $(LLCLIBS) $(LDFLAGS) -o $@ + + $(PROGRAMS_TO_TEST:%=Output/%.bumpptr.cbe): \ + Output/%.bumpptr.cbe: Output/%.bumpptr.cbe.c $(PA_RT_O) + -$(CC) $(CFLAGS) $< $(PA_RT_O) $(LLCLIBS) $(LDFLAGS) -o $@ + + $(PROGRAMS_TO_TEST:%=Output/%.basepa.cbe): \ + Output/%.basepa.cbe: Output/%.basepa.cbe.c $(PA_RT_O) + -$(CC) $(CFLAGS) $< $(PA_RT_O) $(LLCLIBS) $(LDFLAGS) -o $@ + + $(PROGRAMS_TO_TEST:%=Output/%.freeelim.cbe): \ + Output/%.freeelim.cbe: Output/%.freeelim.cbe.c $(PA_RT_O) + -$(CC) $(CFLAGS) $< $(PA_RT_O) $(LLCLIBS) $(LDFLAGS) -o $@ + + + + ifndef PROGRAMS_HAVE_CUSTOM_RUN_RULES + + # This rule runs the generated executable, generating timing information, for + # normal test programs + $(PROGRAMS_TO_TEST:%=Output/%.selectivepa.out-cbe): \ + Output/%.selectivepa.out-cbe: Output/%.selectivepa.cbe + -$(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) + + $(PROGRAMS_TO_TEST:%=Output/%.bumpptr.out-cbe): \ + Output/%.bumpptr.out-cbe: Output/%.bumpptr.cbe + -$(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) + + $(PROGRAMS_TO_TEST:%=Output/%.basepa.out-cbe): \ + Output/%.basepa.out-cbe: Output/%.basepa.cbe + -$(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) + + $(PROGRAMS_TO_TEST:%=Output/%.freeelim.out-cbe): \ + Output/%.freeelim.out-cbe: Output/%.freeelim.cbe + -$(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) + + else + + # This rule runs the generated executable, generating timing information, for + # SPEC + $(PROGRAMS_TO_TEST:%=Output/%.selectivepa.out-cbe): \ + Output/%.selectivepa.out-cbe: Output/%.selectivepa.cbe + -$(SPEC_SANDBOX) selectivepacbe-$(RUN_TYPE) $@ $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + ../../$< $(RUN_OPTIONS) + -(cd Output/selectivepacbe-$(RUN_TYPE); cat $(LOCAL_OUTPUTS)) > $@ + -cp Output/selectivepacbe-$(RUN_TYPE)/$(STDOUT_FILENAME).time $@.time + + $(PROGRAMS_TO_TEST:%=Output/%.bumpptr.out-cbe): \ + Output/%.bumpptr.out-cbe: Output/%.bumpptr.cbe + -$(SPEC_SANDBOX) bumpptrcbe-$(RUN_TYPE) $@ $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + ../../$< $(RUN_OPTIONS) + -(cd Output/bumpptrcbe-$(RUN_TYPE); cat $(LOCAL_OUTPUTS)) > $@ + -cp Output/bumpptrcbe-$(RUN_TYPE)/$(STDOUT_FILENAME).time $@.time + + $(PROGRAMS_TO_TEST:%=Output/%.basepa.out-cbe): \ + Output/%.basepa.out-cbe: Output/%.basepa.cbe + -$(SPEC_SANDBOX) basepacbe-$(RUN_TYPE) $@ $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + ../../$< $(RUN_OPTIONS) + -(cd Output/basepacbe-$(RUN_TYPE); cat $(LOCAL_OUTPUTS)) > $@ + -cp Output/basepacbe-$(RUN_TYPE)/$(STDOUT_FILENAME).time $@.time + + $(PROGRAMS_TO_TEST:%=Output/%.freeelim.out-cbe): \ + Output/%.freeelim.out-cbe: Output/%.freeelim.cbe + -$(SPEC_SANDBOX) freeelimcbe-$(RUN_TYPE) $@ $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + ../../$< $(RUN_OPTIONS) + -(cd Output/freeelimcbe-$(RUN_TYPE); cat $(LOCAL_OUTPUTS)) > $@ + -cp Output/freeelimcbe-$(RUN_TYPE)/$(STDOUT_FILENAME).time $@.time + + endif + + + # This rule diffs the post-poolallocated version to make sure we didn't break + # the program! + $(PROGRAMS_TO_TEST:%=Output/%.selectivepa.diff-cbe): \ + Output/%.selectivepa.diff-cbe: Output/%.out-nat Output/%.selectivepa.out-cbe + @cp Output/$*.out-nat Output/$*.selectivepa.out-nat + -$(DIFFPROG) cbe $*.selectivepa $(HIDEDIFF) + + $(PROGRAMS_TO_TEST:%=Output/%.bumpptr.diff-cbe): \ + Output/%.bumpptr.diff-cbe: Output/%.out-nat Output/%.bumpptr.out-cbe + @cp Output/$*.out-nat Output/$*.bumpptr.out-nat + -$(DIFFPROG) cbe $*.bumpptr $(HIDEDIFF) + + $(PROGRAMS_TO_TEST:%=Output/%.basepa.diff-cbe): \ + Output/%.basepa.diff-cbe: Output/%.out-nat Output/%.basepa.out-cbe + @cp Output/$*.out-nat Output/$*.basepa.out-nat + -$(DIFFPROG) cbe $*.basepa $(HIDEDIFF) + + $(PROGRAMS_TO_TEST:%=Output/%.freeelim.diff-cbe): \ + Output/%.freeelim.diff-cbe: Output/%.out-nat Output/%.freeelim.out-cbe + @cp Output/$*.out-nat Output/$*.freeelim.out-nat + -$(DIFFPROG) cbe $*.freeelim $(HIDEDIFF) + + + + # This rule wraps everything together to build the actual output the report is + # generated from. + $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ + Output/%.$(TEST).report.txt: Output/%.out-nat \ + Output/%.selectivepa.diff-cbe \ + Output/%.bumpptr.diff-cbe \ + Output/%.basepa.diff-cbe \ + Output/%.freeelim.diff-cbe \ + Output/%.LOC.txt + @echo > $@ + @-if test -f Output/$*.basepa.diff-cbe; then \ + printf "CBE-RUN-TIME-BASEPA: " >> $@;\ + grep "^program" Output/$*.basepa.out-cbe.time >> $@;\ + fi + @-if test -f Output/$*.freeelim.diff-cbe; then \ + printf "CBE-RUN-TIME-FREEELIM: " >> $@;\ + grep "^program" Output/$*.freeelim.out-cbe.time >> $@;\ + fi + @-if test -f Output/$*.bumpptr.diff-cbe; then \ + printf "CBE-RUN-TIME-BUMPPTR: " >> $@;\ + grep "^program" Output/$*.bumpptr.out-cbe.time >> $@;\ + fi + @-if test -f Output/$*.selectivepa.diff-cbe; then \ + printf "CBE-RUN-TIME-SELECTIVEPA: " >> $@;\ + grep "^program" Output/$*.selectivepa.out-cbe.time >> $@;\ + fi + + + $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ + test.$(TEST).%: Output/%.$(TEST).report.txt + @echo "---------------------------------------------------------------" + @echo ">>> ========= '$(RELDIR)/$*' Program" + @echo "---------------------------------------------------------------" + @cat $< + + REPORT_DEPENDENCIES := $(PA_RT_O) $(PA_SO) $(PROGRAMS_TO_TEST:%=Output/%.llvm.bc) $(LLC) $(LOPT) Index: poolalloc/test/TEST.optzn.report diff -c /dev/null poolalloc/test/TEST.optzn.report:1.1 *** /dev/null Thu Nov 11 04:13:11 2004 --- poolalloc/test/TEST.optzn.report Thu Nov 11 04:13:00 2004 *************** *** 0 **** --- 1,74 ---- + ##=== TEST.optzn.report - Report description for optzn ---------*- perl -*-===## + # + # This file defines a report to be generated for the pool allocator tests. + # + ##===----------------------------------------------------------------------===## + + # Sort by program name + $SortCol = 0; + $TrimRepeatedPrefix = 1; + + # FormatTime - Convert a time from 1m23.45 into 83.45 + sub FormatTime { + my $Time = shift; + if ($Time =~ m/([0-9]+)[m:]([0-9.]+)/) { + return sprintf("%7.3f", $1*60.0+$2); + } + + return sprintf("%6.2f", $Time); + } + + + sub RuntimePercent { + my ($Cols, $Col) = @_; + if ($Cols->[$Col-1] ne "*" and $Cols->[4] ne "*" and + $Cols->[4] != "0") { + return sprintf "%7.2f", 100*$Cols->[$Col-1]/$Cols->[4]; + } else { + return "n/a"; + } + } + + @LatexColumns = (1, 5, 8, 12, 9, 13, 14, 15, 2, 16); + + my $FREEBENCH = 'MultiSource/Benchmarks/FreeBench'; + my $PTRDIST = 'MultiSource/Benchmarks/Ptrdist'; + + @LatexRowMapOrder = ( + "anagram/anagram" => 'anagram', + "bc/bc" => 'bc', + "ft/ft" => 'ft', + "ks/ks" => 'ks', + "yacr2/yacr2" => 'yacr2', + '-' => '-', + '164.gzip/164.gzip' => '164.gzip', + '175.vpr/175.vpr' => '175.vpr', + '181.mcf/181.mcf' => '181.mcf', + '186.crafty/186.crafty' => '186.crafty', + '197.parser/197.parser' => '197.parser', + '197.parser.hacked/197.parser.hacked' => '197.parser(b)', + '255.vortex/255.vortex' => '255.vortex', + '256.bzip2/256.bzip2' => '256.bzip2', + '300.twolf/300.twolf' => '300.twolf', + '-' => '-', + "analyzer" => 'analyzer', + "llu" => 'llu-bench', + ); + + + # These are the columns for the report. The first entry is the header for the + # column, the second is the regex to use to match the value. Empty list create + # seperators, and closures may be put in for custom processing. + ( + # Name + ["Name:" , '\'([^\']+)\' Program'], + [], + # Times + ["BasePA", 'CBE-RUN-TIME-BASEPA: program\s*([.0-9m:]+)', \&FormatTime], + [], + ["NoSelectivePA", 'CBE-RUN-TIME-SELECTIVEPA: program\s*([.0-9m:]+)', \&FormatTime], + ["NoFreeElim", 'CBE-RUN-TIME-FREEELIM: program\s*([.0-9m:]+)', \&FormatTime], + ["NoBumpPtr", 'CBE-RUN-TIME-BUMPPTR: program\s*([.0-9m:]+)', \&FormatTime], + [] + ); + Index: poolalloc/test/Makefile diff -u poolalloc/test/Makefile:1.26 poolalloc/test/Makefile:1.27 --- poolalloc/test/Makefile:1.26 Tue Nov 9 13:42:15 2004 +++ poolalloc/test/Makefile Thu Nov 11 04:13:00 2004 @@ -158,6 +158,12 @@ test report report.csv) @printf "\a"; sleep 1; printf "\a"; sleep 1; printf "\a" +optzn:: + (cd $(LLVM_OBJ_ROOT)/projects/llvm-test/$(SUBDIR); \ + PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -j1 TEST=optzn \ + GET_STABLE_NUMBERS=1 test report report.csv) + @printf "\a"; sleep 1; printf "\a"; sleep 1; printf "\a" + p4perf:: (cd $(LLVM_OBJ_ROOT)/projects/llvm-test/$(SUBDIR); \ PROJECT_DIR=$(BUILD_OBJ_ROOT) $(MAKE) -j1 TEST=p4perf \ Index: poolalloc/test/TEST.poolalloc.Makefile diff -u poolalloc/test/TEST.poolalloc.Makefile:1.33 poolalloc/test/TEST.poolalloc.Makefile:1.34 --- poolalloc/test/TEST.poolalloc.Makefile:1.33 Wed Nov 10 17:39:08 2004 +++ poolalloc/test/TEST.poolalloc.Makefile Thu Nov 11 04:13:00 2004 @@ -49,7 +49,7 @@ $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).allnodes.bc): \ Output/%.$(TEST).allnodes.bc: Output/%.llvm.bc $(PA_SO) $(LOPT) - at rm -f $(CURDIR)/$@.info - -$(OPT_PA_STATS) -poolalloc -poolalloc-heuristic=AllNodes -pooloptimize $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out + -$(OPT_PA_STATS) -poolalloc -poolalloc-heuristic=AllNodes $(OPTZN_PASSES) -pooloptimize $< -o $@ -f 2>&1 > $@.out $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).mallocrepl.bc): \ @@ -213,7 +213,8 @@ # This rule wraps everything together to build the actual output the report is # generated from. $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ -Output/%.$(TEST).report.txt: Output/%.nonpa.diff-cbe \ +Output/%.$(TEST).report.txt: Output/%.out-nat \ + Output/%.nonpa.diff-cbe \ Output/%.poolalloc.diff-cbe \ Output/%.allnodes.diff-cbe \ Output/%.mallocrepl.diff-cbe \ @@ -221,6 +222,10 @@ Output/%.LOC.txt @echo > $@ @-if test -f Output/$*.nonpa.diff-cbe; then \ + printf "GCC-RUN-TIME: " >> $@;\ + grep "^program" Output/$*.out-nat.time >> $@;\ + fi + @-if test -f Output/$*.nonpa.diff-cbe; then \ printf "CBE-RUN-TIME-NORMAL: " >> $@;\ grep "^program" Output/$*.nonpa.out-cbe.time >> $@;\ fi Index: poolalloc/test/TEST.poolalloc.report diff -u poolalloc/test/TEST.poolalloc.report:1.24 poolalloc/test/TEST.poolalloc.report:1.25 --- poolalloc/test/TEST.poolalloc.report:1.24 Wed Nov 10 17:39:08 2004 +++ poolalloc/test/TEST.poolalloc.report Thu Nov 11 04:13:00 2004 @@ -15,15 +15,15 @@ return sprintf("%7.3f", $1*60.0+$2); } - return sprintf("%7.2f", $Time); + return sprintf("%6.2f", $Time); } sub RuntimePercent { my ($Cols, $Col) = @_; - if ($Cols->[$Col-1] ne "*" and $Cols->[3] ne "*" and - $Cols->[3] != "0") { - return sprintf "%7.2f", 100*$Cols->[$Col-1]/$Cols->[3]; + if ($Cols->[$Col-1] ne "*" and $Cols->[4] ne "*" and + $Cols->[4] != "0") { + return sprintf "%7.2f", 100*$Cols->[$Col-1]/$Cols->[4]; } else { return "n/a"; } @@ -65,7 +65,8 @@ ["LOC" , 'LOC:\s*([0-9]+)'], [], # Times - ["NormalTime", 'CBE-RUN-TIME-NORMAL: program\s*([.0-9m:]+)', \&FormatTime], + ["GCC", 'GCC-RUN-TIME: program\s*([.0-9m:]+)', \&FormatTime], + ["NonPATime", 'CBE-RUN-TIME-NORMAL: program\s*([.0-9m:]+)', \&FormatTime], [], ["OnlyOHTime", 'CBE-RUN-TIME-ONLYOVERHEAD: program\s*([.0-9m:]+)', \&FormatTime], ["OO run%", \&RuntimePercent], From lattner at cs.uiuc.edu Thu Nov 11 16:11:28 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 11 Nov 2004 16:11:28 -0600 Subject: [llvm-commits] CVS: poolalloc/lib/PoolAllocate/EquivClassGraphs.cpp Message-ID: <200411112211.iABMBSag022515@apoc.cs.uiuc.edu> Changes in directory poolalloc/lib/PoolAllocate: EquivClassGraphs.cpp updated: 1.17 -> 1.18 --- Log message: Make this build in release mode --- Diffs of the changes: (+1 -1) Index: poolalloc/lib/PoolAllocate/EquivClassGraphs.cpp diff -u poolalloc/lib/PoolAllocate/EquivClassGraphs.cpp:1.17 poolalloc/lib/PoolAllocate/EquivClassGraphs.cpp:1.18 --- poolalloc/lib/PoolAllocate/EquivClassGraphs.cpp:1.17 Tue Nov 2 14:31:06 2004 +++ poolalloc/lib/PoolAllocate/EquivClassGraphs.cpp Thu Nov 11 16:11:17 2004 @@ -74,7 +74,7 @@ // bool PA::EquivClassGraphs::runOnModule(Module &M) { CBU = &getAnalysis(); - CheckAllGraphs(&M, *CBU); + DEBUG(CheckAllGraphs(&M, *CBU)); GlobalsGraph = new DSGraph(CBU->getGlobalsGraph()); GlobalsGraph->setPrintAuxCalls(); From reid at x10sys.com Thu Nov 11 18:15:54 2004 From: reid at x10sys.com (Reid Spencer) Date: Thu, 11 Nov 2004 18:15:54 -0600 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/llvm-ar.pod Message-ID: <200411120015.SAA12197@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: llvm-ar.pod updated: 1.1 -> 1.2 --- Log message: Document the modifiers and the file format. --- Diffs of the changes: (+131 -23) Index: llvm/docs/CommandGuide/llvm-ar.pod diff -u llvm/docs/CommandGuide/llvm-ar.pod:1.1 llvm/docs/CommandGuide/llvm-ar.pod:1.2 --- llvm/docs/CommandGuide/llvm-ar.pod:1.1 Thu Nov 11 03:21:18 2004 +++ llvm/docs/CommandGuide/llvm-ar.pod Thu Nov 11 18:15:43 2004 @@ -6,7 +6,7 @@ =head1 SYNOPSIS -B [-X32_64] [-]{dmpqrtx}[Rabfouz] [relpos] [count] [files...] +B [-X32_64] [-]{dmpqrtx}[Rabfikouz] [relpos] [count] [files...] =head1 DESCRIPTION @@ -105,9 +105,9 @@ will be moved to the end of the archive. If no F are specified, the archive is not modified. -=item p +=item p[k] -Print files to the standard output. No modifiers are applicable to this +Print files to the standard output. The F modifier applies to this operation. This operation simply prints the F indicated to the standard output. If no F are specified, the entire archive is printed. Printing bytecode files is ill-advised as they might confuse your terminal @@ -139,7 +139,7 @@ those files. If no F are specified, the table of contents for the whole archive is printed. -=item x[o] +=item x[oP] Extract archive members back to files. The F modifier applies to this operation. This operation retrieves the indicated F from the archive @@ -150,76 +150,184 @@ =head2 Modifiers (operation specific) +The modifiers below are specific to certain operations. See the Operations +section (above) to determine which modifiers are applicable to which operations. + =over =item [a] -put F after [relpos] +When inserting or moving member files, this option specifies the destination of +the new files as being Cfter the F member. If F is not found, +the files are placed at the end of the archive. =item [b] -put F before [relpos] (same as [i]) +When inserting or moving member files, this option specifies the destination of +the new files as being Cefore the F member. If F is not +found, the files are placed at the end of the archive. This modifier is +identical to the the F modifier. =item [f] -truncate inserted file names +Normally, B stores the full path name to a file as presented to it on +the command line. With this option, truncated (15 characters max) names are +used. This ensures name compatibility with older versions of C but may also +thwart correct extraction of the files (duplicates may overwrite). If used with +the F option, the directory recursion will be performed but the file names +will all be Clattened to simple file names. =item [i] -put file(s) before [relpos] (same as [b]) +A synonym for the F option. + +=item [k] + +Normally, B will not print the contents of bytecode files when the +F

    operation is used. This modifier defeats the default and allows the +bytecode members to be printed. =item [N] -use instance [count] of name +This option is ignored by B but provided for compatibility. =item [o] -preserve original dates +When extracting files, this option will cause B to preserve the +original modification times of the files it writes. =item [P] use full path names when matching -=item [R] +=item [R] -recurse through directories when inserting +This modifier instructions the F option to recursively process directories. +Without F, directories are ignored and only those F that refer to +files will be added to the archive. When F is used, any directories specified +with F will be scanned (recursively) to find files to be added to the +archive. Any file whose name begins with a dot will not be added. =item [u] -update only files newer than archive contents +When replacing existing files in the archive, only replace those files that have +a timestamp than the timestamp of the member in the archive. =item [z] -compress/uncompress files before inserting/extracting +When inserting or replacing any file in the archive, compress the file first. +The compression will attempt to use the zlib compression algorithm. This +modifier is safe to use when (previously) compressed bytecode files are added to +the archive; the compress bytecode files will not be doubly compressed. =back =head2 Modifiers (generic) +The modifiers below may be applied to any operation. + =over =item [c] -do not warn if the library had to be created +For all operations, B will always create the archive if it doesn't +exist. Normally, B will print a warning message indicating that the +archive is being created. Using this modifier turns off that warning. =item [s] -create an archive index (cf. ranlib) +This modifier requests that an archive index (or symbol table) be added to the +archive. This is the default mode of operation. The symbol table will contain +all the externally visible functions and global variables defined by all the +bytecode files in the archive. Using this modifer is more efficient that using +L which also creates the symbol table. =item [S] -do not build a symbol table - -=item [R] - -recursively process directories +This modifier is the opposite of the F modifier. It instructs B to +not build the symbol table. If both F and F are used, the last modifier to +occur in the options will prevail. =item [v] -be verbose +This modifier instructs B to be verbose about what it is doing. Each +editing operation taken agains the archive will produce a line of output saying +what is being done. =back +=head1 FILE FORMAT + +The file format for LLVM Archive files is similar to that of BSD 4.4 or Mac OSX +archive files. In fact, except for the symbol table, the C commands on those +operating systems should be able to read LLVM archive files. The details of the +file format follow. + +Each archive begins with the archive magic number which is the eight printable +characters !\n where \n represents the newline character (0x0A). Following +the magic number, the file is composed of even length members that begin with an +archive header and end with a \n padding character if necessary (to make the +length even). Each file member is composed of a header (defined below), an +optional null-terminated "long file name" and the contents of the file. + +The fields of the header are described in the items below. All fields of the +header contain only ASCII characters, are left justified and are right padded +with space characters. + +=over + +=item name - char[16] + +This field of the header provides the name of the archive member. If the name is +longer than 15 characters or contains a slash (/) character, then this field +contains C<#1/nnn> where C provides the length of the name and the C<#1/> +is literal. In this case, the actual name of the file is provided in the C +bytes immediately following the header. If the name is 15 characters or less, it +is contained directly in this field and terminated with a slash (/) character. + +=item date - char[12] + +This field provides the date of modification of the file in the form of a +decimal encoded number that provides the number of seconds since the epoch +(since 00:00:00 Jan 1, 1970) per Posix specifications. + +=item uid - char[6] + +This field provides the user id of the file encoded as a decimal ascii string. +This field might not make much sense on non-Unix systems. On Unix, it is the +same value as the st_uid field of the stat structure returned by the stat(2) +operating system call. + +=item gid - char[6] + +This field provides the group id of the file encoded as a decimal ascii string. +This field might not make much sense on non-Unix systems. On Unix, it is the +same value as the st_gid field of the stat structure returned by the stat(2) +operating system call. + +=item mode - char[8] + +This field provides the access mode of the file encoded as an octal ascii +string. This field might not make much sense on non-Unix systems. On Unix, it +is the same value as the st_mode field of the stat structure returned by the +stat(2) operating system call. + +=item size - char[10] + +This field provides the size of the file, in bytes, encoded as a decimal ascii +string. If the size field is negative (starts with a minus sign, 0x02D), then +the archive member is stored in compressed form. The first byte of the archive +member's data indicates the compression type used. A value of 0 (0x30) indicates +that no compression was used. A value of 1 (0x31) indicates that zlib +compression was used. A value of 2 (0x32) indicates that bzip2 compression was +used. + +=item fmag - char[2] + +This field is the archive file member magic number. Its content is always the +two characters backtick (0x60) and newline (0x0A). This provides some measure +utility in identifying archive files that have been corrupted. + =head1 EXIT STATUS If B succeeds, it will exit with 0. A usage error, results @@ -229,7 +337,7 @@ =head1 SEE ALSO -L +L, L =head1 AUTHORS From reid at x10sys.com Thu Nov 11 18:17:01 2004 From: reid at x10sys.com (Reid Spencer) Date: Thu, 11 Nov 2004 18:17:01 -0600 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/llvm-ar.pod Message-ID: <200411120017.SAA12283@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: llvm-ar.pod updated: 1.2 -> 1.3 --- Log message: Correctly terminate a list. --- Diffs of the changes: (+2 -0) Index: llvm/docs/CommandGuide/llvm-ar.pod diff -u llvm/docs/CommandGuide/llvm-ar.pod:1.2 llvm/docs/CommandGuide/llvm-ar.pod:1.3 --- llvm/docs/CommandGuide/llvm-ar.pod:1.2 Thu Nov 11 18:15:43 2004 +++ llvm/docs/CommandGuide/llvm-ar.pod Thu Nov 11 18:16:51 2004 @@ -328,6 +328,8 @@ two characters backtick (0x60) and newline (0x0A). This provides some measure utility in identifying archive files that have been corrupted. +=back + =head1 EXIT STATUS If B succeeds, it will exit with 0. A usage error, results From reid at x10sys.com Thu Nov 11 18:18:46 2004 From: reid at x10sys.com (Reid Spencer) Date: Thu, 11 Nov 2004 18:18:46 -0600 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/llvm-ranlib.pod Message-ID: <200411120018.SAA12423@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: llvm-ranlib.pod added (r1.1) --- Log message: Document the new llvm-ranlib command. --- Diffs of the changes: (+52 -0) Index: llvm/docs/CommandGuide/llvm-ranlib.pod diff -c /dev/null llvm/docs/CommandGuide/llvm-ranlib.pod:1.1 *** /dev/null Thu Nov 11 18:18:46 2004 --- llvm/docs/CommandGuide/llvm-ranlib.pod Thu Nov 11 18:18:35 2004 *************** *** 0 **** --- 1,52 ---- + =pod + + =head1 NAME + + llvm-ranlib - Generate index for LLVM archive + + =head1 SYNOPSIS + + B [--version] [--help] + + =head1 DESCRIPTION + + The B command is similar to the common Unix utility, C. It + adds or updates the symbol table in an LLVM archive file. Note that using the + B modifier F is usually more efficient than running B + which is only provided only for completness and compatibility. Unlike other + implementations of C, B indexes LLVM bytecode files, not + native object modules. You can list the contents of the symbol table with the + C command. + + =head1 OPTIONS + + =over + + =item F + + Specifies the archive-file to which the symbol table is added or updated. + + =item F<--version> + + Print the version of B and exit without building a symbol table. + + =item F<--help> + + Print usage help for B and exit without building a symbol table. + + =back + + =head1 EXIT STATUS + + If B succeeds, it will exit with 0. If an error occurs, a non-zero + exit code will be returned. + + =head1 SEE ALSO + + L,L + + =head1 AUTHORS + + Maintained by the LLVM Team (L). + + =cut From reid at x10sys.com Thu Nov 11 20:27:47 2004 From: reid at x10sys.com (Reid Spencer) Date: Thu, 11 Nov 2004 20:27:47 -0600 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200411120227.UAA15326@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.233 -> 1.234 --- Log message: * Clean up all the shared library output on uninstall * Provide the correct set of input directories to the TAGS target * Provide a CTAGS target for building Vi style ctags files. --- Diffs of the changes: (+17 -3) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.233 llvm/Makefile.rules:1.234 --- llvm/Makefile.rules:1.233 Mon Nov 8 11:32:11 2004 +++ llvm/Makefile.rules Thu Nov 11 20:27:36 2004 @@ -482,7 +482,7 @@ uninstall-local:: $(Echo) Uninstalling $(BuildMode) Shared Library $(DestSharedLib) - -$(Verb) $(RM) -f $(DestSharedLib) + -$(Verb) $(RM) -f $(libdir)/lib$(LIBRARYNAME).* endif @@ -922,11 +922,25 @@ -$(Verb) $(RM) -rf Debug Release Profile # Build tags database for Emacs/Xemacs: -tags:: TAGS +tags:: TAGS CTAGS + TAGS: - find include lib tools examples -name '*.cpp' -o -name '*.h' | \ + find $(BUILD_SRC_ROOT)/include $(BUILD_SRC_ROOT)/lib \ + $(BUILD_SRC_ROOT)/tools $(BUILD_SRC_ROOT)/examples \ + $(BUILD_OBJ_ROOT)/include $(BUILD_OBJ_ROOT)/lib \ + $(BUILD_OBJ_ROOT)/tools $(BUILD_OBJ_ROOT)/examples \ + -name '*.cpp' -o -name '*.h' | \ $(ETAGS) $(ETAGSFLAGS) - +CTAGS: + find $(BUILD_SRC_ROOT)/include $(BUILD_SRC_ROOT)/lib \ + $(BUILD_SRC_ROOT)/tools $(BUILD_SRC_ROOT)/examples \ + $(BUILD_OBJ_ROOT)/include $(BUILD_OBJ_ROOT)/lib \ + $(BUILD_OBJ_ROOT)/tools $(BUILD_OBJ_ROOT)/examples \ + \( -name '*.cpp' -o -name '*.h' \) -print | \ + ctags -ImtT -o $(BUILD_OBJ_ROOT)/CTAGS -L - + + ############################################################################### # DEPENDENCIES: Include the dependency files if we should ############################################################################### From criswell at cs.uiuc.edu Fri Nov 12 14:08:46 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 12 Nov 2004 14:08:46 -0600 (CST) Subject: [llvm-commits] CVS: poolalloc/test/TEST.cputrack.report Message-ID: <200411122008.OAA26456@kain.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.cputrack.report updated: 1.2 -> 1.3 --- Log message: Update to handle new changes in TEST.cputrack.Makefile. --- Diffs of the changes: (+2 -2) Index: poolalloc/test/TEST.cputrack.report diff -u poolalloc/test/TEST.cputrack.report:1.2 poolalloc/test/TEST.cputrack.report:1.3 --- poolalloc/test/TEST.cputrack.report:1.2 Wed Nov 3 13:10:42 2004 +++ poolalloc/test/TEST.cputrack.report Fri Nov 12 14:08:35 2004 @@ -82,13 +82,13 @@ ["NormalL1DataMiss", 'CBE-L1-Data-Misses: ([0-9]+)'], ["NormalL2DataReadMiss", 'CBE-L2-Data-Read-Misses: ([0-9]+)'], ["NormalL2DataMiss", 'CBE-L2-Data-Misses: ([0-9]+)'], - ["NormalWriteCacheMiss", 'CBE-WriteCache-Misses: ([0-9]+)'], + ["NormalWriteCacheMiss", 'CBE-WCache-Misses: ([0-9]+)'], ["PoolAllocL1DataRead", 'CBE-PA-L1-Data-Reads: ([0-9]+)'], ["PoolAllocL1DataMiss", 'CBE-PA-L1-Data-Misses: ([0-9]+)'], ["PoolAllocL2DataReadMiss", 'CBE-PA-L2-Data-Read-Misses: ([0-9]+)'], ["PoolAllocL2DataMiss", 'CBE-PA-L2-Data-Misses: ([0-9]+)'], - ["PoolAllocWriteCacheMiss", 'CBE-PA-WriteCache-Misses: ([0-9]+)'], + ["PoolAllocWriteCacheMiss", 'CBE-PA-WCache-Misses: ([0-9]+)'], [] ); From criswell at cs.uiuc.edu Fri Nov 12 14:09:00 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 12 Nov 2004 14:09:00 -0600 (CST) Subject: [llvm-commits] CVS: poolalloc/test/TEST.cputrack.Makefile Message-ID: <200411122009.OAA26461@kain.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.cputrack.Makefile updated: 1.7 -> 1.8 --- Log message: Re-did Solaris cache measurements, basing it off of the perfctr changes Chris made to TEST.perf.Makefile. --- Diffs of the changes: (+128 -51) Index: poolalloc/test/TEST.cputrack.Makefile diff -u poolalloc/test/TEST.cputrack.Makefile:1.7 poolalloc/test/TEST.cputrack.Makefile:1.8 --- poolalloc/test/TEST.cputrack.Makefile:1.7 Fri Nov 5 12:08:50 2004 +++ poolalloc/test/TEST.cputrack.Makefile Fri Nov 12 14:08:19 2004 @@ -9,13 +9,18 @@ PROGDIR := $(shell cd $(LLVM_SRC_ROOT)/projects/llvm-test; pwd)/ RELDIR := $(subst $(PROGDIR),,$(CURDIR)) - # -# Solaris cputrack command that will sample the counters every 500 ticks. -# All programs must complete in under 500 ticks (500 seconds by default), -# and the counters must not wrap around +# The Solaris cputrack command samples the performance counters every x number +# of ticks (by default, I believe one tick == 1 second). +# +# Use the cputrack command and set the interval to the maximum amount of time +# that the program is allowed to run. +# +# Care must be taken to ensure that the counters do not wrap around. So +# far, I don't believe this has happened, as that would require over +# 4 billion events per execution. # -CPUTRACK := cputrack -T 500 +CPUTRACK := cputrack -T $(RUNTIMELIMIT) # # Events for the Ultrasparc IIIi processor. @@ -38,68 +43,138 @@ EVENTS_TLB := -c pic0=EC_rd_miss,pic1=DTLB_miss EVENTS_WC := -c pic0=Cycle_cnt,pic1=WC_miss -# -# Once the results are generated, create files containing each individiual -# piece of performance information. -# +############################################################################ +# Rules for running the tests +############################################################################ + +ifndef PROGRAMS_HAVE_CUSTOM_RUN_RULES # # Generate events for Pool Allocated CBE # -$(PROGRAMS_TO_TEST:%=Output/test.$(TEST).pa.%): \ -Output/test.$(TEST).pa.%: Output/%.poolalloc.cbe Output/test.$(TEST).% +$(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.dcrd): \ +Output/$(TEST).pa.%.dcrd: Output/%.poolalloc.cbe @echo "=========================================" @echo "Running '$(TEST)' test on '$(TESTNAME)' program" -ifeq ($(RUN_OPTIONS),) - $(VERB) cat $(STDIN_FILENAME) | $(CPUTRACK) $(EVENTS_DC_RD) -o $@.dcrd $< - $(VERB) cat $(STDIN_FILENAME) | $(CPUTRACK) $(EVENTS_EC_MISS) -o $@.ec $< - $(VERB) cat $(STDIN_FILENAME) | $(CPUTRACK) $(EVENTS_WC) -o $@.wc $< -else - $(VERB) cat $(STDIN_FILENAME) | $(CPUTRACK) $(EVENTS_DC_RD) -o $@.dcrd $< $(RUN_OPTIONS) - $(VERB) cat $(STDIN_FILENAME) | $(CPUTRACK) $(EVENTS_EC_MISS) -o $@.ec $< $(RUN_OPTIONS) - $(VERB) cat $(STDIN_FILENAME) | $(CPUTRACK) $(EVENTS_WC) -o $@.wc $< $(RUN_OPTIONS) -endif - $(VERB) cat $@.dcrd | tail -1 | awk '{print $$4}' > $@.dcrd.total - $(VERB) cat $@.dcrd | tail -1 | awk '{print $$5}' > $@.dcrd.misses - $(VERB) cat $@.ec | tail -1 | awk '{print $$4}' > $@.ec.rdmiss - $(VERB) cat $@.ec | tail -1 | awk '{print $$5}' > $@.ec.allmiss - $(VERB) cat $@.wc | tail -1 | awk '{print $$5}' > $@.wc.miss + $(VERB) $(CPUTRACK) $(EVENTS_DC_RD) -o $@ $< $(RUN_OPTIONS) < $(STDIN_FILENAME) > /dev/null 2>&1 + + +$(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.ec): \ +Output/$(TEST).pa.%.ec: Output/%.poolalloc.cbe + @echo "=========================================" + @echo "Running '$(TEST)' test on '$(TESTNAME)' program" + $(VERB) $(CPUTRACK) $(EVENTS_EC_MISS) -o $@ $< $(RUN_OPTIONS) < $(STDIN_FILENAME) > /dev/null 2>&1 + +$(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.wc): \ +Output/$(TEST).pa.%.wc: Output/%.poolalloc.cbe + @echo "=========================================" + @echo "Running '$(TEST)' test on '$(TESTNAME)' program" + $(VERB) $(CPUTRACK) $(EVENTS_WC) -o $@ $< $(RUN_OPTIONS) < $(STDIN_FILENAME) > /dev/null 2>&1 # # Generate events for CBE # -$(PROGRAMS_TO_TEST:%=Output/test.$(TEST).%): \ -Output/test.$(TEST).%: Output/%.cbe +$(PROGRAMS_TO_TEST:%=Output/$(TEST).%.dcrd): \ +Output/$(TEST).%.dcrd: Output/%.nonpa.cbe + @echo "=========================================" + @echo "Running '$(TEST)' test on '$(TESTNAME)' program" + $(VERB) $(CPUTRACK) $(EVENTS_DC_RD) -o $@ $< $(RUN_OPTIONS) < $(STDIN_FILENAME) > /dev/null 2>&1 + +$(PROGRAMS_TO_TEST:%=Output/$(TEST).%.ec): \ +Output/$(TEST).%.ec: Output/%.nonpa.cbe @echo "=========================================" @echo "Running '$(TEST)' test on '$(TESTNAME)' program" -ifeq ($(RUN_OPTIONS),) - $(VERB) cat $(STDIN_FILENAME) | $(CPUTRACK) $(EVENTS_DC_RD) -o $@.dcrd $< - $(VERB) cat $(STDIN_FILENAME) | $(CPUTRACK) $(EVENTS_EC_MISS) -o $@.ec $< - $(VERB) cat $(STDIN_FILENAME) | $(CPUTRACK) $(EVENTS_WC) -o $@.wc $< + $(VERB) $(CPUTRACK) $(EVENTS_EC_MISS) -o $@ $< $(RUN_OPTIONS) < $(STDIN_FILENAME) > /dev/null 2>&1 + +$(PROGRAMS_TO_TEST:%=Output/$(TEST).%.wc): \ +Output/$(TEST).%.wc: Output/%.nonpa.cbe + @echo "=========================================" + @echo "Running '$(TEST)' test on '$(TESTNAME)' program" + $(VERB) $(CPUTRACK) $(EVENTS_WC) -o $@ $< $(RUN_OPTIONS) < $(STDIN_FILENAME) > /dev/null 2>&1 + else - $(VERB) cat $(STDIN_FILENAME) | $(CPUTRACK) $(EVENTS_DC_RD) -o $@.dcrd $< $(RUN_OPTIONS) - $(VERB) cat $(STDIN_FILENAME) | $(CPUTRACK) $(EVENTS_EC_MISS) -o $@.ec $< $(RUN_OPTIONS) - $(VERB) cat $(STDIN_FILENAME) | $(CPUTRACK) $(EVENTS_WC) -o $@.wc $< $(RUN_OPTIONS) + +# This rule runs the generated executable, generating timing information, for +# SPEC +$(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.dcrd): \ +Output/$(TEST).pa.%.dcrd: Output/%.poolalloc.cbe + -$(SPEC_SANDBOX) poolalloccbe-$(RUN_TYPE) $@.out $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + $(CPUTRACK) $(EVENTS_DC_RD) -o $(BUILD_OBJ_DIR)/$@ $(BUILD_OBJ_DIR)/$< $(RUN_OPTIONS) + + +$(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.ec): \ +Output/$(TEST).pa.%.ec: Output/%.poolalloc.cbe + -$(SPEC_SANDBOX) poolalloccbe-$(RUN_TYPE) $@.out $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + $(CPUTRACK) $(EVENTS_EC_MISS) -o $(BUILD_OBJ_DIR)/$@ $(BUILD_OBJ_DIR)/$< $(RUN_OPTIONS) + +$(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.wc): \ +Output/$(TEST).pa.%.wc: Output/%.poolalloc.cbe + -$(SPEC_SANDBOX) poolalloccbe-$(RUN_TYPE) $@.out $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + $(CPUTRACK) $(EVENTS_WC) -o $(BUILD_OBJ_DIR)/$@ $(BUILD_OBJ_DIR)/$< $(RUN_OPTIONS) + +# This rule runs the generated executable, generating timing information, for +# SPEC +$(PROGRAMS_TO_TEST:%=Output/$(TEST).%.dcrd): \ +Output/$(TEST).%.dcrd: Output/%.nonpa.cbe + -$(SPEC_SANDBOX) nonpacbe-$(RUN_TYPE) $@.out $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + $(CPUTRACK) $(EVENTS_DC_RD) -o $(BUILD_OBJ_DIR)/$@ $(BUILD_OBJ_DIR)/$< $(RUN_OPTIONS) + +$(PROGRAMS_TO_TEST:%=Output/$(TEST).%.ec): \ +Output/$(TEST).%.ec: Output/%.nonpa.cbe + -$(SPEC_SANDBOX) nonpacbe-$(RUN_TYPE) $@.out $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + $(CPUTRACK) $(EVENTS_EC_MISS) -o $(BUILD_OBJ_DIR)/$@ $(BUILD_OBJ_DIR)/$< $(RUN_OPTIONS) + +$(PROGRAMS_TO_TEST:%=Output/$(TEST).%.wc): \ +Output/$(TEST).%.wc: Output/%.nonpa.cbe + -$(SPEC_SANDBOX) nonpacbe-$(RUN_TYPE) $@.out $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + $(CPUTRACK) $(EVENTS_WC) -o $(BUILD_OBJ_DIR)/$@ $(BUILD_OBJ_DIR)/$< $(RUN_OPTIONS) endif - $(VERB) cat $@.dcrd | tail -1 | awk '{print $$4}' > $@.dcrd.total - $(VERB) cat $@.dcrd | tail -1 | awk '{print $$5}' > $@.dcrd.misses - $(VERB) cat $@.ec | tail -1 | awk '{print $$4}' > $@.ec.rdmiss - $(VERB) cat $@.ec | tail -1 | awk '{print $$5}' > $@.ec.allmiss - $(VERB) cat $@.wc | tail -1 | awk '{print $$5}' > $@.wc.miss +############################################################################ +# Report Targets +############################################################################ $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ -Output/%.$(TEST).report.txt: Output/test.$(TEST).pa.% Output/test.$(TEST).% - @printf "CBE-PA-L1-Data-Reads: %d\n" `cat Output/test.$(TEST).pa.$*.dcrd.total` > $@ - @printf "CBE-PA-L1-Data-Misses: %d\n" `cat Output/test.$(TEST).pa.$*.dcrd.misses` >> $@ - @printf "CBE-L1-Data-Reads: %d\n" `cat Output/test.$(TEST).$*.dcrd.total` >> $@ - @printf "CBE-L1-Data-Misses: %d\n" `cat Output/test.$(TEST).$*.dcrd.misses` >> $@ - @printf "CBE-PA-L2-Data-Read-Misses: %d\n" `cat Output/test.$(TEST).pa.$*.ec.rdmiss` >> $@ - @printf "CBE-PA-L2-Data-Misses: %d\n" `cat Output/test.$(TEST).pa.$*.ec.allmiss` >> $@ - @printf "CBE-L2-Data-Read-Misses: %d\n" `cat Output/test.$(TEST).$*.ec.rdmiss` >> $@ - @printf "CBE-L2-Data-Misses: %d\n" `cat Output/test.$(TEST).$*.ec.allmiss` >> $@ - @printf "CBE-PA-WriteCache-Misses: %d\n" `cat Output/test.$(TEST).pa.$*.wc.miss` >> $@ - @printf "CBE-WriteCache-Misses: %d\n" `cat Output/test.$(TEST).$*.wc.miss` >> $@ - @touch $@ +Output/%.$(TEST).report.txt: \ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).%.dcrd) \ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.dcrd) \ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).%.wc) \ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.wc) \ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).%.ec) \ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.ec) \ + $(PROGRAMS_TO_TEST:%=Output/%.poolalloc.out-cbe.time) \ + $(PROGRAMS_TO_TEST:%=Output/%.nonpa.out-cbe.time) + @echo "Program:" $* > $@ + @echo "-------------------------------------------------------------" >> $@ + @printf "CBE-PA-L1-Data-Reads: " >> $@ + @cat Output/$(TEST).pa.$*.dcrd | tail -1 | awk '{print $$4}' >> $@ + @printf "CBE-PA-L1-Data-Misses: " >> $@ + @cat Output/$(TEST).pa.$*.dcrd | tail -1 | awk '{print $$5}' >> $@ + @printf "CBE-L1-Data-Reads: " >> $@ + @cat Output/$(TEST).$*.dcrd | tail -1 | awk '{print $$4}' >> $@ + @printf "CBE-L1-Data-Misses: " >> $@ + @cat Output/$(TEST).$*.dcrd | tail -1 | awk '{print $$5}' >> $@ + @printf "CBE-PA-WCache-Misses: " >> $@ + @cat Output/$(TEST).pa.$*.wc | tail -1 | awk '{print $$5}' >> $@ + @printf "CBE-WCache-Misses: " >> $@ + @cat Output/$(TEST).$*.wc | tail -1 | awk '{print $$5}' >> $@ + @printf "CBE-PA-L2-Data-Read-Misses: " >> $@ + @cat Output/$(TEST).pa.$*.ec | tail -1 | awk '{print $$4}' >> $@ + @printf "CBE-PA-L2-Data-Misses: " >> $@ + @cat Output/$(TEST).pa.$*.ec | tail -1 | awk '{print $$5}' >> $@ + @printf "CBE-L2-Data-Read-Misses: " >> $@ + @cat Output/$(TEST).$*.ec | tail -1 | awk '{print $$4}' >> $@ + @printf "CBE-L2-Data-Misses: " >> $@ + @cat Output/$(TEST).$*.ec | tail -1 | awk '{print $$5}' >> $@ + @printf "CBE-RUN-TIME: " >> $@ + @grep "^program" Output/$*.nonpa.out-cbe.time >> $@ + @printf "CBE-PA-RUN-TIME: " >> $@ + @grep "^program" Output/$*.poolalloc.out-cbe.time >> $@ $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ test.$(TEST).%: Output/%.$(TEST).report.txt @@ -108,3 +183,5 @@ @echo "---------------------------------------------------------------" @cat $< +REPORT_DEPENDENCIES := $(PROGRAMS_TO_TEST:%=Output/%.poolalloc.out-cbe.time) \ + $(PROGRAMS_TO_TEST:%=Output/%.nonpa.out-cbe.time) From criswell at cs.uiuc.edu Fri Nov 12 14:09:54 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 12 Nov 2004 14:09:54 -0600 Subject: [llvm-commits] CVS: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp Message-ID: <200411122009.OAA06979@choi.cs.uiuc.edu> Changes in directory poolalloc/runtime/FL2Allocator: FreeListAllocator.cpp updated: 1.29 -> 1.30 --- Log message: Fixed warnings and errors on Sparc by making the code generate 64 bit integers when on Solaris. --- Diffs of the changes: (+4 -3) Index: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp diff -u poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.29 poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.30 --- poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.29 Wed Nov 10 23:46:41 2004 +++ poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp Fri Nov 12 14:09:43 2004 @@ -19,6 +19,7 @@ #include typedef long intptr_t; +typedef unsigned long uintptr_t; // Performance tweaking macros. #define INITIAL_SLAB_SIZE 4096 @@ -65,7 +66,7 @@ for (unsigned i = 0; i != NumLivePools; ++i) if (PoolIDs[i].PD == PD) return PoolIDs[i].ID; - fprintf(stderr, "INVALID/UNKNOWN POOL DESCRIPTOR: 0x%X\n", (unsigned)PD); + fprintf(stderr, "INVALID/UNKNOWN POOL DESCRIPTOR: 0x%lX\n", (unsigned long)PD); return 0; } @@ -77,7 +78,7 @@ --NumLivePools; return PN; } - fprintf(stderr, "INVALID/UNKNOWN POOL DESCRIPTOR: 0x%X\n", (unsigned)PD); + fprintf(stderr, "INVALID/UNKNOWN POOL DESCRIPTOR: 0x%lX\n", (unsigned long)PD); return 0; } @@ -279,7 +280,7 @@ if (NumBytes < 1) NumBytes = 1; - unsigned Alignment; + uintptr_t Alignment; char *BumpPtr, *EndPtr; Alignment = Pool->Alignment-1; BumpPtr = (char*)Pool->ObjFreeList; // Get our bump pointer. From llvm at cs.uiuc.edu Fri Nov 12 14:20:25 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Fri, 12 Nov 2004 14:20:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/Linker/ Message-ID: <200411122020.OAA13715@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: --- Log message: Directory /var/cvs/llvm/llvm/lib/Linker added to the repository --- Diffs of the changes: (+0 -0) From criswell at cs.uiuc.edu Fri Nov 12 14:21:13 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 12 Nov 2004 14:21:13 -0600 (CST) Subject: [llvm-commits] CVS: poolalloc/test/TEST.cputrack.Makefile TEST.cputrack.report Message-ID: <200411122021.OAA26828@kain.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.cputrack.Makefile updated: 1.8 -> 1.9 TEST.cputrack.report updated: 1.3 -> 1.4 --- Log message: Added support for getting some TLB misses. --- Diffs of the changes: (+32 -1) Index: poolalloc/test/TEST.cputrack.Makefile diff -u poolalloc/test/TEST.cputrack.Makefile:1.8 poolalloc/test/TEST.cputrack.Makefile:1.9 --- poolalloc/test/TEST.cputrack.Makefile:1.8 Fri Nov 12 14:08:19 2004 +++ poolalloc/test/TEST.cputrack.Makefile Fri Nov 12 14:21:03 2004 @@ -71,6 +71,12 @@ @echo "Running '$(TEST)' test on '$(TESTNAME)' program" $(VERB) $(CPUTRACK) $(EVENTS_WC) -o $@ $< $(RUN_OPTIONS) < $(STDIN_FILENAME) > /dev/null 2>&1 +$(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.tlb): \ +Output/$(TEST).pa.%.tlb: Output/%.poolalloc.cbe + @echo "=========================================" + @echo "Running '$(TEST)' test on '$(TESTNAME)' program" + $(VERB) $(CPUTRACK) $(EVENTS_TLB) -o $@ $< $(RUN_OPTIONS) < $(STDIN_FILENAME) > /dev/null 2>&1 + # # Generate events for CBE # @@ -92,6 +98,12 @@ @echo "Running '$(TEST)' test on '$(TESTNAME)' program" $(VERB) $(CPUTRACK) $(EVENTS_WC) -o $@ $< $(RUN_OPTIONS) < $(STDIN_FILENAME) > /dev/null 2>&1 +$(PROGRAMS_TO_TEST:%=Output/$(TEST).%.tlb): \ +Output/$(TEST).%.tlb: Output/%.nonpa.cbe + @echo "=========================================" + @echo "Running '$(TEST)' test on '$(TESTNAME)' program" + $(VERB) $(CPUTRACK) $(EVENTS_TLB) -o $@ $< $(RUN_OPTIONS) < $(STDIN_FILENAME) > /dev/null 2>&1 + else # This rule runs the generated executable, generating timing information, for @@ -102,7 +114,6 @@ $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ $(CPUTRACK) $(EVENTS_DC_RD) -o $(BUILD_OBJ_DIR)/$@ $(BUILD_OBJ_DIR)/$< $(RUN_OPTIONS) - $(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.ec): \ Output/$(TEST).pa.%.ec: Output/%.poolalloc.cbe -$(SPEC_SANDBOX) poolalloccbe-$(RUN_TYPE) $@.out $(REF_IN_DIR) \ @@ -115,6 +126,12 @@ $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ $(CPUTRACK) $(EVENTS_WC) -o $(BUILD_OBJ_DIR)/$@ $(BUILD_OBJ_DIR)/$< $(RUN_OPTIONS) +$(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.tlb): \ +Output/$(TEST).pa.%.tlb: Output/%.poolalloc.cbe + -$(SPEC_SANDBOX) poolalloccbe-$(RUN_TYPE) $@.out $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + $(CPUTRACK) $(EVENTS_TLB) -o $(BUILD_OBJ_DIR)/$@ $(BUILD_OBJ_DIR)/$< $(RUN_OPTIONS) + # This rule runs the generated executable, generating timing information, for # SPEC $(PROGRAMS_TO_TEST:%=Output/$(TEST).%.dcrd): \ @@ -134,6 +151,12 @@ -$(SPEC_SANDBOX) nonpacbe-$(RUN_TYPE) $@.out $(REF_IN_DIR) \ $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ $(CPUTRACK) $(EVENTS_WC) -o $(BUILD_OBJ_DIR)/$@ $(BUILD_OBJ_DIR)/$< $(RUN_OPTIONS) + +$(PROGRAMS_TO_TEST:%=Output/$(TEST).%.tlb): \ +Output/$(TEST).%.tlb: Output/%.nonpa.cbe + -$(SPEC_SANDBOX) nonpacbe-$(RUN_TYPE) $@.out $(REF_IN_DIR) \ + $(RUNSAFELY) $(STDIN_FILENAME) $(STDOUT_FILENAME) \ + $(CPUTRACK) $(EVENTS_TLB) -o $(BUILD_OBJ_DIR)/$@ $(BUILD_OBJ_DIR)/$< $(RUN_OPTIONS) endif ############################################################################ @@ -147,6 +170,8 @@ $(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.wc) \ $(PROGRAMS_TO_TEST:%=Output/$(TEST).%.ec) \ $(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.ec) \ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).%.tlb) \ + $(PROGRAMS_TO_TEST:%=Output/$(TEST).pa.%.tlb) \ $(PROGRAMS_TO_TEST:%=Output/%.poolalloc.out-cbe.time) \ $(PROGRAMS_TO_TEST:%=Output/%.nonpa.out-cbe.time) @echo "Program:" $* > $@ @@ -171,6 +196,10 @@ @cat Output/$(TEST).$*.ec | tail -1 | awk '{print $$4}' >> $@ @printf "CBE-L2-Data-Misses: " >> $@ @cat Output/$(TEST).$*.ec | tail -1 | awk '{print $$5}' >> $@ + @printf "CBE-PA-DTLB-Misses: " >> $@ + @cat Output/$(TEST).pa.$*.tlb | tail -1 | awk '{print $$5}' >> $@ + @printf "CBE-DTLB-Misses: " >> $@ + @cat Output/$(TEST).$*.tlb | tail -1 | awk '{print $$5}' >> $@ @printf "CBE-RUN-TIME: " >> $@ @grep "^program" Output/$*.nonpa.out-cbe.time >> $@ @printf "CBE-PA-RUN-TIME: " >> $@ Index: poolalloc/test/TEST.cputrack.report diff -u poolalloc/test/TEST.cputrack.report:1.3 poolalloc/test/TEST.cputrack.report:1.4 --- poolalloc/test/TEST.cputrack.report:1.3 Fri Nov 12 14:08:35 2004 +++ poolalloc/test/TEST.cputrack.report Fri Nov 12 14:21:03 2004 @@ -83,12 +83,14 @@ ["NormalL2DataReadMiss", 'CBE-L2-Data-Read-Misses: ([0-9]+)'], ["NormalL2DataMiss", 'CBE-L2-Data-Misses: ([0-9]+)'], ["NormalWriteCacheMiss", 'CBE-WCache-Misses: ([0-9]+)'], + ["NormalDTLBMiss", 'CBE-DTLB-Misses: ([0-9]+)'], ["PoolAllocL1DataRead", 'CBE-PA-L1-Data-Reads: ([0-9]+)'], ["PoolAllocL1DataMiss", 'CBE-PA-L1-Data-Misses: ([0-9]+)'], ["PoolAllocL2DataReadMiss", 'CBE-PA-L2-Data-Read-Misses: ([0-9]+)'], ["PoolAllocL2DataMiss", 'CBE-PA-L2-Data-Misses: ([0-9]+)'], ["PoolAllocWriteCacheMiss", 'CBE-PA-WCache-Misses: ([0-9]+)'], + ["PoolAllocDTLBMiss", 'CBE-PA-DTLB-Misses: ([0-9]+)'], [] ); From reid at x10sys.com Fri Nov 12 14:35:09 2004 From: reid at x10sys.com (Reid Spencer) Date: Fri, 12 Nov 2004 14:35:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/Linker/LinkArchives.cpp Message-ID: <200411122035.OAA14025@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: LinkArchives.cpp updated: 1.30 -> 1.31 --- Log message: This file originated in tools/gccld/Linker.cpp but now lives in lib/Linker/LinkArchives.cpp --- Diffs of the changes: (+1 -1) Index: llvm/lib/Linker/LinkArchives.cpp diff -u llvm/lib/Linker/LinkArchives.cpp:1.30 llvm/lib/Linker/LinkArchives.cpp:1.31 --- llvm/lib/Linker/LinkArchives.cpp:1.30 Mon Nov 8 22:24:59 2004 +++ llvm/lib/Linker/LinkArchives.cpp Fri Nov 12 14:34:32 2004 @@ -1,4 +1,4 @@ -//===- Linker.cpp - Link together LLVM objects and libraries --------------===// +//===- lib/Linker/LinkArchives.cpp - Link LLVM objects and libraries ------===// // // The LLVM Compiler Infrastructure // From reid at x10sys.com Fri Nov 12 14:38:21 2004 From: reid at x10sys.com (Reid Spencer) Date: Fri, 12 Nov 2004 14:38:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/Linker/LinkModules.cpp Message-ID: <200411122038.OAA14091@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: LinkModules.cpp updated: 1.88 -> 1.89 --- Log message: This file originated in lib/VMCore/Linker.cpp but now lives in lib/Linker/LinkModules.cpp --- Diffs of the changes: (+1 -1) Index: llvm/lib/Linker/LinkModules.cpp diff -u llvm/lib/Linker/LinkModules.cpp:1.88 llvm/lib/Linker/LinkModules.cpp:1.89 --- llvm/lib/Linker/LinkModules.cpp:1.88 Fri Nov 5 16:15:36 2004 +++ llvm/lib/Linker/LinkModules.cpp Fri Nov 12 14:37:43 2004 @@ -1,4 +1,4 @@ -//===- Linker.cpp - Module Linker Implementation --------------------------===// +//===- lib/Linker/LinkModules.cpp - Module Linker Implementation ----------===// // // The LLVM Compiler Infrastructure // From reid at x10sys.com Fri Nov 12 14:39:22 2004 From: reid at x10sys.com (Reid Spencer) Date: Fri, 12 Nov 2004 14:39:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/Linker/Makefile Message-ID: <200411122039.OAA14131@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: Makefile added (r1.1) --- Log message: Makefile for lib/Linker --- Diffs of the changes: (+13 -0) Index: llvm/lib/Linker/Makefile diff -c /dev/null llvm/lib/Linker/Makefile:1.1 *** /dev/null Fri Nov 12 14:39:04 2004 --- llvm/lib/Linker/Makefile Fri Nov 12 14:38:45 2004 *************** *** 0 **** --- 1,13 ---- + ##===- lib/Linker/Makefile ---------------------------------*- Makefile -*-===## + # + # The LLVM Compiler Infrastructure + # + # This file was developed by Reid Spencer and is distributed under the + # University of Illinois Open Source License. See LICENSE.TXT for details. + # + ##===----------------------------------------------------------------------===## + LEVEL = ../.. + LIBRARYNAME = LLVMLinker + + include $(LEVEL)/Makefile.common + From lattner at cs.uiuc.edu Fri Nov 12 16:43:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 Nov 2004 16:43:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LowerInvoke.cpp Message-ID: <200411122243.iACMhBYV030705@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LowerInvoke.cpp updated: 1.18 -> 1.19 --- Log message: Simplify handling of constant initializers --- Diffs of the changes: (+13 -36) Index: llvm/lib/Transforms/Scalar/LowerInvoke.cpp diff -u llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.18 llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.19 --- llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.18 Wed Sep 1 17:55:36 2004 +++ llvm/lib/Transforms/Scalar/LowerInvoke.cpp Fri Nov 12 16:42:57 2004 @@ -55,7 +55,6 @@ // Used for both models. Function *WriteFn; Function *AbortFn; - Constant *AbortMessageInit; Value *AbortMessage; unsigned AbortMessageLength; @@ -120,24 +119,18 @@ LongJmpFn = M.getOrInsertFunction("llvm.longjmp", Type::VoidTy, PointerType::get(JmpBufTy), Type::IntTy, 0); - + // The abort message for expensive EH support tells the user that the // program 'unwound' without an 'invoke' instruction. Constant *Msg = ConstantArray::get("ERROR: Exception thrown, but not caught!\n"); AbortMessageLength = Msg->getNumOperands()-1; // don't include \0 - AbortMessageInit = Msg; - - GlobalVariable *MsgGV = M.getGlobalVariable("abort.msg", Msg->getType()); - if (MsgGV && (!MsgGV->hasInitializer() || MsgGV->getInitializer() != Msg)) - MsgGV = 0; - - if (MsgGV) { - std::vector GEPIdx(2, Constant::getNullValue(Type::LongTy)); - AbortMessage = - ConstantExpr::getGetElementPtr(MsgGV, GEPIdx); - } - + + GlobalVariable *MsgGV = new GlobalVariable(Msg->getType(), true, + GlobalValue::InternalLinkage, + Msg, "abortmsg", &M); + std::vector GEPIdx(2, Constant::getNullValue(Type::LongTy)); + AbortMessage = ConstantExpr::getGetElementPtr(MsgGV, GEPIdx); } else { // The abort message for cheap EH support tells the user that EH is not // enabled. @@ -145,17 +138,12 @@ ConstantArray::get("Exception handler needed, but not enabled. Recompile" " program with -enable-correct-eh-support.\n"); AbortMessageLength = Msg->getNumOperands()-1; // don't include \0 - AbortMessageInit = Msg; - - GlobalVariable *MsgGV = M.getGlobalVariable("abort.msg", Msg->getType()); - if (MsgGV && (!MsgGV->hasInitializer() || MsgGV->getInitializer() != Msg)) - MsgGV = 0; - - if (MsgGV) { - std::vector GEPIdx(2, Constant::getNullValue(Type::LongTy)); - AbortMessage = - ConstantExpr::getGetElementPtr(MsgGV, GEPIdx); - } + + GlobalVariable *MsgGV = new GlobalVariable(Msg->getType(), true, + GlobalValue::InternalLinkage, + Msg, "abortmsg", &M); + std::vector GEPIdx(2, Constant::getNullValue(Type::LongTy)); + AbortMessage = ConstantExpr::getGetElementPtr(MsgGV, GEPIdx); } // We need the 'write' and 'abort' functions for both models. @@ -183,17 +171,6 @@ void LowerInvoke::writeAbortMessage(Instruction *IB) { if (WriteFn) { - if (!AbortMessage) { - GlobalVariable *MsgGV = new GlobalVariable(AbortMessageInit->getType(), - true, - GlobalValue::InternalLinkage, - AbortMessageInit, "abort.msg", - WriteFn->getParent()); - std::vector GEPIdx(2, Constant::getNullValue(Type::LongTy)); - AbortMessage = - ConstantExpr::getGetElementPtr(MsgGV, GEPIdx); - } - // These are the arguments we WANT... std::vector Args; Args.push_back(ConstantInt::get(Type::IntTy, 2)); From lattner at cs.uiuc.edu Fri Nov 12 17:50:58 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 Nov 2004 17:50:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CodeExtractor.cpp Message-ID: <200411122350.iACNowZa031580@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CodeExtractor.cpp updated: 1.32 -> 1.33 --- Log message: Fix a bug where the code extractor would get a bit confused handling invoke instructions, setting DefBlock to a block it did not have dom info for. --- Diffs of the changes: (+13 -1) Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp diff -u llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.32 llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.33 --- llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.32 Wed Sep 15 12:06:42 2004 +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp Fri Nov 12 17:50:44 2004 @@ -488,8 +488,20 @@ // For an invoke, the normal destination is the only one that is // dominated by the result of the invocation BasicBlock *DefBlock = cast(outputs[out])->getParent(); - if (InvokeInst *Invoke = dyn_cast(outputs[out])) + if (InvokeInst *Invoke = dyn_cast(outputs[out])) { DefBlock = Invoke->getNormalDest(); + + // Make sure we are looking at the original successor block, not + // at a newly inserted exit block, which won't be in the dominator + // info. + for (std::map::iterator I = + ExitBlockMap.begin(), E = ExitBlockMap.end(); I != E; ++I) + if (DefBlock == I->second) { + DefBlock = I->first; + break; + } + } + if (!DS || DS->dominates(DefBlock, TI->getParent())) if (AggregateArgs) { std::vector Indices; From lattner at cs.uiuc.edu Fri Nov 12 18:06:45 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 Nov 2004 18:06:45 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll Message-ID: <200411130006.iAD06jZI032186@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/CodeExtractor: 2004-11-12-InvokeExtract.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: (+10 -0) Index: llvm/test/Regression/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll diff -c /dev/null llvm/test/Regression/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll:1.1 *** /dev/null Fri Nov 12 18:06:42 2004 --- llvm/test/Regression/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll Fri Nov 12 18:06:32 2004 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as < %s | opt -extract-blocks -disable-output + int %foo() { + br label %EB + EB: + %V = invoke int %foo() to label %Cont unwind label %Unw + Cont: + ret int %V + Unw: + unwind + } From lattner at cs.uiuc.edu Fri Nov 12 18:06:57 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 Nov 2004 18:06:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CodeExtractor.cpp Message-ID: <200411130006.iAD06vHA032194@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CodeExtractor.cpp updated: 1.33 -> 1.34 --- Log message: Fix: CodeExtractor/2004-11-12-InvokeExtract.ll --- Diffs of the changes: (+16 -2) Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp diff -u llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.33 llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.34 --- llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.33 Fri Nov 12 17:50:44 2004 +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp Fri Nov 12 18:06:45 2004 @@ -488,6 +488,9 @@ // For an invoke, the normal destination is the only one that is // dominated by the result of the invocation BasicBlock *DefBlock = cast(outputs[out])->getParent(); + + bool DominatesDef = true; + if (InvokeInst *Invoke = dyn_cast(outputs[out])) { DefBlock = Invoke->getNormalDest(); @@ -500,9 +503,18 @@ DefBlock = I->first; break; } + + // In the extract block case, if the block we are extracting ends + // with an invoke instruction, make sure that we don't emit a + // store of the invoke value for the unwind block. + if (!DS && DefBlock != OldTarget) + DominatesDef = false; } - if (!DS || DS->dominates(DefBlock, TI->getParent())) + if (DS) + DominatesDef = DS->dominates(DefBlock, OldTarget); + + if (DominatesDef) { if (AggregateArgs) { std::vector Indices; Indices.push_back(Constant::getNullValue(Type::UIntTy)); @@ -512,8 +524,10 @@ "gep_" + outputs[out]->getName(), NTRet); new StoreInst(outputs[out], GEP, NTRet); - } else + } else { new StoreInst(outputs[out], OAI, NTRet); + } + } // Advance output iterator even if we don't emit a store if (!AggregateArgs) ++OAI; } From lattner at cs.uiuc.edu Sat Nov 13 13:07:47 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 13:07:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LowerInvoke.cpp Message-ID: <200411131907.iADJ7lXp018653@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LowerInvoke.cpp updated: 1.19 -> 1.20 --- Log message: Lazily create the abort message, so only translation units that use unwind will actually get it. --- Diffs of the changes: (+31 -22) Index: llvm/lib/Transforms/Scalar/LowerInvoke.cpp diff -u llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.19 llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.20 --- llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.19 Fri Nov 12 16:42:57 2004 +++ llvm/lib/Transforms/Scalar/LowerInvoke.cpp Sat Nov 13 13:07:32 2004 @@ -66,6 +66,7 @@ bool doInitialization(Module &M); bool runOnFunction(Function &F); private: + void createAbortMessage(); void writeAbortMessage(Instruction *IB); bool insertCheapEHSupport(Function &F); bool insertExpensiveEHSupport(Function &F); @@ -119,7 +120,34 @@ LongJmpFn = M.getOrInsertFunction("llvm.longjmp", Type::VoidTy, PointerType::get(JmpBufTy), Type::IntTy, 0); + } + + // We need the 'write' and 'abort' functions for both models. + AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, 0); + // Unfortunately, 'write' can end up being prototyped in several different + // ways. If the user defines a three (or more) operand function named 'write' + // we will use their prototype. We _do not_ want to insert another instance + // of a write prototype, because we don't know that the funcresolve pass will + // run after us. If there is a definition of a write function, but it's not + // suitable for our uses, we just don't emit write calls. If there is no + // write prototype at all, we just add one. + if (Function *WF = M.getNamedFunction("write")) { + if (WF->getFunctionType()->getNumParams() > 3 || + WF->getFunctionType()->isVarArg()) + WriteFn = WF; + else + WriteFn = 0; + } else { + WriteFn = M.getOrInsertFunction("write", Type::VoidTy, Type::IntTy, + VoidPtrTy, Type::IntTy, 0); + } + return true; +} + +void LowerInvoke::createAbortMessage() { + Module &M = *WriteFn->getParent(); + if (ExpensiveEHSupport) { // The abort message for expensive EH support tells the user that the // program 'unwound' without an 'invoke' instruction. Constant *Msg = @@ -145,32 +173,13 @@ std::vector GEPIdx(2, Constant::getNullValue(Type::LongTy)); AbortMessage = ConstantExpr::getGetElementPtr(MsgGV, GEPIdx); } - - // We need the 'write' and 'abort' functions for both models. - AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, 0); - - // Unfortunately, 'write' can end up being prototyped in several different - // ways. If the user defines a three (or more) operand function named 'write' - // we will use their prototype. We _do not_ want to insert another instance - // of a write prototype, because we don't know that the funcresolve pass will - // run after us. If there is a definition of a write function, but it's not - // suitable for our uses, we just don't emit write calls. If there is no - // write prototype at all, we just add one. - if (Function *WF = M.getNamedFunction("write")) { - if (WF->getFunctionType()->getNumParams() > 3 || - WF->getFunctionType()->isVarArg()) - WriteFn = WF; - else - WriteFn = 0; - } else { - WriteFn = M.getOrInsertFunction("write", Type::VoidTy, Type::IntTy, - VoidPtrTy, Type::IntTy, 0); - } - return true; } + void LowerInvoke::writeAbortMessage(Instruction *IB) { if (WriteFn) { + if (AbortMessage == 0) createAbortMessage(); + // These are the arguments we WANT... std::vector Args; Args.push_back(ConstantInt::get(Type::IntTy, 2)); From lattner at cs.uiuc.edu Sat Nov 13 13:31:54 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 13:31:54 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200411131931.iADJVs8A019525@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.279 -> 1.280 --- Log message: Fold: (X + (X << C2)) --> X * ((1 << C2) + 1) ((X << C2) + X) --> X * ((1 << C2) + 1) This means that we now canonicalize "Y+Y+Y" into: %tmp.2 = mul long %Y, 3 ; [#uses=1] instead of: %tmp.10 = shl long %Y, ubyte 1 ; [#uses=1] %tmp.6 = add long %Y, %tmp.10 ; [#uses=1] --- Diffs of the changes: (+13 -0) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.279 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.280 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.279 Thu Nov 4 22:45:43 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sat Nov 13 13:31:40 2004 @@ -618,6 +618,19 @@ if (match(RHS, m_And(m_Value(), m_ConstantInt(C2)))) if (Instruction *R = AssociativeOpt(I, AddMaskingAnd(C2))) return R; + // (X + (X << C2)) --> X * ((1 << C2) + 1) + // ((X << C2) + X) --> X * ((1 << C2) + 1) + Value *Tmp; + if ((RHS->hasOneUse() && match(RHS, m_Shl(m_Value(Tmp), + m_ConstantInt(C2))) && LHS == Tmp)|| + (LHS->hasOneUse() && match(LHS, m_Shl(m_Value(Tmp), + m_ConstantInt(C2))) && RHS == Tmp)){ + ConstantInt *One = ConstantInt::get(LHS->getType(), 1); + Constant *NewRHS = + ConstantExpr::getAdd(ConstantExpr::getShl(One, C2), One); + return BinaryOperator::createMul(Tmp, NewRHS); + } + if (ConstantInt *CRHS = dyn_cast(RHS)) { Value *X; if (match(LHS, m_Not(m_Value(X)))) { // ~X + C --> (C-1) - X From lattner at cs.uiuc.edu Sat Nov 13 13:32:59 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 13:32:59 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/PatternMatch.h Message-ID: <200411131932.iADJWxA3019538@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: PatternMatch.h updated: 1.3 -> 1.4 --- Log message: Add support for shifts --- Diffs of the changes: (+12 -0) Index: llvm/include/llvm/Support/PatternMatch.h diff -u llvm/include/llvm/Support/PatternMatch.h:1.3 llvm/include/llvm/Support/PatternMatch.h:1.4 --- llvm/include/llvm/Support/PatternMatch.h:1.3 Tue Aug 3 23:45:29 2004 +++ llvm/include/llvm/Support/PatternMatch.h Sat Nov 13 13:32:45 2004 @@ -138,6 +138,18 @@ return BinaryOp_match(L, R); } +template +inline BinaryOp_match m_Shl(const LHS &L, + const RHS &R) { + return BinaryOp_match(L, R); +} + +template +inline BinaryOp_match m_Shr(const LHS &L, + const RHS &R) { + return BinaryOp_match(L, R); +} + //===----------------------------------------------------------------------===// // Matchers for binary classes // From lattner at cs.uiuc.edu Sat Nov 13 13:45:51 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 13:45:51 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/add.ll Message-ID: <200411131945.iADJjpgw020147@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: add.ll updated: 1.23 -> 1.24 --- Log message: New testcase --- Diffs of the changes: (+8 -0) Index: llvm/test/Regression/Transforms/InstCombine/add.ll diff -u llvm/test/Regression/Transforms/InstCombine/add.ll:1.23 llvm/test/Regression/Transforms/InstCombine/add.ll:1.24 --- llvm/test/Regression/Transforms/InstCombine/add.ll:1.23 Thu Oct 7 22:41:59 2004 +++ llvm/test/Regression/Transforms/InstCombine/add.ll Sat Nov 13 13:45:37 2004 @@ -169,3 +169,11 @@ %D = sub int %C, 2 ret int %D ;; A << 1 } + +long %test25(long %Y) { + %tmp.4 = shl long %Y, ubyte 2 + %tmp.12 = shl long %Y, ubyte 2 + %tmp.8 = add long %tmp.4, %tmp.12 ;; Y << 3 + ret long %tmp.8 +} + From lattner at cs.uiuc.edu Sat Nov 13 13:49:51 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 13:49:51 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/sub.ll Message-ID: <200411131949.iADJnpIe020444@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: sub.ll updated: 1.19 -> 1.20 --- Log message: New testcase --- Diffs of the changes: (+8 -0) Index: llvm/test/Regression/Transforms/InstCombine/sub.ll diff -u llvm/test/Regression/Transforms/InstCombine/sub.ll:1.19 llvm/test/Regression/Transforms/InstCombine/sub.ll:1.20 --- llvm/test/Regression/Transforms/InstCombine/sub.ll:1.19 Fri Oct 8 21:50:01 2004 +++ llvm/test/Regression/Transforms/InstCombine/sub.ll Sat Nov 13 13:49:39 2004 @@ -111,3 +111,11 @@ %C = div int %B, 1234 ret int %C } + +long %test18(long %Y) { + %tmp.4 = shl long %Y, ubyte 2 + %tmp.12 = shl long %Y, ubyte 2 + %tmp.8 = sub long %tmp.4, %tmp.12 ;; 0 + ret long %tmp.8 +} + From lattner at cs.uiuc.edu Sat Nov 13 13:50:24 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 13:50:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200411131950.iADJoO6A020457@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.280 -> 1.281 --- Log message: Simplify handling of shifts to be the same as we do for adds. Add support for (X * C1) + (X * C2) (where * can be mul or shl), allowing us to fold: Y+Y+Y+Y+Y+Y+Y+Y into %tmp.8 = shl long %Y, ubyte 3 ; [#uses=1] instead of %tmp.4 = shl long %Y, ubyte 2 ; [#uses=1] %tmp.12 = shl long %Y, ubyte 2 ; [#uses=1] %tmp.8 = add long %tmp.4, %tmp.12 ; [#uses=1] This implements add.ll:test25 Also add support for (X*C1)-(X*C2) -> X*(C1-C2), implementing sub.ll:test18 --- Diffs of the changes: (+40 -45) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.280 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.281 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.280 Sat Nov 13 13:31:40 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sat Nov 13 13:50:12 2004 @@ -317,14 +317,23 @@ // dyn_castFoldableMul - If this value is a multiply that can be folded into // other computations (because it has a constant operand), return the -// non-constant operand of the multiply. +// non-constant operand of the multiply, and set CST to point to the multiplier. +// Otherwise, return null. // -static inline Value *dyn_castFoldableMul(Value *V) { +static inline Value *dyn_castFoldableMul(Value *V, ConstantInt *&CST) { if (V->hasOneUse() && V->getType()->isInteger()) - if (Instruction *I = dyn_cast(V)) + if (Instruction *I = dyn_cast(V)) { if (I->getOpcode() == Instruction::Mul) - if (isa(I->getOperand(1))) + if (CST = dyn_cast(I->getOperand(1))) + return I->getOperand(0); + if (I->getOpcode() == Instruction::Shl) + if (CST = dyn_cast(I->getOperand(1))) { + // The multiplier is really 1 << CST. + Constant *One = ConstantInt::get(V->getType(), 1); + CST = cast(ConstantExpr::getShl(One, CST)); return I->getOperand(0); + } + } return 0; } @@ -595,42 +604,26 @@ if (Value *V = dyn_castNegVal(RHS)) return BinaryOperator::createSub(LHS, V); - // X*C + X --> X * (C+1) - if (dyn_castFoldableMul(LHS) == RHS) { - Constant *CP1 = - ConstantExpr::getAdd( - cast(cast(LHS)->getOperand(1)), - ConstantInt::get(I.getType(), 1)); - return BinaryOperator::createMul(RHS, CP1); + ConstantInt *C2; + if (Value *X = dyn_castFoldableMul(LHS, C2)) { + if (X == RHS) // X*C + X --> X * (C+1) + return BinaryOperator::createMul(RHS, AddOne(C2)); + + // X*C1 + X*C2 --> X * (C1+C2) + ConstantInt *C1; + if (X == dyn_castFoldableMul(RHS, C1)) + return BinaryOperator::createMul(X, ConstantExpr::getAdd(C1, C2)); } // X + X*C --> X * (C+1) - if (dyn_castFoldableMul(RHS) == LHS) { - Constant *CP1 = - ConstantExpr::getAdd( - cast(cast(RHS)->getOperand(1)), - ConstantInt::get(I.getType(), 1)); - return BinaryOperator::createMul(LHS, CP1); - } + if (dyn_castFoldableMul(RHS, C2) == LHS) + return BinaryOperator::createMul(LHS, AddOne(C2)); + // (A & C1)+(B & C2) --> (A & C1)|(B & C2) iff C1&C2 == 0 - ConstantInt *C2; if (match(RHS, m_And(m_Value(), m_ConstantInt(C2)))) if (Instruction *R = AssociativeOpt(I, AddMaskingAnd(C2))) return R; - // (X + (X << C2)) --> X * ((1 << C2) + 1) - // ((X << C2) + X) --> X * ((1 << C2) + 1) - Value *Tmp; - if ((RHS->hasOneUse() && match(RHS, m_Shl(m_Value(Tmp), - m_ConstantInt(C2))) && LHS == Tmp)|| - (LHS->hasOneUse() && match(LHS, m_Shl(m_Value(Tmp), - m_ConstantInt(C2))) && RHS == Tmp)){ - ConstantInt *One = ConstantInt::get(LHS->getType(), 1); - Constant *NewRHS = - ConstantExpr::getAdd(ConstantExpr::getShl(One, C2), One); - return BinaryOperator::createMul(Tmp, NewRHS); - } - if (ConstantInt *CRHS = dyn_cast(RHS)) { Value *X; if (match(LHS, m_Not(m_Value(X)))) { // ~X + C --> (C-1) - X @@ -800,24 +793,26 @@ ConstantExpr::getNeg(DivRHS)); // X - X*C --> X * (1-C) - if (dyn_castFoldableMul(Op1I) == Op0) { - Constant *CP1 = - ConstantExpr::getSub(ConstantInt::get(I.getType(), 1), - cast(cast(Op1)->getOperand(1))); - assert(CP1 && "Couldn't constant fold 1-C?"); + ConstantInt *C2; + if (dyn_castFoldableMul(Op1I, C2) == Op0) { + Constant *CP1 = + ConstantExpr::getSub(ConstantInt::get(I.getType(), 1), C2); return BinaryOperator::createMul(Op0, CP1); } } - // X*C - X --> X * (C-1) - if (dyn_castFoldableMul(Op0) == Op1) { - Constant *CP1 = - ConstantExpr::getSub(cast(cast(Op0)->getOperand(1)), - ConstantInt::get(I.getType(), 1)); - assert(CP1 && "Couldn't constant fold C - 1?"); - return BinaryOperator::createMul(Op1, CP1); - } + + ConstantInt *C1; + if (Value *X = dyn_castFoldableMul(Op0, C1)) { + if (X == Op1) { // X*C - X --> X * (C-1) + Constant *CP1 = ConstantExpr::getSub(C1, ConstantInt::get(I.getType(),1)); + return BinaryOperator::createMul(Op1, CP1); + } + ConstantInt *C2; // X*C1 - X*C2 -> X * (C1-C2) + if (X == dyn_castFoldableMul(Op1, C2)) + return BinaryOperator::createMul(Op1, ConstantExpr::getSub(C1, C2)); + } return 0; } From lattner at cs.uiuc.edu Sat Nov 13 14:04:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 14:04:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelSimple.cpp Message-ID: <200411132004.iADK41eH021598@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelSimple.cpp updated: 1.291 -> 1.292 --- Log message: Compile: long long X3_2(long long Y) { return Y+Y; } int X(int Y) { return Y+Y; } into: X3_2: movl 4(%esp), %eax movl 8(%esp), %edx addl %eax, %eax adcl %edx, %edx ret X: movl 4(%esp), %eax addl %eax, %eax ret instead of: X3_2: movl 4(%esp), %eax movl 8(%esp), %edx shldl $1, %eax, %edx shll $1, %eax ret X: movl 4(%esp), %eax shll $1, %eax ret --- Diffs of the changes: (+14 -4) Index: llvm/lib/Target/X86/X86ISelSimple.cpp diff -u llvm/lib/Target/X86/X86ISelSimple.cpp:1.291 llvm/lib/Target/X86/X86ISelSimple.cpp:1.292 --- llvm/lib/Target/X86/X86ISelSimple.cpp:1.291 Sun Oct 17 12:40:50 2004 +++ llvm/lib/Target/X86/X86ISelSimple.cpp Sat Nov 13 14:03:48 2004 @@ -2925,7 +2925,12 @@ // if (ConstantUInt *CUI = dyn_cast(ShiftAmount)) { unsigned Amount = CUI->getValue(); - if (Amount < 32) { + if (Amount == 1) { // X << 1 == X+X + BuildMI(*MBB, IP, X86::ADD32rr, 2, + DestReg).addReg(SrcReg).addReg(SrcReg); + BuildMI(*MBB, IP, X86::ADC32rr, 2, + DestReg+1).addReg(SrcReg+1).addReg(SrcReg+1); + } else if (Amount < 32) { const unsigned *Opc = ConstantOperand[isLeftShift*2+isSigned]; if (isLeftShift) { BuildMI(*MBB, IP, Opc[3], 3, @@ -3018,9 +3023,14 @@ // The shift amount is constant, guaranteed to be a ubyte. Get its value. assert(CUI->getType() == Type::UByteTy && "Shift amount not a ubyte?"); - const unsigned *Opc = ConstantOperand[isLeftShift*2+isSigned]; - BuildMI(*MBB, IP, Opc[Class], 2, - DestReg).addReg(SrcReg).addImm(CUI->getValue()); + if (CUI->getValue() == 1 && isLeftShift) { // X << 1 -> X+X + static const int AddOpC[] = { X86::ADD8rr, X86::ADD16rr, X86::ADD32rr }; + BuildMI(*MBB, IP, AddOpC[Class], 2,DestReg).addReg(SrcReg).addReg(SrcReg); + } else { + const unsigned *Opc = ConstantOperand[isLeftShift*2+isSigned]; + BuildMI(*MBB, IP, Opc[Class], 2, + DestReg).addReg(SrcReg).addImm(CUI->getValue()); + } } else { // The shift amount is non-constant. unsigned ShiftAmountReg = getReg (ShiftAmount, MBB, IP); BuildMI(*MBB, IP, X86::MOV8rr, 1, X86::CL).addReg(ShiftAmountReg); From lattner at cs.uiuc.edu Sat Nov 13 14:04:50 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 14:04:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelSimple.cpp Message-ID: <200411132004.iADK4oVf021610@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelSimple.cpp updated: 1.292 -> 1.293 --- Log message: Add missing check --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/X86/X86ISelSimple.cpp diff -u llvm/lib/Target/X86/X86ISelSimple.cpp:1.292 llvm/lib/Target/X86/X86ISelSimple.cpp:1.293 --- llvm/lib/Target/X86/X86ISelSimple.cpp:1.292 Sat Nov 13 14:03:48 2004 +++ llvm/lib/Target/X86/X86ISelSimple.cpp Sat Nov 13 14:04:38 2004 @@ -2925,7 +2925,7 @@ // if (ConstantUInt *CUI = dyn_cast(ShiftAmount)) { unsigned Amount = CUI->getValue(); - if (Amount == 1) { // X << 1 == X+X + if (Amount == 1 && isLeftShift) { // X << 1 == X+X BuildMI(*MBB, IP, X86::ADD32rr, 2, DestReg).addReg(SrcReg).addReg(SrcReg); BuildMI(*MBB, IP, X86::ADC32rr, 2, From lattner at cs.uiuc.edu Sat Nov 13 14:49:09 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 14:49:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelSimple.cpp Message-ID: <200411132049.iADKn92k022027@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelSimple.cpp updated: 1.293 -> 1.294 --- Log message: shld is a very high latency operation. Instead of emitting it for shifts of two or three, open code the equivalent operation which is faster on athlon and P4 (by a substantial margin). For example, instead of compiling this: long long X2(long long Y) { return Y << 2; } to: X3_2: movl 4(%esp), %eax movl 8(%esp), %edx shldl $2, %eax, %edx shll $2, %eax ret Compile it to: X2: movl 4(%esp), %eax movl 8(%esp), %ecx movl %eax, %edx shrl $30, %edx leal (%edx,%ecx,4), %edx shll $2, %eax ret Likewise, for << 3, compile to: X3: movl 4(%esp), %eax movl 8(%esp), %ecx movl %eax, %edx shrl $29, %edx leal (%edx,%ecx,8), %edx shll $3, %eax ret This matches icc, except that icc open codes the shifts as adds on the P4. --- Diffs of the changes: (+52 -14) Index: llvm/lib/Target/X86/X86ISelSimple.cpp diff -u llvm/lib/Target/X86/X86ISelSimple.cpp:1.293 llvm/lib/Target/X86/X86ISelSimple.cpp:1.294 --- llvm/lib/Target/X86/X86ISelSimple.cpp:1.293 Sat Nov 13 14:04:38 2004 +++ llvm/lib/Target/X86/X86ISelSimple.cpp Sat Nov 13 14:48:57 2004 @@ -313,6 +313,13 @@ MachineBasicBlock::iterator IP, Value *Op, Value *ShiftAmount, bool isLeftShift, const Type *ResultTy, unsigned DestReg); + + // Emit code for a 'SHLD DestReg, Op0, Op1, Amt' operation, where Amt is a + // constant. + void doSHLDConst(MachineBasicBlock *MBB, + MachineBasicBlock::iterator MBBI, + unsigned DestReg, unsigned Op0Reg, unsigned Op1Reg, + unsigned Op1Val); /// emitSelectOperation - Common code shared between visitSelectInst and the /// constant expression support. @@ -2893,6 +2900,41 @@ getReg (I)); } +/// Emit code for a 'SHLD DestReg, Op0, Op1, Amt' operation, where Amt is a +/// constant. +void X86ISel::doSHLDConst(MachineBasicBlock *MBB, + MachineBasicBlock::iterator IP, + unsigned DestReg, unsigned Op0Reg, unsigned Op1Reg, + unsigned Amt) { + // SHLD is a very inefficient operation on every processor, try to do + // somethign simpler for common values of 'Amt'. + if (Amt == 0) { + BuildMI(*MBB, IP, X86::MOV32rr, 1, DestReg).addReg(Op0Reg); + } else if (Amt == 1) { + unsigned Tmp = makeAnotherReg(Type::UIntTy); + BuildMI(*MBB, IP, X86::ADD32rr, 2, Tmp).addReg(Op1Reg).addReg(Op1Reg); + BuildMI(*MBB, IP, X86::ADC32rr, 2, DestReg).addReg(Op0Reg).addReg(Op0Reg); + } else if (Amt == 2 || Amt == 3) { + // On the P4 and Athlon it is cheaper to replace shld ..., 2|3 with a + // shift/lea pair. NOTE: This should not be done on the P6 family! + unsigned Tmp = makeAnotherReg(Type::UIntTy); + BuildMI(*MBB, IP, X86::SHR32ri, 2, Tmp).addReg(Op1Reg).addImm(32-Amt); + X86AddressMode AM; + AM.BaseType = X86AddressMode::RegBase; + AM.Base.Reg = Tmp; + AM.Scale = 1 << Amt; + AM.IndexReg = Op0Reg; + AM.Disp = 0; + addFullAddress(BuildMI(*MBB, IP, X86::LEA32r, 4, DestReg), AM); + } else { + // NOTE: It is always cheaper on the P4 to emit SHLD as two shifts and an OR + // than it is to emit a real SHLD. + + BuildMI(*MBB, IP, X86::SHLD32rri8, 3, + DestReg).addReg(Op0Reg).addReg(Op1Reg).addImm(Amt); + } +} + /// emitShiftOperation - Common code shared between visitShiftInst and /// constant expression support. void X86ISel::emitShiftOperation(MachineBasicBlock *MBB, @@ -2904,25 +2946,22 @@ bool isSigned = ResultTy->isSigned (); unsigned Class = getClass (ResultTy); - static const unsigned ConstantOperand[][4] = { - { X86::SHR8ri, X86::SHR16ri, X86::SHR32ri, X86::SHRD32rri8 }, // SHR - { X86::SAR8ri, X86::SAR16ri, X86::SAR32ri, X86::SHRD32rri8 }, // SAR - { X86::SHL8ri, X86::SHL16ri, X86::SHL32ri, X86::SHLD32rri8 }, // SHL - { X86::SHL8ri, X86::SHL16ri, X86::SHL32ri, X86::SHLD32rri8 }, // SAL = SHL + static const unsigned ConstantOperand[][3] = { + { X86::SHR8ri, X86::SHR16ri, X86::SHR32ri }, // SHR + { X86::SAR8ri, X86::SAR16ri, X86::SAR32ri }, // SAR + { X86::SHL8ri, X86::SHL16ri, X86::SHL32ri }, // SHL + { X86::SHL8ri, X86::SHL16ri, X86::SHL32ri }, // SAL = SHL }; - static const unsigned NonConstantOperand[][4] = { + static const unsigned NonConstantOperand[][3] = { { X86::SHR8rCL, X86::SHR16rCL, X86::SHR32rCL }, // SHR { X86::SAR8rCL, X86::SAR16rCL, X86::SAR32rCL }, // SAR { X86::SHL8rCL, X86::SHL16rCL, X86::SHL32rCL }, // SHL { X86::SHL8rCL, X86::SHL16rCL, X86::SHL32rCL }, // SAL = SHL }; - // Longs, as usual, are handled specially... + // Longs, as usual, are handled specially. if (Class == cLong) { - // If we have a constant shift, we can generate much more efficient code - // than otherwise... - // if (ConstantUInt *CUI = dyn_cast(ShiftAmount)) { unsigned Amount = CUI->getValue(); if (Amount == 1 && isLeftShift) { // X << 1 == X+X @@ -2933,12 +2972,11 @@ } else if (Amount < 32) { const unsigned *Opc = ConstantOperand[isLeftShift*2+isSigned]; if (isLeftShift) { - BuildMI(*MBB, IP, Opc[3], 3, - DestReg+1).addReg(SrcReg+1).addReg(SrcReg).addImm(Amount); + doSHLDConst(MBB, IP, DestReg+1, SrcReg+1, SrcReg, Amount); BuildMI(*MBB, IP, Opc[2], 2, DestReg).addReg(SrcReg).addImm(Amount); } else { - BuildMI(*MBB, IP, Opc[3], 3, - DestReg).addReg(SrcReg ).addReg(SrcReg+1).addImm(Amount); + BuildMI(*MBB, IP, X86::SHRD32rri8, 3, + DestReg).addReg(SrcReg ).addReg(SrcReg+1).addImm(Amount); BuildMI(*MBB, IP, Opc[2],2,DestReg+1).addReg(SrcReg+1).addImm(Amount); } } else { // Shifting more than 32 bits From tbrethou at cs.uiuc.edu Sat Nov 13 15:03:33 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 15:03:33 -0600 Subject: [llvm-commits] CVS: llvm/test/Scripts/prcontext.tcl Message-ID: <200411132103.PAA19350@zion.cs.uiuc.edu> Changes in directory llvm/test/Scripts: prcontext.tcl added (r1.1) --- Log message: Rewrote prcontext.py in tcl. --- Diffs of the changes: (+36 -0) Index: llvm/test/Scripts/prcontext.tcl diff -c /dev/null llvm/test/Scripts/prcontext.tcl:1.1 *** /dev/null Sat Nov 13 15:03:32 2004 --- llvm/test/Scripts/prcontext.tcl Sat Nov 13 15:03:22 2004 *************** *** 0 **** --- 1,36 ---- + #!/usr/bin/tclsh + # + # Usage: + # prcontext <# lines of context> + # (for platforms that don't have grep -C) + + + # + # Get the arguments + # + set pattern [lindex $argv 0] + set num [lindex $argv 1] + + + # + # Get all of the lines in the file. + # + set lines [split [read stdin] \n] + + set index 0 + foreach line $lines { + if { [regexp $pattern $line match matchline] } { + if { [ expr [expr $index - $num] < 0 ] } { + set bottom 0 + } else { + set bottom [expr $index - $num] + } + set endLineNum [ expr [expr $index + $num] + 1] + while {$bottom < $endLineNum} { + set output [lindex $lines $bottom] + puts $output + set bottom [expr $bottom + 1] + } + } + set index [expr $index + 1] + } \ No newline at end of file From lattner at cs.uiuc.edu Sat Nov 13 16:21:30 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 16:21:30 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/CBackend/2004-11-13-FunctionPointerCast.llx Message-ID: <200411132221.iADMLUBv026886@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/CBackend: 2004-11-13-FunctionPointerCast.llx added (r1.1) --- Log message: New testcase --- Diffs of the changes: (+17 -0) Index: llvm/test/Regression/CodeGen/CBackend/2004-11-13-FunctionPointerCast.llx diff -c /dev/null llvm/test/Regression/CodeGen/CBackend/2004-11-13-FunctionPointerCast.llx:1.1 *** /dev/null Sat Nov 13 16:21:26 2004 --- llvm/test/Regression/CodeGen/CBackend/2004-11-13-FunctionPointerCast.llx Sat Nov 13 16:21:15 2004 *************** *** 0 **** --- 1,17 ---- + ; The CBE should not emit code that casts the function pointer. This causes + ; GCC to get testy and insert trap instructions instead of doing the right + ; thing. :( + ; RUN: llvm-as < %s | llc -march=c | not grep 'external)' + + implementation + + declare void %external(sbyte*) + + int %test(int *%X) { + %RV = call int (int*)* cast (void(sbyte*)* %external to int(int*)*)(int* %X) + ret int %RV + } + + + + From lattner at cs.uiuc.edu Sat Nov 13 16:22:08 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 16:22:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200411132222.iADMM8ro026977@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.207 -> 1.208 --- Log message: Hack around stupidity in GCC, fixing Burg with the CBE and CBackend/2004-11-13-FunctionPointerCast.llx --- Diffs of the changes: (+56 -9) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.207 llvm/lib/Target/CBackend/Writer.cpp:1.208 --- llvm/lib/Target/CBackend/Writer.cpp:1.207 Mon Oct 25 13:41:50 2004 +++ llvm/lib/Target/CBackend/Writer.cpp Sat Nov 13 16:21:56 2004 @@ -182,7 +182,6 @@ void visitCastInst (CastInst &I); void visitSelectInst(SelectInst &I); void visitCallInst (CallInst &I); - void visitCallSite (CallSite CS); void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); } void visitMallocInst(MallocInst &I); @@ -1466,23 +1465,71 @@ return; } } - visitCallSite(&I); -} -void CWriter::visitCallSite(CallSite CS) { - const PointerType *PTy = cast(CS.getCalledValue()->getType()); + Value *Callee = I.getCalledValue(); + + // GCC is really a PITA. It does not permit codegening casts of functions to + // function pointers if they are in a call (it generates a trap instruction + // instead!). We work around this by inserting a cast to void* in between the + // function and the function pointer cast. Unfortunately, we can't just form + // the constant expression here, because the folder will immediately nuke it. + // + // Note finally, that this is completely unsafe. ANSI C does not guarantee + // that void* and function pointers have the same size. :( To deal with this + // in the common case, we handle casts where the number of arguments passed + // match exactly. + // + bool WroteCallee = false; + if (ConstantExpr *CE = dyn_cast(Callee)) + if (CE->getOpcode() == Instruction::Cast) + if (Function *RF = dyn_cast(CE->getOperand(0))) { + const FunctionType *RFTy = RF->getFunctionType(); + if (RFTy->getNumParams() == I.getNumOperands()-1) { + // If the call site expects a value, and the actual callee doesn't + // provide one, return 0. + if (I.getType() != Type::VoidTy && + RFTy->getReturnType() == Type::VoidTy) + Out << "0 /*actual callee doesn't return value*/; "; + Callee = RF; + } else { + // Ok, just cast the pointer type. + Out << "(("; + printType(Out, CE->getType()); + Out << ")(void*)"; + printConstant(RF); + Out << ")"; + WroteCallee = true; + } + } + + const PointerType *PTy = cast(Callee->getType()); const FunctionType *FTy = cast(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); - writeOperand(CS.getCalledValue()); + if (!WroteCallee) writeOperand(Callee); Out << "("; - if (CS.arg_begin() != CS.arg_end()) { - CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); + unsigned NumDeclaredParams = FTy->getNumParams(); + + if (I.getNumOperands() != 1) { + CallSite::arg_iterator AI = I.op_begin()+1, AE = I.op_end(); + if (NumDeclaredParams && (*AI)->getType() != FTy->getParamType(0)) { + Out << "("; + printType(Out, FTy->getParamType(0)); + Out << ")"; + } + writeOperand(*AI); - for (++AI; AI != AE; ++AI) { + unsigned ArgNo; + for (ArgNo = 1, ++AI; AI != AE; ++AI, ++ArgNo) { Out << ", "; + if (ArgNo < NumDeclaredParams && + (*AI)->getType() != FTy->getParamType(ArgNo)) { + Out << "("; + printType(Out, FTy->getParamType(ArgNo)); + Out << ")"; + } writeOperand(*AI); } } From tbrethou at cs.uiuc.edu Sat Nov 13 16:56:02 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 16:56:02 -0600 Subject: [llvm-commits] CVS: llvm/test/lib/llvm-dg.exp Message-ID: <200411132256.QAA20137@zion.cs.uiuc.edu> Changes in directory llvm/test/lib: llvm-dg.exp updated: 1.5 -> 1.6 --- Log message: Changed to use tcl script. --- Diffs of the changes: (+2 -2) Index: llvm/test/lib/llvm-dg.exp diff -u llvm/test/lib/llvm-dg.exp:1.5 llvm/test/lib/llvm-dg.exp:1.6 --- llvm/test/lib/llvm-dg.exp:1.5 Sun Nov 7 21:26:59 2004 +++ llvm/test/lib/llvm-dg.exp Sat Nov 13 16:55:51 2004 @@ -52,8 +52,8 @@ #replace %llvmgxx with actual path to llvmg++ regsub -all {%llvmgxx} $new_runline $llvmgxx new_runline - #replace %prcontext with actual path to llvmg++ (Goes away when we remove qmtest) - regsub -all {%prcontext} $new_runline "$prcontext" new_runline + #replace %prcontext with prcontext.tcl (Goes away when we remove qmtest) + regsub -all {%prcontext} $new_runline "prcontext.tcl" new_runline puts $scriptFileId $new_runline } elseif {[regexp {XFAIL:[ *](.+)} $line match targets]} { From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:08 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:08 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/GCSE/dg.exp Message-ID: <200411132301.RAA20706@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/GCSE: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/GCSE/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/GCSE/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/GCSE/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/GlobalsModRef/dg.exp Message-ID: <200411132301.RAA20780@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/GlobalsModRef: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Analysis/GlobalsModRef/dg.exp diff -c /dev/null llvm/test/Regression/Analysis/GlobalsModRef/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/Analysis/GlobalsModRef/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LowerSwitch/dg.exp Message-ID: <200411132301.RAA20714@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LowerSwitch: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/LowerSwitch/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/LowerSwitch/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/LowerSwitch/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:08 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:08 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ScalarRepl/dg.exp Message-ID: <200411132301.RAA20701@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ScalarRepl: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/ScalarRepl/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/ScalarRepl/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:56 2004 --- llvm/test/Regression/Transforms/ScalarRepl/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:08 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:08 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/dg.exp Message-ID: <200411132301.RAA20704@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/InstCombine/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/InstCombine/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:08 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:08 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/PruneEH/dg.exp Message-ID: <200411132301.RAA20707@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/PruneEH: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/PruneEH/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/PruneEH/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:56 2004 --- llvm/test/Regression/Transforms/PruneEH/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:59 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:59 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/dg.exp Message-ID: <200411132301.RAA20941@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression: dg.exp (r1.4) removed --- Log message: Removing because there are no tests in this directory to run. Each subdirectory has a dg.exp file to handle tests in it. --- Diffs of the changes: (+0 -0) From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:08 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:08 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/GlobalOpt/dg.exp Message-ID: <200411132301.RAA20705@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/GlobalOpt: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/GlobalOpt/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/GlobalOpt/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/GlobalOpt/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Other/dg.exp Message-ID: <200411132301.RAA20708@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Other: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Other/dg.exp diff -c /dev/null llvm/test/Regression/Other/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Other/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/TailCallElim/dg.exp Message-ID: <200411132301.RAA20700@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/TailCallElim: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/TailCallElim/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/TailCallElim/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/TailCallElim/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LoopUnswitch/dg.exp Message-ID: <200411132301.RAA20712@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LoopUnswitch: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/LoopUnswitch/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/LoopUnswitch/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/LoopUnswitch/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/dg.exp Message-ID: <200411132301.RAA20715@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/TableGen/dg.exp diff -c /dev/null llvm/test/Regression/TableGen/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/TableGen/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LoopSimplify/dg.exp Message-ID: <200411132301.RAA20723@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LoopSimplify: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/LoopSimplify/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/LoopSimplify/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/LoopSimplify/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/DeadStoreElimination/dg.exp Message-ID: <200411132301.RAA20718@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/DeadStoreElimination: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/DeadStoreElimination/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/DeadStoreElimination/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/DeadStoreElimination/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/SimplifyCFG/dg.exp Message-ID: <200411132301.RAA20728@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/SimplifyCFG: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/SimplifyCFG/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/SimplifyCFG/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:56 2004 --- llvm/test/Regression/Transforms/SimplifyCFG/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LoopUnroll/dg.exp Message-ID: <200411132301.RAA20710@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LoopUnroll: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/LoopUnroll/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/LoopUnroll/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/LoopUnroll/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Generic/dg.exp Message-ID: <200411132301.RAA20811@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Generic: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/CodeGen/Generic/dg.exp diff -c /dev/null llvm/test/Regression/CodeGen/Generic/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/CodeGen/Generic/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/BasicAA/dg.exp Message-ID: <200411132301.RAA20767@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/BasicAA: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Analysis/BasicAA/dg.exp diff -c /dev/null llvm/test/Regression/Analysis/BasicAA/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/Analysis/BasicAA/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/CodeExtractor/dg.exp Message-ID: <200411132301.RAA20719@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/CodeExtractor: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/CodeExtractor/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/CodeExtractor/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/CodeExtractor/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/DecomposeMultiDimRefs/dg.exp Message-ID: <200411132301.RAA20709@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/DecomposeMultiDimRefs: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/DecomposeMultiDimRefs/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/DecomposeMultiDimRefs/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/DecomposeMultiDimRefs/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/DSGraph/dg.exp Message-ID: <200411132301.RAA20824@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/DSGraph: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Analysis/DSGraph/dg.exp diff -c /dev/null llvm/test/Regression/Analysis/DSGraph/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/Analysis/DSGraph/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/BugPoint/dg.exp Message-ID: <200411132301.RAA20814@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/BugPoint: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/BugPoint/dg.exp diff -c /dev/null llvm/test/Regression/BugPoint/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/BugPoint/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/GlobalDCE/dg.exp Message-ID: <200411132301.RAA20702@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/GlobalDCE: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/GlobalDCE/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/GlobalDCE/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/GlobalDCE/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/CBackend/dg.exp Message-ID: <200411132301.RAA20810@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/CBackend: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/CodeGen/CBackend/dg.exp diff -c /dev/null llvm/test/Regression/CodeGen/CBackend/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/CodeGen/CBackend/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:08 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:08 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/DeadArgElim/dg.exp Message-ID: <200411132301.RAA20703@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/DeadArgElim: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/DeadArgElim/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/DeadArgElim/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/DeadArgElim/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Inline/dg.exp Message-ID: <200411132301.RAA20725@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Inline: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/Inline/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/Inline/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/Inline/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/IPConstantProp/dg.exp Message-ID: <200411132301.RAA20716@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/IPConstantProp: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/IPConstantProp/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/IPConstantProp/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/IPConstantProp/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/ExecutionEngine/dg.exp Message-ID: <200411132301.RAA20711@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/ExecutionEngine: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/ExecutionEngine/dg.exp diff -c /dev/null llvm/test/Regression/ExecutionEngine/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/ExecutionEngine/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:10 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LowerInvoke/dg.exp Message-ID: <200411132301.RAA20717@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LowerInvoke: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/LowerInvoke/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/LowerInvoke/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/LowerInvoke/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/dg.exp Message-ID: <200411132301.RAA20831@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/C++Frontend/dg.exp diff -c /dev/null llvm/test/Regression/C++Frontend/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/C++Frontend/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/dg.exp Message-ID: <200411132301.RAA20809@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/CFrontend/dg.exp diff -c /dev/null llvm/test/Regression/CFrontend/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/CFrontend/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/BranchCombine/dg.exp Message-ID: <200411132301.RAA20724@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/BranchCombine: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/BranchCombine/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/BranchCombine/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/BranchCombine/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ADCE/dg.exp Message-ID: <200411132301.RAA20829@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ADCE: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/ADCE/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/ADCE/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/ADCE/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/dg.exp Message-ID: <200411132301.RAA20770@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/CodeGen/X86/dg.exp diff -c /dev/null llvm/test/Regression/CodeGen/X86/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/CodeGen/X86/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/LoadVN/dg.exp Message-ID: <200411132301.RAA20827@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/LoadVN: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Analysis/LoadVN/dg.exp diff -c /dev/null llvm/test/Regression/Analysis/LoadVN/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/Analysis/LoadVN/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LowerSetJmp/dg.exp Message-ID: <200411132301.RAA20713@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LowerSetJmp: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/LowerSetJmp/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/LowerSetJmp/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/LowerSetJmp/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LevelRaise/dg.exp Message-ID: <200411132301.RAA20720@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LevelRaise: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/LevelRaise/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/LevelRaise/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/LevelRaise/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/CorrelatedExprs/dg.exp Message-ID: <200411132301.RAA20833@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/CorrelatedExprs: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/CorrelatedExprs/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/CorrelatedExprs/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:58 2004 --- llvm/test/Regression/Transforms/CorrelatedExprs/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Bytecode/dg.exp Message-ID: <200411132301.RAA20764@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Bytecode: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Bytecode/dg.exp diff -c /dev/null llvm/test/Regression/Bytecode/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/Bytecode/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Mem2Reg/dg.exp Message-ID: <200411132301.RAA20721@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Mem2Reg: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/Mem2Reg/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/Mem2Reg/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:56 2004 --- llvm/test/Regression/Transforms/Mem2Reg/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/Andersens/dg.exp Message-ID: <200411132301.RAA20771@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/Andersens: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Analysis/Andersens/dg.exp diff -c /dev/null llvm/test/Regression/Analysis/Andersens/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/Analysis/Andersens/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/RaiseAllocations/dg.exp Message-ID: <200411132301.RAA20775@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/RaiseAllocations: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/RaiseAllocations/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/RaiseAllocations/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/RaiseAllocations/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/FunctionResolve/dg.exp Message-ID: <200411132301.RAA20726@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/FunctionResolve: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/FunctionResolve/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/FunctionResolve/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:58 2004 --- llvm/test/Regression/Transforms/FunctionResolve/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Reassociate/dg.exp Message-ID: <200411132301.RAA20768@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Reassociate: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/Reassociate/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/Reassociate/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/Reassociate/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ArgumentPromotion/dg.exp Message-ID: <200411132301.RAA20825@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ArgumentPromotion: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/ArgumentPromotion/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/ArgumentPromotion/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/ArgumentPromotion/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Debugger/dg.exp Message-ID: <200411132301.RAA20807@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Debugger: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Debugger/dg.exp diff -c /dev/null llvm/test/Regression/Debugger/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/Debugger/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/SCCP/dg.exp Message-ID: <200411132301.RAA20727@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/SCCP: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/SCCP/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/SCCP/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/SCCP/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ProfilePaths/dg.exp Message-ID: <200411132301.RAA20761@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ProfilePaths: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/ProfilePaths/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/ProfilePaths/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/ProfilePaths/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/LoopInfo/dg.exp Message-ID: <200411132301.RAA20772@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/LoopInfo: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Analysis/LoopInfo/dg.exp diff -c /dev/null llvm/test/Regression/Analysis/LoopInfo/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/Analysis/LoopInfo/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ConstantMerge/dg.exp Message-ID: <200411132301.RAA20765@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ConstantMerge: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/ConstantMerge/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/ConstantMerge/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/ConstantMerge/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/IndVarsSimplify/dg.exp Message-ID: <200411132301.RAA20762@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/IndVarsSimplify: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/IndVarsSimplify/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/IndVarsSimplify/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/IndVarsSimplify/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/PRE/dg.exp Message-ID: <200411132301.RAA20808@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/PRE: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/PRE/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/PRE/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/PRE/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Linker/dg.exp Message-ID: <200411132301.RAA20781@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Linker: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Linker/dg.exp diff -c /dev/null llvm/test/Regression/Linker/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/Linker/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/Dominators/dg.exp Message-ID: <200411132301.RAA20826@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/Dominators: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Analysis/Dominators/dg.exp diff -c /dev/null llvm/test/Regression/Analysis/Dominators/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/Analysis/Dominators/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/TailDup/dg.exp Message-ID: <200411132301.RAA20828@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/TailDup: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/TailDup/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/TailDup/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/TailDup/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/BlockPlacement/dg.exp Message-ID: <200411132301.RAA20722@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/BlockPlacement: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/BlockPlacement/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/BlockPlacement/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/BlockPlacement/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LICM/dg.exp Message-ID: <200411132301.RAA20813@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LICM: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/LICM/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/LICM/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/LICM/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/SparcV9/dg.exp Message-ID: <200411132301.RAA20812@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/SparcV9: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/CodeGen/SparcV9/dg.exp diff -c /dev/null llvm/test/Regression/CodeGen/SparcV9/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/CodeGen/SparcV9/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/DSAnalysis/dg.exp Message-ID: <200411132301.RAA20769@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/DSAnalysis: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/DSAnalysis/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/DSAnalysis/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/DSAnalysis/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ConstProp/dg.exp Message-ID: <200411132301.RAA20830@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ConstProp: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/ConstProp/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/ConstProp/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:55 2004 --- llvm/test/Regression/Transforms/ConstProp/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/dg.exp Message-ID: <200411132301.RAA20832@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/CodeGen/PowerPC/dg.exp diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:58 2004 --- llvm/test/Regression/CodeGen/PowerPC/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/dg.exp Message-ID: <200411132301.RAA20763@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Assembler/dg.exp diff -c /dev/null llvm/test/Regression/Assembler/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:54 2004 --- llvm/test/Regression/Assembler/dg.exp Sat Nov 13 17:00:44 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:01:11 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:01:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Verifier/dg.exp Message-ID: <200411132301.RAA20766@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Verifier: dg.exp added (r1.1) --- Log message: Adding subdirectory dg.exp files in order to be able to use dejagnu to only run specific tests (located in some subdirectory of Regression) --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Verifier/dg.exp diff -c /dev/null llvm/test/Regression/Verifier/dg.exp:1.1 *** /dev/null Sat Nov 13 17:00:57 2004 --- llvm/test/Regression/Verifier/dg.exp Sat Nov 13 17:00:45 2004 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext From tbrethou at cs.uiuc.edu Sat Nov 13 17:16:28 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:16:28 -0600 Subject: [llvm-commits] CVS: llvm/test/lib/llvm-dg.exp Message-ID: <200411132316.RAA21209@zion.cs.uiuc.edu> Changes in directory llvm/test/lib: llvm-dg.exp updated: 1.6 -> 1.7 --- Log message: Run prcontext.tcl with tclsh and let it be found in the path. This should be found by configure. --- Diffs of the changes: (+1 -1) Index: llvm/test/lib/llvm-dg.exp diff -u llvm/test/lib/llvm-dg.exp:1.6 llvm/test/lib/llvm-dg.exp:1.7 --- llvm/test/lib/llvm-dg.exp:1.6 Sat Nov 13 16:55:51 2004 +++ llvm/test/lib/llvm-dg.exp Sat Nov 13 17:16:17 2004 @@ -53,7 +53,7 @@ regsub -all {%llvmgxx} $new_runline $llvmgxx new_runline #replace %prcontext with prcontext.tcl (Goes away when we remove qmtest) - regsub -all {%prcontext} $new_runline "prcontext.tcl" new_runline + regsub -all {%prcontext} $new_runline "tclsh prcontext.tcl" new_runline puts $scriptFileId $new_runline } elseif {[regexp {XFAIL:[ *](.+)} $line match targets]} { From lattner at cs.uiuc.edu Sat Nov 13 17:27:24 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 17:27:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86AsmPrinter.cpp Message-ID: <200411132327.iADNROnP028741@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86AsmPrinter.cpp updated: 1.126 -> 1.127 --- Log message: Don't print unneeded labels --- Diffs of the changes: (+7 -5) Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.126 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.127 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.126 Sun Oct 17 02:16:32 2004 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Sat Nov 13 17:27:11 2004 @@ -242,9 +242,10 @@ // Print out code for the function. for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E; ++I) { - // Print a label for the basic block. - O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" - << CommentString << " " << I->getBasicBlock()->getName() << "\n"; + // Print a label for the basic block if there are any predecessors. + if (I->pred_begin() != I->pred_end()) + O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" + << CommentString << " " << I->getBasicBlock()->getName() << "\n"; for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { // Print the assembly for the instruction. @@ -465,8 +466,9 @@ for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E; ++I) { // Print a label for the basic block. - O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" - << CommentString << " " << I->getBasicBlock()->getName() << "\n"; + if (I->pred_begin() != I->pred_end()) + O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" + << CommentString << " " << I->getBasicBlock()->getName() << "\n"; for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { // Print the assembly for the instruction. From lattner at cs.uiuc.edu Sat Nov 13 17:28:22 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 17:28:22 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/CallSite.h Message-ID: <200411132328.iADNSM2h028758@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: CallSite.h updated: 1.15 -> 1.16 --- Log message: Add useful method, minor cleanups --- Diffs of the changes: (+7 -3) Index: llvm/include/llvm/Support/CallSite.h diff -u llvm/include/llvm/Support/CallSite.h:1.15 llvm/include/llvm/Support/CallSite.h:1.16 --- llvm/include/llvm/Support/CallSite.h:1.15 Fri Jun 4 19:17:13 2004 +++ llvm/include/llvm/Support/CallSite.h Sat Nov 13 17:28:10 2004 @@ -13,8 +13,7 @@ // NOTE: This class is supposed to have "value semantics". So it should be // passed by value, not by reference; it should not be "new"ed or "delete"d. It // is efficiently copyable, assignable and constructable, with cost equivalent -// to copying a pointer. (You will notice that it has only a single data -// member.) +// to copying a pointer (notice that it has only a single data member). // //===----------------------------------------------------------------------===// @@ -55,7 +54,7 @@ /// getType - Return the type of the instruction that generated this call site /// - const Type *getType () const { return I->getType (); } + const Type *getType() const { return I->getType(); } /// getInstruction - Return the instruction this call site corresponds to /// @@ -85,6 +84,11 @@ I->setOperand(0, V); } + Value *getArgument(unsigned ArgNo) const { + assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!"); + return *(arg_begin()+ArgNo); + } + /// arg_iterator - The type of iterator to use when looping over actual /// arguments at this call site... typedef User::op_iterator arg_iterator; From lattner at cs.uiuc.edu Sat Nov 13 17:28:51 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 17:28:51 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ArgumentPromotion/control-flow.ll Message-ID: <200411132328.iADNSp1S028770@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ArgumentPromotion: control-flow.ll added (r1.1) --- Log message: Add a testcase for a function we cannot legally promote the argument of. --- Diffs of the changes: (+18 -0) Index: llvm/test/Regression/Transforms/ArgumentPromotion/control-flow.ll diff -c /dev/null llvm/test/Regression/Transforms/ArgumentPromotion/control-flow.ll:1.1 *** /dev/null Sat Nov 13 17:28:49 2004 --- llvm/test/Regression/Transforms/ArgumentPromotion/control-flow.ll Sat Nov 13 17:28:39 2004 *************** *** 0 **** --- 1,18 ---- + ; RUN: llvm-as < %s | opt -argpromotion | llvm-dis | not grep 'load int\* null' + + implementation + + internal int %callee(bool %C, int* %P) { + br bool %C, label %T, label %F + T: + ret int 17 + F: + %X = load int* %P + ret int %X + } + + int %foo() { + %X = call int %callee(bool true, int* null) + ret int %X + } + From lattner at cs.uiuc.edu Sat Nov 13 17:30:34 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 17:30:34 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ArgumentPromotion/control-flow2.ll Message-ID: <200411132330.iADNUYMS028809@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ArgumentPromotion: control-flow2.ll added (r1.1) --- Log message: Add a testcase we should continue to argpromote --- Diffs of the changes: (+20 -0) Index: llvm/test/Regression/Transforms/ArgumentPromotion/control-flow2.ll diff -c /dev/null llvm/test/Regression/Transforms/ArgumentPromotion/control-flow2.ll:1.1 *** /dev/null Sat Nov 13 17:30:32 2004 --- llvm/test/Regression/Transforms/ArgumentPromotion/control-flow2.ll Sat Nov 13 17:30:22 2004 *************** *** 0 **** --- 1,20 ---- + ; RUN: llvm-as < %s | opt -argpromotion | llvm-dis | grep 'load int\* %A' + + implementation + + internal int %callee(bool %C, int* %P) { + br bool %C, label %T, label %F + T: + ret int 17 + F: + %X = load int* %P + ret int %X + } + + int %foo() { + %A = alloca int + store int 17, int* %A + %X = call int %callee(bool false, int* %A) + ret int %X + } + From lattner at cs.uiuc.edu Sat Nov 13 17:31:46 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 17:31:46 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/ArgumentPromotion.cpp Message-ID: <200411132331.iADNVkbR028819@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: ArgumentPromotion.cpp updated: 1.13 -> 1.14 --- Log message: Argument promotion transforms functions to unconditionally load their argument pointers. This is only valid to do if the function already unconditionally loaded an argument or if the pointer passed in is known to be valid. Make sure to do the required checks. This fixed ArgumentPromotion/control-flow.ll and the Burg program. --- Diffs of the changes: (+51 -3) Index: llvm/lib/Transforms/IPO/ArgumentPromotion.cpp diff -u llvm/lib/Transforms/IPO/ArgumentPromotion.cpp:1.13 llvm/lib/Transforms/IPO/ArgumentPromotion.cpp:1.14 --- llvm/lib/Transforms/IPO/ArgumentPromotion.cpp:1.13 Sun Sep 19 23:43:34 2004 +++ llvm/lib/Transforms/IPO/ArgumentPromotion.cpp Sat Nov 13 17:31:34 2004 @@ -87,6 +87,7 @@ // Attempt to promote arguments from all functions in this SCC. for (unsigned i = 0, e = SCC.size(); i != e; ++i) LocalChange |= PromoteArguments(SCC[i]); + if (LocalChange) return true; Changed |= LocalChange; // Remember that we changed something. } while (LocalChange); @@ -145,6 +146,39 @@ return true; } +/// IsAlwaysValidPointer - Return true if the specified pointer is always legal +/// to load. +static bool IsAlwaysValidPointer(Value *V) { + if (isa(V) || isa(V)) return true; + if (GetElementPtrInst *GEP = dyn_cast(V)) + return IsAlwaysValidPointer(GEP->getOperand(0)); + if (ConstantExpr *CE = dyn_cast(V)) + if (CE->getOpcode() == Instruction::GetElementPtr) + return IsAlwaysValidPointer(CE->getOperand(0)); + + return false; +} + +/// AllCalleesPassInValidPointerForArgument - Return true if we can prove that +/// all callees pass in a valid pointer for the specified function argument. +static bool AllCalleesPassInValidPointerForArgument(Argument *Arg) { + Function *Callee = Arg->getParent(); + + unsigned ArgNo = std::distance(Callee->abegin(), Function::aiterator(Arg)); + + // Look at all call sites of the function. At this pointer we know we only + // have direct callees. + for (Value::use_iterator UI = Callee->use_begin(), E = Callee->use_end(); + UI != E; ++UI) { + CallSite CS = CallSite::get(*UI); + assert(CS.getInstruction() && "Should only have direct calls!"); + + if (!IsAlwaysValidPointer(CS.getArgument(ArgNo))) + return false; + } + return true; +} + /// isSafeToPromoteArgument - As you might guess from the name of this method, /// it checks to see if it is both safe and useful to promote the argument. @@ -154,6 +188,8 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg) const { // We can only promote this argument if all of the uses are loads, or are GEP // instructions (with constant indices) that are subsequently loaded. + bool HasLoadInEntryBlock = false; + BasicBlock *EntryBlock = Arg->getParent()->begin(); std::vector Loads; std::vector > GEPIndices; for (Value::use_iterator UI = Arg->use_begin(), E = Arg->use_end(); @@ -161,6 +197,7 @@ if (LoadInst *LI = dyn_cast(*UI)) { if (LI->isVolatile()) return false; // Don't hack volatile loads Loads.push_back(LI); + HasLoadInEntryBlock |= LI->getParent() == EntryBlock; } else if (GetElementPtrInst *GEP = dyn_cast(*UI)) { if (GEP->use_empty()) { // Dead GEP's cause trouble later. Just remove them if we run into @@ -183,6 +220,7 @@ if (LoadInst *LI = dyn_cast(*UI)) { if (LI->isVolatile()) return false; // Don't hack volatile loads Loads.push_back(LI); + HasLoadInEntryBlock |= LI->getParent() == EntryBlock; } else { return false; } @@ -208,9 +246,19 @@ if (Loads.empty()) return true; // No users, this is a dead argument. - // Okay, now we know that the argument is only used by load instructions. Use - // alias analysis to check to see if the pointer is guaranteed to not be - // modified from entry of the function to each of the load instructions. + // If we decide that we want to promote this argument, the value is going to + // be unconditionally loaded in all callees. This is only safe to do if the + // pointer was going to be unconditionally loaded anyway (i.e. there is a load + // of the pointer in the entry block of the function) or if we can prove that + // all pointers passed in are always to legal locations (for example, no null + // pointers are passed in, no pointers to free'd memory, etc). + if (!HasLoadInEntryBlock && !AllCalleesPassInValidPointerForArgument(Arg)) + return false; // Cannot prove that this is safe!! + + // Okay, now we know that the argument is only used by load instructions and + // it is safe to unconditionally load the pointer. Use alias analysis to + // check to see if the pointer is guaranteed to not be modified from entry of + // the function to each of the load instructions. Function &F = *Arg->getParent(); // Because there could be several/many load instructions, remember which From lattner at cs.uiuc.edu Sat Nov 13 17:33:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 17:33:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/ArgumentPromotion.cpp Message-ID: <200411132333.iADNX68r028833@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: ArgumentPromotion.cpp updated: 1.14 -> 1.15 --- Log message: Remove debugging code --- Diffs of the changes: (+0 -1) Index: llvm/lib/Transforms/IPO/ArgumentPromotion.cpp diff -u llvm/lib/Transforms/IPO/ArgumentPromotion.cpp:1.14 llvm/lib/Transforms/IPO/ArgumentPromotion.cpp:1.15 --- llvm/lib/Transforms/IPO/ArgumentPromotion.cpp:1.14 Sat Nov 13 17:31:34 2004 +++ llvm/lib/Transforms/IPO/ArgumentPromotion.cpp Sat Nov 13 17:32:53 2004 @@ -87,7 +87,6 @@ // Attempt to promote arguments from all functions in this SCC. for (unsigned i = 0, e = SCC.size(); i != e; ++i) LocalChange |= PromoteArguments(SCC[i]); - if (LocalChange) return true; Changed |= LocalChange; // Remember that we changed something. } while (LocalChange); From tbrethou at cs.uiuc.edu Sat Nov 13 17:36:29 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:36:29 -0600 Subject: [llvm-commits] CVS: llvm/test/lib/llvm-dg.exp Message-ID: <200411132336.RAA21421@zion.cs.uiuc.edu> Changes in directory llvm/test/lib: llvm-dg.exp updated: 1.7 -> 1.8 --- Log message: setting path to prcontext.tcl script. Right now it searches for tclsh in your path, but this should be obtained from configure. --- Diffs of the changes: (+1 -1) Index: llvm/test/lib/llvm-dg.exp diff -u llvm/test/lib/llvm-dg.exp:1.7 llvm/test/lib/llvm-dg.exp:1.8 --- llvm/test/lib/llvm-dg.exp:1.7 Sat Nov 13 17:16:17 2004 +++ llvm/test/lib/llvm-dg.exp Sat Nov 13 17:36:18 2004 @@ -53,7 +53,7 @@ regsub -all {%llvmgxx} $new_runline $llvmgxx new_runline #replace %prcontext with prcontext.tcl (Goes away when we remove qmtest) - regsub -all {%prcontext} $new_runline "tclsh prcontext.tcl" new_runline + regsub -all {%prcontext} $new_runline $prcontext new_runline puts $scriptFileId $new_runline } elseif {[regexp {XFAIL:[ *](.+)} $line match targets]} { From tbrethou at cs.uiuc.edu Sat Nov 13 17:36:29 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat, 13 Nov 2004 17:36:29 -0600 Subject: [llvm-commits] CVS: llvm/test/Makefile Message-ID: <200411132336.RAA21420@zion.cs.uiuc.edu> Changes in directory llvm/test: Makefile updated: 1.67 -> 1.68 --- Log message: setting path to prcontext.tcl script. Right now it searches for tclsh in your path, but this should be obtained from configure. --- Diffs of the changes: (+1 -1) Index: llvm/test/Makefile diff -u llvm/test/Makefile:1.67 llvm/test/Makefile:1.68 --- llvm/test/Makefile:1.67 Tue Nov 9 00:32:58 2004 +++ llvm/test/Makefile Sat Nov 13 17:36:18 2004 @@ -137,7 +137,7 @@ @echo '# Do not edit here. If you wish to override these values' >>site.tmp @echo '# edit the last section' >>site.tmp @echo "set target_triplet $(TARGET_TRIPLE)" >> site.tmp - @echo 'set prcontext "$(PYTHON) $(LLVM_SRC_ROOT)/test/Scripts/prcontext.py"' >> site.tmp + @echo 'set prcontext "tclsh $(LLVM_SRC_ROOT)/test/Scripts/prcontext.tcl"' >> site.tmp @echo 'set srcdir $(LLVM_SRC_ROOT)/test' >>site.tmp @echo "set objdir $(LLVM_OBJ_ROOT)/test" >>site.tmp @echo 'set llvmgcc $(LLVMGCCDIR)/bin/gcc' >> site.tmp From lattner at cs.uiuc.edu Sat Nov 13 22:24:42 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 22:24:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp Message-ID: <200411140424.iAE4OgTw030350@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: ScalarReplAggregates.cpp updated: 1.26 -> 1.27 --- Log message: Rearrange some code, no functionality changes. --- Diffs of the changes: (+68 -49) Index: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp diff -u llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.26 llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.27 --- llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.26 Sun Sep 19 23:43:15 2004 +++ llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp Sat Nov 13 22:24:28 2004 @@ -54,9 +54,10 @@ } private: - bool isSafeElementUse(Value *Ptr); - bool isSafeUseOfAllocation(Instruction *User); - bool isSafeAllocaToPromote(AllocationInst *AI); + int isSafeElementUse(Value *Ptr); + int isSafeUseOfAllocation(Instruction *User); + int isSafeAllocaToScalarRepl(AllocationInst *AI); + void CanonicalizeAllocaUsers(AllocationInst *AI); AllocaInst *AddNewAlloca(Function &F, const Type *Ty, AllocationInst *Base); }; @@ -141,8 +142,15 @@ // Check that all of the users of the allocation are capable of being // transformed. - if (!isSafeAllocaToPromote(AI)) + switch (isSafeAllocaToScalarRepl(AI)) { + default: assert(0 && "Unexpected value!"); + case 0: // Not safe to scalar replace. continue; + case 1: // Safe, but requires cleanup/canonicalizations first + CanonicalizeAllocaUsers(AI); + case 3: // Safe to scalar replace. + break; + } DEBUG(std::cerr << "Found inst to xform: " << *AI); Changed = true; @@ -217,11 +225,42 @@ } +/// isSafeElementUse - Check to see if this use is an allowed use for a +/// getelementptr instruction of an array aggregate allocation. +/// +int SROA::isSafeElementUse(Value *Ptr) { + for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end(); + I != E; ++I) { + Instruction *User = cast(*I); + switch (User->getOpcode()) { + case Instruction::Load: break; + case Instruction::Store: + // Store is ok if storing INTO the pointer, not storing the pointer + if (User->getOperand(0) == Ptr) return 0; + break; + case Instruction::GetElementPtr: { + GetElementPtrInst *GEP = cast(User); + if (GEP->getNumOperands() > 1) { + if (!isa(GEP->getOperand(1)) || + !cast(GEP->getOperand(1))->isNullValue()) + return 0; // Using pointer arithmetic to navigate the array... + } + if (!isSafeElementUse(GEP)) return 0; + break; + } + default: + DEBUG(std::cerr << " Transformation preventing inst: " << *User); + return 0; + } + } + return 3; // All users look ok :) +} + /// isSafeUseOfAllocation - Check to see if this user is an allowed use for an /// aggregate allocation. /// -bool SROA::isSafeUseOfAllocation(Instruction *User) { - if (!isa(User)) return false; +int SROA::isSafeUseOfAllocation(Instruction *User) { + if (!isa(User)) return 0; GetElementPtrInst *GEPI = cast(User); gep_type_iterator I = gep_type_begin(GEPI), E = gep_type_end(GEPI); @@ -229,11 +268,11 @@ // The GEP is safe to transform if it is of the form GEP , 0, if (I == E || I.getOperand() != Constant::getNullValue(I.getOperand()->getType())) - return false; + return 0; ++I; if (I == E || !isa(I.getOperand())) - return false; + return 0; // If this is a use of an array allocation, do a bit more checking for sanity. if (const ArrayType *AT = dyn_cast(*I)) { @@ -243,7 +282,7 @@ // something funny is going on, so we won't do the optimization. // if (cast(GEPI->getOperand(2))->getRawValue() >= NumElements) - return false; + return 0; } // If there are any non-simple uses of this getelementptr, make sure to reject @@ -251,51 +290,31 @@ return isSafeElementUse(GEPI); } -/// isSafeElementUse - Check to see if this use is an allowed use for a -/// getelementptr instruction of an array aggregate allocation. +/// isSafeStructAllocaToScalarRepl - Check to see if the specified allocation of +/// an aggregate can be broken down into elements. Return 0 if not, 3 if safe, +/// or 1 if safe after canonicalization has been performed. /// -bool SROA::isSafeElementUse(Value *Ptr) { - for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end(); - I != E; ++I) { - Instruction *User = cast(*I); - switch (User->getOpcode()) { - case Instruction::Load: break; - case Instruction::Store: - // Store is ok if storing INTO the pointer, not storing the pointer - if (User->getOperand(0) == Ptr) return false; - break; - case Instruction::GetElementPtr: { - GetElementPtrInst *GEP = cast(User); - if (GEP->getNumOperands() > 1) { - if (!isa(GEP->getOperand(1)) || - !cast(GEP->getOperand(1))->isNullValue()) - return false; // Using pointer arithmetic to navigate the array... - } - if (!isSafeElementUse(GEP)) return false; - break; - } - default: - DEBUG(std::cerr << " Transformation preventing inst: " << *User); - return false; - } - } - return true; // All users look ok :) -} - - -/// isSafeStructAllocaToPromote - Check to see if the specified allocation of a -/// structure can be broken down into elements. -/// -bool SROA::isSafeAllocaToPromote(AllocationInst *AI) { +int SROA::isSafeAllocaToScalarRepl(AllocationInst *AI) { // Loop over the use list of the alloca. We can only transform it if all of // the users are safe to transform. // + int isSafe = 3; for (Value::use_iterator I = AI->use_begin(), E = AI->use_end(); - I != E; ++I) - if (!isSafeUseOfAllocation(cast(*I))) { + I != E; ++I) { + isSafe &= isSafeUseOfAllocation(cast(*I)); + if (isSafe == 0) { DEBUG(std::cerr << "Cannot transform: " << *AI << " due to user: " - << **I); - return false; + << **I); + return 0; } - return true; + } + // If we require cleanup, isSafe is now 1, otherwise it is 3. + return isSafe; +} + +/// CanonicalizeAllocaUsers - If SROA reported that it can promote the specified +/// allocation, but only if cleaned up, perform the cleanups required. +void SROA::CanonicalizeAllocaUsers(AllocationInst *AI) { + + } From lattner at cs.uiuc.edu Sat Nov 13 22:58:52 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 22:58:52 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ScalarRepl/sroa_two.ll Message-ID: <200411140458.iAE4wqkG031884@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ScalarRepl: sroa_two.ll added (r1.1) --- Log message: New testcase, SROA with variable array index --- Diffs of the changes: (+16 -0) Index: llvm/test/Regression/Transforms/ScalarRepl/sroa_two.ll diff -c /dev/null llvm/test/Regression/Transforms/ScalarRepl/sroa_two.ll:1.1 *** /dev/null Sat Nov 13 22:58:50 2004 --- llvm/test/Regression/Transforms/ScalarRepl/sroa_two.ll Sat Nov 13 22:58:40 2004 *************** *** 0 **** --- 1,16 ---- + ; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis + + implementation + + int %test(int %X) { + %Arr = alloca [2 x int] + %tmp.0 = getelementptr [2 x int]* %Arr, int 0, int 0 + store int 1, int* %tmp.0 + %tmp.1 = getelementptr [2 x int]* %Arr, int 0, int 1 + store int 2, int* %tmp.1 + + ;; This should turn into a select instruction. + %tmp.3 = getelementptr [2 x int]* %Arr, int 0, int %X + %tmp.4 = load int* %tmp.3 + ret int %tmp.4 + } From lattner at cs.uiuc.edu Sat Nov 13 23:00:31 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 13 Nov 2004 23:00:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp Message-ID: <200411140500.iAE50VDu031903@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: ScalarReplAggregates.cpp updated: 1.27 -> 1.28 --- Log message: Teach SROA how to promote an array index that is variable, if the dimension of the array is just two. This occurs 8 times in gcc, 6 times in crafty, and 12 times in 099.go. This implements ScalarRepl/sroa_two.ll --- Diffs of the changes: (+98 -40) Index: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp diff -u llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.27 llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.28 --- llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.27 Sat Nov 13 22:24:28 2004 +++ llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp Sat Nov 13 23:00:19 2004 @@ -181,39 +181,35 @@ // while (!AI->use_empty()) { Instruction *User = cast(AI->use_back()); - if (GetElementPtrInst *GEPI = dyn_cast(User)) { - // We now know that the GEP is of the form: GEP , 0, - uint64_t Idx = cast(GEPI->getOperand(2))->getRawValue(); - - assert(Idx < ElementAllocas.size() && "Index out of range?"); - AllocaInst *AllocaToUse = ElementAllocas[Idx]; - - Value *RepValue; - if (GEPI->getNumOperands() == 3) { - // Do not insert a new getelementptr instruction with zero indices, - // only to have it optimized out later. - RepValue = AllocaToUse; - } else { - // We are indexing deeply into the structure, so we still need a - // getelement ptr instruction to finish the indexing. This may be - // expanded itself once the worklist is rerun. - // - std::string OldName = GEPI->getName(); // Steal the old name... - std::vector NewArgs; - NewArgs.push_back(Constant::getNullValue(Type::IntTy)); - NewArgs.insert(NewArgs.end(), GEPI->op_begin()+3, GEPI->op_end()); - GEPI->setName(""); - RepValue = - new GetElementPtrInst(AllocaToUse, NewArgs, OldName, GEPI); - } - - // Move all of the users over to the new GEP. - GEPI->replaceAllUsesWith(RepValue); - // Delete the old GEP - GEPI->getParent()->getInstList().erase(GEPI); + GetElementPtrInst *GEPI = cast(User); + // We now know that the GEP is of the form: GEP , 0, + uint64_t Idx = cast(GEPI->getOperand(2))->getRawValue(); + + assert(Idx < ElementAllocas.size() && "Index out of range?"); + AllocaInst *AllocaToUse = ElementAllocas[Idx]; + + Value *RepValue; + if (GEPI->getNumOperands() == 3) { + // Do not insert a new getelementptr instruction with zero indices, only + // to have it optimized out later. + RepValue = AllocaToUse; } else { - assert(0 && "Unexpected instruction type!"); + // We are indexing deeply into the structure, so we still need a + // getelement ptr instruction to finish the indexing. This may be + // expanded itself once the worklist is rerun. + // + std::string OldName = GEPI->getName(); // Steal the old name. + std::vector NewArgs; + NewArgs.push_back(Constant::getNullValue(Type::IntTy)); + NewArgs.insert(NewArgs.end(), GEPI->op_begin()+3, GEPI->op_end()); + GEPI->setName(""); + RepValue = new GetElementPtrInst(AllocaToUse, NewArgs, OldName, GEPI); } + + // Move all of the users over to the new GEP. + GEPI->replaceAllUsesWith(RepValue); + // Delete the old GEP + GEPI->eraseFromParent(); } // Finally, delete the Alloca instruction @@ -256,6 +252,15 @@ return 3; // All users look ok :) } +/// AllUsersAreLoads - Return true if all users of this value are loads. +static bool AllUsersAreLoads(Value *Ptr) { + for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end(); + I != E; ++I) + if (cast(*I)->getOpcode() != Instruction::Load) + return false; + return true; +} + /// isSafeUseOfAllocation - Check to see if this user is an allowed use for an /// aggregate allocation. /// @@ -271,18 +276,28 @@ return 0; ++I; - if (I == E || !isa(I.getOperand())) - return 0; + if (I == E) return 0; // ran out of GEP indices?? // If this is a use of an array allocation, do a bit more checking for sanity. if (const ArrayType *AT = dyn_cast(*I)) { uint64_t NumElements = AT->getNumElements(); - - // Check to make sure that index falls within the array. If not, - // something funny is going on, so we won't do the optimization. - // - if (cast(GEPI->getOperand(2))->getRawValue() >= NumElements) + + if (ConstantInt *CI = dyn_cast(I.getOperand())) { + // Check to make sure that index falls within the array. If not, + // something funny is going on, so we won't do the optimization. + // + if (cast(GEPI->getOperand(2))->getRawValue() >= NumElements) + return 0; + + } else { + // If this is an array index and the index is not constant, we cannot + // promote... that is unless the array has exactly one or two elements in + // it, in which case we CAN promote it, but we have to canonicalize this + // out if this is the only problem. + if (NumElements == 1 || NumElements == 2) + return AllUsersAreLoads(GEPI) ? 1 : 0; // Canonicalization required! return 0; + } } // If there are any non-simple uses of this getelementptr, make sure to reject @@ -315,6 +330,49 @@ /// CanonicalizeAllocaUsers - If SROA reported that it can promote the specified /// allocation, but only if cleaned up, perform the cleanups required. void SROA::CanonicalizeAllocaUsers(AllocationInst *AI) { - - + // At this point, we know that the end result will be SROA'd and promoted, so + // we can insert ugly code if required so long as sroa+mem2reg will clean it + // up. + for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); + UI != E; ) { + GetElementPtrInst *GEPI = cast(*UI++); + gep_type_iterator I = gep_type_begin(GEPI), E = gep_type_end(GEPI); + ++I; + + if (const ArrayType *AT = dyn_cast(*I)) { + uint64_t NumElements = AT->getNumElements(); + + if (!isa(I.getOperand())) { + if (NumElements == 1) { + GEPI->setOperand(2, Constant::getNullValue(Type::IntTy)); + } else { + assert(NumElements == 2 && "Unhandled case!"); + // All users of the GEP must be loads. At each use of the GEP, insert + // two loads of the appropriate indexed GEP and select between them. + Value *IsOne = BinaryOperator::createSetNE(I.getOperand(), + Constant::getNullValue(I.getOperand()->getType()), + "isone", GEPI); + // Insert the new GEP instructions, which are properly indexed. + std::vector Indices(GEPI->op_begin()+1, GEPI->op_end()); + Indices[1] = Constant::getNullValue(Type::IntTy); + Value *ZeroIdx = new GetElementPtrInst(GEPI->getOperand(0), Indices, + GEPI->getName()+".0", GEPI); + Indices[1] = ConstantInt::get(Type::IntTy, 1); + Value *OneIdx = new GetElementPtrInst(GEPI->getOperand(0), Indices, + GEPI->getName()+".1", GEPI); + // Replace all loads of the variable index GEP with loads from both + // indexes and a select. + while (!GEPI->use_empty()) { + LoadInst *LI = cast(GEPI->use_back()); + Value *Zero = new LoadInst(ZeroIdx, LI->getName()+".0", LI); + Value *One = new LoadInst(OneIdx , LI->getName()+".1", LI); + Value *R = new SelectInst(IsOne, One, Zero, LI->getName(), LI); + LI->replaceAllUsesWith(R); + LI->eraseFromParent(); + } + GEPI->eraseFromParent(); + } + } + } + } } From lattner at cs.uiuc.edu Sun Nov 14 00:03:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 00:03:00 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/IPConstantProp/return-constant.ll Message-ID: <200411140603.iAE630Fq000578@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/IPConstantProp: return-constant.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: (+16 -0) Index: llvm/test/Regression/Transforms/IPConstantProp/return-constant.ll diff -c /dev/null llvm/test/Regression/Transforms/IPConstantProp/return-constant.ll:1.1 *** /dev/null Sun Nov 14 00:02:56 2004 --- llvm/test/Regression/Transforms/IPConstantProp/return-constant.ll Sun Nov 14 00:02:46 2004 *************** *** 0 **** --- 1,16 ---- + ; RUN: llvm-as < %s | opt -ipconstprop -instcombine | llvm-dis + implementation + + internal int %foo(bool %C) { + br bool %C, label %T, label %F + T: + ret int 52 + F: + ret int 52 + } + + bool %caller(bool %C) { + %X = call int %foo(bool %C) + %Y = cast int %X to bool + ret bool %Y + } From lattner at cs.uiuc.edu Sun Nov 14 00:10:23 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 00:10:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Message-ID: <200411140610.iAE6ANrJ000894@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: IPConstantPropagation.cpp updated: 1.13 -> 1.14 --- Log message: If a function always returns a constant, replace all calls sites with that constant value. This makes the return value dead and allows for simplification in the caller. This implements IPConstantProp/return-constant.ll This triggers several dozen times throughout SPEC. --- Diffs of the changes: (+80 -11) Index: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp diff -u llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.13 llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.14 --- llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.13 Thu Nov 11 01:47:54 2004 +++ llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Sun Nov 14 00:10:11 2004 @@ -16,9 +16,10 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO.h" +#include "llvm/Constants.h" +#include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Pass.h" -#include "llvm/Constants.h" #include "llvm/Support/CallSite.h" #include "llvm/ADT/Statistic.h" using namespace llvm; @@ -26,13 +27,16 @@ namespace { Statistic<> NumArgumentsProped("ipconstprop", "Number of args turned into constants"); + Statistic<> NumReturnValProped("ipconstprop", + "Number of return values turned into constants"); /// IPCP - The interprocedural constant propagation pass /// struct IPCP : public ModulePass { bool runOnModule(Module &M); private: - bool processFunction(Function &F); + bool PropagateConstantsIntoArguments(Function &F); + bool PropagateConstantReturn(Function &F); }; RegisterOpt X("ipconstprop", "Interprocedural constant propagation"); } @@ -48,23 +52,25 @@ while (LocalChange) { LocalChange = false; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (!I->isExternal() && I->hasInternalLinkage()) - LocalChange |= processFunction(*I); + if (!I->isExternal()) { + // Delete any klingons. + I->removeDeadConstantUsers(); + if (I->hasInternalLinkage()) + LocalChange |= PropagateConstantsIntoArguments(*I); + Changed |= PropagateConstantReturn(*I); + } Changed |= LocalChange; } return Changed; } -/// processFunction - Look at all uses of the specified function. If all uses -/// are direct call sites, and all pass a particular constant in for an -/// argument, propagate that constant in as the argument. +/// PropagateConstantsIntoArguments - Look at all uses of the specified +/// function. If all uses are direct call sites, and all pass a particular +/// constant in for an argument, propagate that constant in as the argument. /// -bool IPCP::processFunction(Function &F) { +bool IPCP::PropagateConstantsIntoArguments(Function &F) { if (F.aempty() || F.use_empty()) return false; // No arguments? Early exit. - // Delete any klingons. - F.removeDeadConstantUsers(); - std::vector > ArgumentConstants; ArgumentConstants.resize(F.asize()); @@ -123,3 +129,66 @@ return MadeChange; } + +// Check to see if this function returns a constant. If so, replace all callers +// that user the return value with the returned valued. If we can replace ALL +// callers, +bool IPCP::PropagateConstantReturn(Function &F) { + if (F.getReturnType() == Type::VoidTy) + return false; // No return value. + + // Check to see if this function returns a constant. + Value *RetVal = 0; + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + if (ReturnInst *RI = dyn_cast(BB->getTerminator())) + if (isa(RI->getOperand(0))) { + // Ignore. + } else if (Constant *C = dyn_cast(RI->getOperand(0))) { + if (RetVal == 0) + RetVal = C; + else if (RetVal != C) + return false; // Does not return the same constant. + } else { + return false; // Does not return a constant. + } + + if (RetVal == 0) RetVal = UndefValue::get(F.getReturnType()); + + // If we got here, the function returns a constant value. Loop over all + // users, replacing any uses of the return value with the returned constant. + bool ReplacedAllUsers = true; + bool MadeChange = false; + for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) + if (!isa(*I)) + ReplacedAllUsers = false; + else { + CallSite CS = CallSite::get(cast(*I)); + if (CS.getInstruction() == 0 || + CS.getCalledFunction() != &F) { + ReplacedAllUsers = false; + } else { + if (!CS.getInstruction()->use_empty()) { + CS.getInstruction()->replaceAllUsesWith(RetVal); + MadeChange = true; + } + } + } + + // If we replace all users with the returned constant, and there can be no + // other callers of the function, replace the constant being returned in the + // function with an undef value. + if (ReplacedAllUsers && F.hasInternalLinkage() && !isa(RetVal)) { + Value *RV = UndefValue::get(RetVal->getType()); + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + if (ReturnInst *RI = dyn_cast(BB->getTerminator())) + RI->setOperand(0, RV); + MadeChange = true; + } + + if (MadeChange) ++NumReturnValProped; + + // FIXME: DAE should remove dead return values if the result is an undef + // value... or if it is never used. + + return MadeChange; +} From lattner at cs.uiuc.edu Sun Nov 14 00:11:53 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 00:11:53 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/IPConstantProp/return-constant.ll Message-ID: <200411140611.iAE6BrPn000932@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/IPConstantProp: return-constant.ll updated: 1.1 -> 1.2 --- Log message: Oops, make this test the right thing. --- Diffs of the changes: (+1 -1) Index: llvm/test/Regression/Transforms/IPConstantProp/return-constant.ll diff -u llvm/test/Regression/Transforms/IPConstantProp/return-constant.ll:1.1 llvm/test/Regression/Transforms/IPConstantProp/return-constant.ll:1.2 --- llvm/test/Regression/Transforms/IPConstantProp/return-constant.ll:1.1 Sun Nov 14 00:02:46 2004 +++ llvm/test/Regression/Transforms/IPConstantProp/return-constant.ll Sun Nov 14 00:11:41 2004 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -ipconstprop -instcombine | llvm-dis +; RUN: llvm-as < %s | opt -ipconstprop -instcombine | llvm-dis | grep 'ret bool true' implementation internal int %foo(bool %C) { From lattner at cs.uiuc.edu Sun Nov 14 00:57:59 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 00:57:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Message-ID: <200411140657.iAE6vx6T000982@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: IPConstantPropagation.cpp updated: 1.14 -> 1.15 --- Log message: Remove note to self --- Diffs of the changes: (+0 -4) Index: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp diff -u llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.14 llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.15 --- llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.14 Sun Nov 14 00:10:11 2004 +++ llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Sun Nov 14 00:57:47 2004 @@ -186,9 +186,5 @@ } if (MadeChange) ++NumReturnValProped; - - // FIXME: DAE should remove dead return values if the result is an undef - // value... or if it is never used. - return MadeChange; } From lattner at cs.uiuc.edu Sun Nov 14 01:33:28 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 01:33:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200411140733.iAE7XSrF002383@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.281 -> 1.282 --- Log message: Transform this: %X = alloca ... %Y = alloca ... X == Y into false. This allows us to simplify some stuff in eon (and probably many other C++ programs) where operator= was checking for self assignment. Folding this allows us to SROA several additional structs. --- Diffs of the changes: (+6 -4) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.281 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.282 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.281 Sat Nov 13 13:50:12 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 14 01:33:16 2004 @@ -1870,12 +1870,14 @@ if (isa(Op1)) // X setcc undef -> undef return ReplaceInstUsesWith(I, UndefValue::get(Type::BoolTy)); - // setcc , 0 - Global/Stack value addresses are never null! - if (isa(Op1) && - (isa(Op0) || isa(Op0))) + // setcc , - Global/Stack value + // addresses never equal each other! We already know that Op0 != Op1. + if ((isa(Op0) || isa(Op0) || + isa(Op0)) && + (isa(Op1) || isa(Op1) || + isa(Op1))) return ReplaceInstUsesWith(I, ConstantBool::get(!isTrueWhenEqual(I))); - // setcc's with boolean values can always be turned into bitwise operations if (Ty == Type::BoolTy) { switch (I.getOpcode()) { From lattner at cs.uiuc.edu Sun Nov 14 02:21:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 02:21:02 -0600 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/252.eon/Makefile Message-ID: <200411140821.iAE8L2KV002628@apoc.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/252.eon: Makefile updated: 1.10 -> 1.11 --- Log message: Use the tolerance that the SPEC makefiles use. This allows eon to pass in ref mode. --- Diffs of the changes: (+1 -1) Index: llvm-test/External/SPEC/CINT2000/252.eon/Makefile diff -u llvm-test/External/SPEC/CINT2000/252.eon/Makefile:1.10 llvm-test/External/SPEC/CINT2000/252.eon/Makefile:1.11 --- llvm-test/External/SPEC/CINT2000/252.eon/Makefile:1.10 Mon Sep 6 23:18:02 2004 +++ llvm-test/External/SPEC/CINT2000/252.eon/Makefile Sun Nov 14 02:20:47 2004 @@ -2,7 +2,7 @@ RUN_OPTIONS = chair.control.cook chair.camera chair.surfaces chair.cook.ppm ppm pixels_out.cook STDOUT_FILENAME = cook_log.out STDERR_FILENAME = cook_log.err -FP_TOLERANCE := 0.0001 +FP_ABSTOLERANCE := 0.005 # Yes, we know this is an old crufty C++ benchmark. Don't tell us about it GCC! CPPFLAGS = -include errno.h -Wno-deprecated -Wno-non-template-friend -DHAS_ERRLIST -DUSE_STRERROR -DSPEC_STDCPP -DNDEBUG From llvm at cs.uiuc.edu Sun Nov 14 02:51:01 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Sun, 14 Nov 2004 02:51:01 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ranlib/ Message-ID: <200411140851.CAA00675@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ranlib: --- Log message: Directory /var/cvs/llvm/llvm/tools/llvm-ranlib added to the repository --- Diffs of the changes: (+0 -0) From lattner at cs.uiuc.edu Sun Nov 14 11:54:41 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 11:54:41 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/phi.ll Message-ID: <200411141754.iAEHsfVU009386@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: phi.ll updated: 1.10 -> 1.11 --- Log message: add a testcase, which we already handle --- Diffs of the changes: (+11 -1) Index: llvm/test/Regression/Transforms/InstCombine/phi.ll diff -u llvm/test/Regression/Transforms/InstCombine/phi.ll:1.10 llvm/test/Regression/Transforms/InstCombine/phi.ll:1.11 --- llvm/test/Regression/Transforms/InstCombine/phi.ll:1.10 Thu May 27 02:39:51 2004 +++ llvm/test/Regression/Transforms/InstCombine/phi.ll Sun Nov 14 11:54:27 2004 @@ -33,7 +33,7 @@ ret int %B } -int %test3(bool %b) { +int %test4(bool %b) { BB0: ret int 7 ; Loop is unreachable Loop: @@ -43,3 +43,13 @@ br label %Loop } +int %test5(int %a, bool %b) { +BB0: br label %Loop + +Loop: + %B = phi int [%A, %BB0], [undef, %Loop] ; PHI has same value always. + br bool %b, label %Loop, label %Exit +Exit: + ret int %B +} + From lattner at cs.uiuc.edu Sun Nov 14 11:55:10 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 11:55:10 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/phi.ll Message-ID: <200411141755.iAEHtAvJ009409@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: phi.ll updated: 1.11 -> 1.12 --- Log message: Fix typo --- Diffs of the changes: (+1 -1) Index: llvm/test/Regression/Transforms/InstCombine/phi.ll diff -u llvm/test/Regression/Transforms/InstCombine/phi.ll:1.11 llvm/test/Regression/Transforms/InstCombine/phi.ll:1.12 --- llvm/test/Regression/Transforms/InstCombine/phi.ll:1.11 Sun Nov 14 11:54:27 2004 +++ llvm/test/Regression/Transforms/InstCombine/phi.ll Sun Nov 14 11:54:58 2004 @@ -43,7 +43,7 @@ br label %Loop } -int %test5(int %a, bool %b) { +int %test5(int %A, bool %b) { BB0: br label %Loop Loop: From lattner at cs.uiuc.edu Sun Nov 14 13:12:31 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 13:12:31 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/phi.ll Message-ID: <200411141912.iAEJCVon010508@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: phi.ll updated: 1.12 -> 1.13 --- Log message: New testcase: the phi can be eliminated if the casts are sucked into it. Note that this reduces code size anyway (as well as making further optimizations simpler) so it's always a win. --- Diffs of the changes: (+12 -0) Index: llvm/test/Regression/Transforms/InstCombine/phi.ll diff -u llvm/test/Regression/Transforms/InstCombine/phi.ll:1.12 llvm/test/Regression/Transforms/InstCombine/phi.ll:1.13 --- llvm/test/Regression/Transforms/InstCombine/phi.ll:1.12 Sun Nov 14 11:54:58 2004 +++ llvm/test/Regression/Transforms/InstCombine/phi.ll Sun Nov 14 13:12:17 2004 @@ -53,3 +53,15 @@ ret int %B } +uint %test6(int %A, bool %b) { +BB0: + %X = cast int %A to uint + br bool %b, label %BB1, label %BB2 +BB1: + %Y = cast int %A to uint + br label %BB2 +BB2: + %B = phi uint [%X, %BB0], [%Y, %BB1] ;; Suck casts into phi + ret uint %B +} + From lattner at cs.uiuc.edu Sun Nov 14 13:13:35 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 13:13:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200411141913.iAEJDZSt010547@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.282 -> 1.283 --- Log message: Implement instcombine/phi.ll:test6 - pulling operations through PHI nodes. This exposes subsequent optimization possiblities and reduces code size. This triggers 1423 times in spec. --- Diffs of the changes: (+85 -6) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.282 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.283 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.282 Sun Nov 14 01:33:16 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 14 13:13:23 2004 @@ -29,7 +29,7 @@ // 5. add X, X is represented as (X*2) => (X << 1) // 6. Multiplies with a power-of-two constant argument are transformed into // shifts. -// N. This list is incomplete +// ... etc. // //===----------------------------------------------------------------------===// @@ -205,6 +205,11 @@ // (which is only possible if all operands to the PHI are constants). Instruction *FoldOpIntoPhi(Instruction &I); + // FoldPHIArgOpIntoPHI - If all operands to a PHI node are the same "unary" + // operator and they all are only used by the PHI, PHI together their + // inputs, and do the operation once, to the result of the PHI. + Instruction *FoldPHIArgOpIntoPHI(PHINode &PN); + Instruction *OptAndOp(Instruction *Op, ConstantIntegral *OpRHS, ConstantIntegral *AndRHS, BinaryOperator &TheAnd); @@ -509,11 +514,13 @@ /// is only possible if all operands to the PHI are constants). Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) { PHINode *PN = cast(I.getOperand(0)); - if (!PN->hasOneUse()) return 0; + unsigned NumPHIValues = PN->getNumIncomingValues(); + if (!PN->hasOneUse() || NumPHIValues == 0 || + !isa(PN->getIncomingValue(0))) return 0; // Check to see if all of the operands of the PHI are constants. If not, we // cannot do the transformation. - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + for (unsigned i = 1; i != NumPHIValues; ++i) if (!isa(PN->getIncomingValue(i))) return 0; @@ -526,7 +533,7 @@ // Next, add all of the operands to the PHI. if (I.getNumOperands() == 2) { Constant *C = cast(I.getOperand(1)); - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + for (unsigned i = 0; i != NumPHIValues; ++i) { Constant *InV = cast(PN->getIncomingValue(i)); NewPN->addIncoming(ConstantExpr::get(I.getOpcode(), InV, C), PN->getIncomingBlock(i)); @@ -534,7 +541,7 @@ } else { assert(isa(I) && "Unary op should be a cast!"); const Type *RetTy = I.getType(); - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + for (unsigned i = 0; i != NumPHIValues; ++i) { Constant *InV = cast(PN->getIncomingValue(i)); NewPN->addIncoming(ConstantExpr::getCast(InV, RetTy), PN->getIncomingBlock(i)); @@ -3408,6 +3415,63 @@ } +// FoldPHIArgOpIntoPHI - If all operands to a PHI node are the same "unary" +// operator and they all are only used by the PHI, PHI together their +// inputs, and do the operation once, to the result of the PHI. +Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) { + Instruction *FirstInst = cast(PN.getIncomingValue(0)); + + // Scan the instruction, looking for input operations that can be folded away. + // If all input operands to the phi are the same instruction (e.g. a cast from + // the same type or "+42") we can pull the operation through the PHI, reducing + // code size and simplifying code. + Constant *ConstantOp = 0; + const Type *CastSrcTy = 0; + if (isa(FirstInst)) { + CastSrcTy = FirstInst->getOperand(0)->getType(); + } else if (isa(FirstInst) || isa(FirstInst)) { + // Can fold binop or shift if the RHS is a constant. + ConstantOp = dyn_cast(FirstInst->getOperand(1)); + if (ConstantOp == 0) return 0; + } else { + return 0; // Cannot fold this operation. + } + + // Check to see if all arguments are the same operation. + for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) { + if (!isa(PN.getIncomingValue(i))) return 0; + Instruction *I = cast(PN.getIncomingValue(i)); + if (!I->hasOneUse() || I->getOpcode() != FirstInst->getOpcode()) + return 0; + if (CastSrcTy) { + if (I->getOperand(0)->getType() != CastSrcTy) + return 0; // Cast operation must match. + } else if (I->getOperand(1) != ConstantOp) { + return 0; + } + } + + // Okay, they are all the same operation. Create a new PHI node of the + // correct type, and PHI together all of the LHS's of the instructions. + PHINode *NewPN = new PHINode(FirstInst->getOperand(0)->getType(), + PN.getName()+".in"); + NewPN->op_reserve(PN.getNumOperands()); + InsertNewInstBefore(NewPN, PN); + + // Add all operands to the new PHI. + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) + NewPN->addIncoming(cast(PN.getIncomingValue(i))->getOperand(0), + PN.getIncomingBlock(i)); + + // Insert and return the new operation. + if (isa(FirstInst)) + return new CastInst(NewPN, PN.getType()); + else if (BinaryOperator *BinOp = dyn_cast(FirstInst)) + return BinaryOperator::create(BinOp->getOpcode(), NewPN, ConstantOp); + else + return new ShiftInst(cast(FirstInst)->getOpcode(), + NewPN, ConstantOp); +} // PHINode simplification // @@ -3459,6 +3523,15 @@ return &PN; // PN is now dead! } } + + // If all PHI operands are the same operation, pull them through the PHI, + // reducing code size. + if (isa(PN.getIncomingValue(0)) && + PN.getIncomingValue(0)->hasOneUse()) + if (Instruction *Result = FoldPHIArgOpIntoPHI(PN)) + return Result; + + return 0; } @@ -4111,7 +4184,13 @@ // Insert the new instruction into the basic block... BasicBlock *InstParent = I->getParent(); - InstParent->getInstList().insert(I, Result); + BasicBlock::iterator InsertPos = I; + + if (!isa(Result)) // If combining a PHI, don't insert + while (isa(InsertPos)) // middle of a block of PHIs. + ++InsertPos; + + InstParent->getInstList().insert(InsertPos, Result); // Make sure that we reprocess all operands now that we reduced their // use counts. From lattner at cs.uiuc.edu Sun Nov 14 13:29:46 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 13:29:46 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200411141929.iAEJTkJa011371@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.283 -> 1.284 --- Log message: This optimization makes MANY phi nodes that all have the same incoming value. If this happens, detect it early instead of relying on instcombine to notice it later. This can be a big speedup, because PHI nodes can have many incoming values. --- Diffs of the changes: (+23 -7) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.283 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.284 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.283 Sun Nov 14 13:13:23 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 14 13:29:34 2004 @@ -3456,21 +3456,37 @@ PHINode *NewPN = new PHINode(FirstInst->getOperand(0)->getType(), PN.getName()+".in"); NewPN->op_reserve(PN.getNumOperands()); - InsertNewInstBefore(NewPN, PN); + + Value *InVal = FirstInst->getOperand(0); + NewPN->addIncoming(InVal, PN.getIncomingBlock(0)); // Add all operands to the new PHI. - for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) - NewPN->addIncoming(cast(PN.getIncomingValue(i))->getOperand(0), - PN.getIncomingBlock(i)); + for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) { + Value *NewInVal = cast(PN.getIncomingValue(i))->getOperand(0); + if (NewInVal != InVal) + InVal = 0; + NewPN->addIncoming(NewInVal, PN.getIncomingBlock(i)); + } + + Value *PhiVal; + if (InVal) { + // The new PHI unions all of the same values together. This is really + // common, so we handle it intelligently here for compile-time speed. + PhiVal = InVal; + delete NewPN; + } else { + InsertNewInstBefore(NewPN, PN); + PhiVal = NewPN; + } // Insert and return the new operation. if (isa(FirstInst)) - return new CastInst(NewPN, PN.getType()); + return new CastInst(PhiVal, PN.getType()); else if (BinaryOperator *BinOp = dyn_cast(FirstInst)) - return BinaryOperator::create(BinOp->getOpcode(), NewPN, ConstantOp); + return BinaryOperator::create(BinOp->getOpcode(), PhiVal, ConstantOp); else return new ShiftInst(cast(FirstInst)->getOpcode(), - NewPN, ConstantOp); + PhiVal, ConstantOp); } // PHINode simplification From reid at x10sys.com Sun Nov 14 14:00:19 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 14:00:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Archive/ArchiveReader.cpp Message-ID: <200411142000.OAA04636@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Archive: ArchiveReader.cpp updated: 1.20 -> 1.21 --- Log message: Moved to lib/Bytecode/Archive in preparation for re-write. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Bytecode/Archive/ArchiveReader.cpp diff -u llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.20 llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.21 --- llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.20 Tue Nov 9 13:37:07 2004 +++ llvm/lib/Bytecode/Archive/ArchiveReader.cpp Sun Nov 14 13:59:40 2004 @@ -1,4 +1,4 @@ -//===- ArchiveReader.cpp - Code to read LLVM bytecode from .a files -------===// +//===- lib/Archive/ArchiveReader.cpp - Read LLVM archive files ------------===// // // The LLVM Compiler Infrastructure // From reid at x10sys.com Sun Nov 14 14:22:36 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 14:22:36 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Linker.h Message-ID: <200411142022.OAA05653@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Linker.h updated: 1.8 -> 1.9 --- Log message: Moved from include/llvm/Support/Linker.h --- Diffs of the changes: (+3 -3) Index: llvm/include/llvm/Linker.h diff -u llvm/include/llvm/Linker.h:1.8 llvm/include/llvm/Linker.h:1.9 --- llvm/include/llvm/Linker.h:1.8 Tue Nov 11 16:41:31 2003 +++ llvm/include/llvm/Linker.h Sun Nov 14 14:21:58 2004 @@ -1,4 +1,4 @@ -//===- llvm/Transforms/Utils/Linker.h - Module Linker Interface -*- C++ -*-===// +//===- llvm/Linker.h - Module Linker Interface ------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TRANSFORMATIONS_UTILS_LINKER_H -#define LLVM_TRANSFORMATIONS_UTILS_LINKER_H +#ifndef LLVM_LINKER_H +#define LLVM_LINKER_H #include From brukman at cs.uiuc.edu Sun Nov 14 14:34:11 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Sun, 14 Nov 2004 14:34:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPC.h Message-ID: <200411142034.OAA07750@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPC.h updated: 1.10 -> 1.11 --- Log message: Fix build on Linux/PowerPC64 using SuSE GCC (#undef PPC) --- Diffs of the changes: (+3 -0) Index: llvm/lib/Target/PowerPC/PowerPC.h diff -u llvm/lib/Target/PowerPC/PowerPC.h:1.10 llvm/lib/Target/PowerPC/PowerPC.h:1.11 --- llvm/lib/Target/PowerPC/PowerPC.h:1.10 Sat Sep 4 00:00:00 2004 +++ llvm/lib/Target/PowerPC/PowerPC.h Sun Nov 14 14:34:01 2004 @@ -30,6 +30,9 @@ } // end namespace llvm; +// GCC #defines PPC on Linux but we use it as our namespace name +#undef PPC + // Defines symbolic names for PowerPC registers. This defines a mapping from // register name to register number. // From lattner at cs.uiuc.edu Sun Nov 14 14:41:53 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 14:41:53 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/GlobalOpt/load-store-global.llx Message-ID: <200411142041.iAEKfrpF012126@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/GlobalOpt: load-store-global.llx added (r1.1) --- Log message: New testcase. Believe it or not, this happens a LOT in vortex --- Diffs of the changes: (+14 -0) Index: llvm/test/Regression/Transforms/GlobalOpt/load-store-global.llx diff -c /dev/null llvm/test/Regression/Transforms/GlobalOpt/load-store-global.llx:1.1 *** /dev/null Sun Nov 14 14:41:49 2004 --- llvm/test/Regression/Transforms/GlobalOpt/load-store-global.llx Sun Nov 14 14:41:39 2004 *************** *** 0 **** --- 1,14 ---- + ; RUN: llvm-as < %s | opt -globalopt | llvm-dis | not grep G + + %G = internal global int 17 + + void %foo() { + %V = load int* %G + store int %V, int* %G ;; Doesn't change the value + ret void + } + int %bar() { + %X = load int* %G + ret int %X + } + From lattner at cs.uiuc.edu Sun Nov 14 14:50:43 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 14:50:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200411142050.iAEKoh6p012702@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.26 -> 1.27 --- Log message: If a global is just loaded and restored, realize that it is not changing value. This allows us to turn more globals into constants and eliminate them. This patch implements GlobalOpt/load-store-global.llx. Note that this patch speeds up 255.vortex from: Output/255.vortex.out-cbe.time:program 7.640000 Output/255.vortex.out-llc.time:program 9.810000 to: Output/255.vortex.out-cbe.time:program 7.250000 Output/255.vortex.out-llc.time:program 9.490000 Which isn't bad at all! --- Diffs of the changes: (+9 -3) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.26 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.27 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.26 Fri Oct 22 01:43:28 2004 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Sun Nov 14 14:50:30 2004 @@ -155,14 +155,20 @@ // stores. if (GS.StoredType != GlobalStatus::isStored) if (GlobalVariable *GV = dyn_cast(SI->getOperand(1))){ - if (SI->getOperand(0) == GV->getInitializer()) { + Value *StoredVal = SI->getOperand(0); + if (StoredVal == GV->getInitializer()) { + if (GS.StoredType < GlobalStatus::isInitializerStored) + GS.StoredType = GlobalStatus::isInitializerStored; + } else if (isa(StoredVal) && + cast(StoredVal)->getOperand(0) == GV) { + // G = G if (GS.StoredType < GlobalStatus::isInitializerStored) GS.StoredType = GlobalStatus::isInitializerStored; } else if (GS.StoredType < GlobalStatus::isStoredOnce) { GS.StoredType = GlobalStatus::isStoredOnce; - GS.StoredOnceValue = SI->getOperand(0); + GS.StoredOnceValue = StoredVal; } else if (GS.StoredType == GlobalStatus::isStoredOnce && - GS.StoredOnceValue == SI->getOperand(0)) { + GS.StoredOnceValue == StoredVal) { // noop. } else { GS.StoredType = GlobalStatus::isStored; From brukman at cs.uiuc.edu Sun Nov 14 15:02:38 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Sun, 14 Nov 2004 15:02:38 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/GlobalValue.h Message-ID: <200411142102.PAA15812@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: GlobalValue.h updated: 1.18 -> 1.19 --- Log message: Add GhostLinkage for marking functions before they're fully materialized --- Diffs of the changes: (+2 -1) Index: llvm/include/llvm/GlobalValue.h diff -u llvm/include/llvm/GlobalValue.h:1.18 llvm/include/llvm/GlobalValue.h:1.19 --- llvm/include/llvm/GlobalValue.h:1.18 Sun Jul 18 19:55:19 2004 +++ llvm/include/llvm/GlobalValue.h Sun Nov 14 15:02:28 2004 @@ -32,7 +32,8 @@ LinkOnceLinkage, // Keep one copy of named function when linking (inline) WeakLinkage, // Keep one copy of named function when linking (weak) AppendingLinkage, // Special purpose, only applies to global arrays - InternalLinkage // Rename collisions when linking (static functions) + InternalLinkage, // Rename collisions when linking (static functions) + GhostLinkage // Stand-in functions for streaming fns from BC files }; protected: GlobalValue(const Type *Ty, ValueTy vty, LinkageTypes linkage, From brukman at cs.uiuc.edu Sun Nov 14 15:03:06 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Sun, 14 Nov 2004 15:03:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/Reader.cpp Message-ID: <200411142103.PAA15823@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: Reader.cpp updated: 1.137 -> 1.138 --- Log message: Mark an unmaterialized function as having GhostLinkage --- Diffs of the changes: (+4 -0) Index: llvm/lib/Bytecode/Reader/Reader.cpp diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.137 llvm/lib/Bytecode/Reader/Reader.cpp:1.138 --- llvm/lib/Bytecode/Reader/Reader.cpp:1.137 Sun Nov 7 12:20:55 2004 +++ llvm/lib/Bytecode/Reader/Reader.cpp Sun Nov 14 15:02:55 2004 @@ -1735,6 +1735,10 @@ // Save the information for future reading of the function LazyFunctionLoadMap[Func] = LazyFunctionInfo(BlockStart, BlockEnd); + // This function has a body but it's not loaded so it appears `External'. + // Mark it as a `Ghost' instead to notify the users that it has a body. + Func->setLinkage(GlobalValue::GhostLinkage); + // Pretend we've `parsed' this function At = BlockEnd; } From brukman at cs.uiuc.edu Sun Nov 14 15:03:41 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Sun, 14 Nov 2004 15:03:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Message-ID: <200411142103.PAA15839@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCAsmPrinter.cpp updated: 1.66 -> 1.67 --- Log message: Handle GhostLinkage (should not ever reach the assembly printing stage!) --- Diffs of the changes: (+3 -0) Index: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.66 llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.67 --- llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.66 Mon Nov 8 22:01:18 2004 +++ llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Sun Nov 14 15:03:30 2004 @@ -508,6 +508,9 @@ case GlobalValue::InternalLinkage: SwitchSection(O, CurSection, ".data"); break; + case GlobalValue::GhostLinkage: + std::cerr << "Error: unmaterialized (GhostLinkage) function in asm!"; + abort(); } emitAlignment(Align); From brukman at cs.uiuc.edu Sun Nov 14 15:04:00 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Sun, 14 Nov 2004 15:04:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86AsmPrinter.cpp Message-ID: <200411142104.PAA15850@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86AsmPrinter.cpp updated: 1.127 -> 1.128 --- Log message: GhostLinkage should not reach asm printing stage --- Diffs of the changes: (+3 -0) Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.127 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.128 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.127 Sat Nov 13 17:27:11 2004 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Sun Nov 14 15:03:49 2004 @@ -144,6 +144,9 @@ else SwitchSection(O, CurSection, ".data"); break; + case GlobalValue::GhostLinkage: + std::cerr << "GhostLinkage cannot appear in X86AsmPrinter!\n"; + abort(); } emitAlignment(Align); From brukman at cs.uiuc.edu Sun Nov 14 15:04:44 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Sun, 14 Nov 2004 15:04:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Message-ID: <200411142104.PAA15874@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.163 -> 1.164 --- Log message: GhostLinkage not allowed in LLVM AsmWriter, either --- Diffs of the changes: (+6 -0) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.163 llvm/lib/VMCore/AsmWriter.cpp:1.164 --- llvm/lib/VMCore/AsmWriter.cpp:1.163 Sat Oct 16 13:08:06 2004 +++ llvm/lib/VMCore/AsmWriter.cpp Sun Nov 14 15:04:34 2004 @@ -806,6 +806,9 @@ case GlobalValue::WeakLinkage: Out << "weak "; break; case GlobalValue::AppendingLinkage: Out << "appending "; break; case GlobalValue::ExternalLinkage: break; + case GlobalValue::GhostLinkage: + std::cerr << "GhostLinkage not allowed in AsmWriter!\n"; + abort(); } Out << (GV->isConstant() ? "constant " : "global "); @@ -887,6 +890,9 @@ case GlobalValue::WeakLinkage: Out << "weak "; break; case GlobalValue::AppendingLinkage: Out << "appending "; break; case GlobalValue::ExternalLinkage: break; + case GlobalValue::GhostLinkage: + std::cerr << "GhostLinkage not allowed in AsmWriter!\n"; + abort(); } printType(F->getReturnType()) << ' '; From reid at x10sys.com Sun Nov 14 15:46:45 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:46:45 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Linker.h Message-ID: <200411142146.PAA20531@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Linker.h updated: 1.9 -> 1.10 --- Log message: Interface to Linker (revised/expanded from Support/Linker.h) --- Diffs of the changes: (+71 -11) Index: llvm/include/llvm/Linker.h diff -u llvm/include/llvm/Linker.h:1.9 llvm/include/llvm/Linker.h:1.10 --- llvm/include/llvm/Linker.h:1.9 Sun Nov 14 14:21:58 2004 +++ llvm/include/llvm/Linker.h Sun Nov 14 15:46:08 2004 @@ -2,12 +2,12 @@ // // 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 file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// This file defines the interface to the module linker. +// This file defines the interface to the module/file/archive linker. // //===----------------------------------------------------------------------===// @@ -15,19 +15,79 @@ #define LLVM_LINKER_H #include +#include +#include namespace llvm { class Module; -// LinkModules - This function links two modules together, with the resulting -// left module modified to be the composite of the two input modules. If an -// error occurs, true is returned and ErrorMsg (if not null) is set to indicate -// the problem. -// -bool LinkModules(Module *Dest, const Module *Src, std::string *ErrorMsg = 0); - +/// This is the heart of the linker. The \p Src module is linked into the +/// \p Dest module. If an error occurs, true is returned, otherwise false. If +/// \p ErrorMsg is not null and an error occurs, \p *ErrorMsg will be set to a +/// readable string that indicates the nature of the error. +/// @returns true if there's an error +/// @brief Link two modules together +bool LinkModules( + Module* Dest, ///< Module into which \p Src is linked + const Module* Src, ///< Module linked into \p Dest + std::string* ErrorMsg ///< Optional error message string +); + +/// This function links the bytecode \p Files into the \p HeadModule. No +/// matching of symbols is done. It simply calls loads each module and calls +/// LinkModules for each one. +/// @returns true if an error occurs, false otherwise +bool LinkFiles ( + const char * progname, ///< Name of the program being linked (for output) + Module * HeadModule, ///< Main (resulting) module to be linked into + const std::vector & Files, ///< Files to link in + bool Verbose ///< Link verbosely, indicating each action +); + +/// This function links one archive, \p Filename, that contains bytecode into +/// \p HeadModule. If an error occurs, true is returned, otherwise false. If +/// \p ErrorMsg is not null and an error occurs, \p *ErrorMsg will be set to a +/// readable string that indicates the nature of the error. +/// @returns true if there's an error +/// @brief Link in one archive. +bool LinkInArchive( + Module* HeadModule, ///< Main (resulting) module to be linked into + const std::string& Filename, ///< Filename of the archive to link + std::string* ErrorMsg, ///< Error message if an error occurs. + bool Verbose ///< Link verbosely, indicating each action +); + +/// This function provides the ability to handle the -L and -l options on a +/// linker's command line. It will link into \p HeadModule any modules found in +/// the \p Libraries (which might be found in the \p LibPaths). +/// @brief Link libraries into a module +void LinkLibraries ( + const char * progname, ///< Name of the program being linked (for output) + Module* HeadModule, ///< Main (resulting) module to be linked into + const std::vector & Libraries, ///< Set of libraries to link in + const std::vector & LibPaths, ///< Set of library paths + bool Verbose, ///< Link verbosely, indicating each action + bool Native ///< Linking is for a native executable +); + +/// This function looks at Module \p M and returns a set of strings, +/// \p DefinedSymbols, that is the publicly visible defined symbols in +/// module \p M. +void GetAllDefinedSymbols (Module *M, std::set &DefinedSymbols); + +/// This function looks at Module \p M and returns a set of strings, +/// \p UnefinedSymbols, that is the publicly visible undefined symbols in +/// module \p M. +void GetAllUndefinedSymbols(Module *M, std::set &UndefinedSymbols); + +/// This function looks through a set of \p Paths to find a library with the +/// name \p Filename. If \p SharedObjectOnly is true, it only finds a match +/// if the file is a shared library. +std::string FindLib(const std::string &Filename, + const std::vector &Paths, + bool SharedObjectOnly = false); + } // End llvm namespace #endif - From reid at x10sys.com Sun Nov 14 15:47:33 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:47:33 -0600 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200411142147.PAA20567@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.234 -> 1.235 --- Log message: Add a command for using llvm-ar correctly. --- Diffs of the changes: (+1 -0) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.234 llvm/Makefile.rules:1.235 --- llvm/Makefile.rules:1.234 Thu Nov 11 20:27:36 2004 +++ llvm/Makefile.rules Sun Nov 14 15:46:55 2004 @@ -281,6 +281,7 @@ Burg = $(BURG) -I $(BUILD_SRC_DIR) TableGen = $(TBLGEN) -I $(BUILD_SRC_DIR) Archive = $(AR) $(AR.Flags) +LArchive = $(ToolDir)/llvm-ar rcsf ifdef RANLIB Ranlib = $(RANLIB) else From reid at x10sys.com Sun Nov 14 15:48:19 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:48:19 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Bytecode/Archive.h Message-ID: <200411142148.PAA20599@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Bytecode: Archive.h updated: 1.4 -> 1.5 --- Log message: Complete rewrite to get first working version. --- Diffs of the changes: (+411 -193) Index: llvm/include/llvm/Bytecode/Archive.h diff -u llvm/include/llvm/Bytecode/Archive.h:1.4 llvm/include/llvm/Bytecode/Archive.h:1.5 --- llvm/include/llvm/Bytecode/Archive.h:1.4 Sat Nov 6 02:53:59 2004 +++ llvm/include/llvm/Bytecode/Archive.h Sun Nov 14 15:47:41 2004 @@ -7,130 +7,309 @@ // //===----------------------------------------------------------------------===// // -// This header file defines the interface to LLVM Archive files. The interface -// is provided by the Archive class implemented by the lib/Bytecode/Archive -// library. This library is used to read and write archive (*.a) files that -// contain LLVM bytecode files (or others). It provides rudimentary capabilities -// to construct an archive file from a set of files, read the archive members -// into memory, search the archive for member files that fulfill unresolved -// symbols, and extract the archive back to the file system. Full -// symbol table support is provided for loading only those files that resolve -// symbols. Note that read performance of this library is _crucial_ for -// performance of JIT type applications and the linkers. Consequently, the -// library is optimized for reading. +// This header file declares the Archive and ArchiveMember classes that provide +// manipulation of LLVM Archive files. The implementation is provided by the +// lib/Bytecode/Archive library. This library is used to read and write +// archive (*.a) files that contain LLVM bytecode files (or others). // //===----------------------------------------------------------------------===// #ifndef LLVM_BYTECODE_ARCHIVE_H #define LLVM_BYTECODE_ARCHIVE_H +#include "llvm/ADT/ilist" #include "llvm/System/Path.h" +#include "llvm/System/MappedFile.h" #include +#include +#include namespace llvm { -class ModuleProvider; -class Module; +// Forward declare classes +class ModuleProvider; // From VMCore +class Module; // From VMCore +class Archive; // Declared below +class ArchiveMemberHeader; // Internal implementation class + +/// This class is the main class manipulated by users of the Archive class. It +/// holds information about one member of the Archive. It is also the element +/// stored by the Archive's ilist, the Archive's main abstraction. Because of +/// the special requirements of archive files, users are not permitted to +/// construct ArchiveMember instances. You should obtain them from the methods +/// of the Archive class instead. +/// @brief This class represents a single archive member. +class ArchiveMember { -/// This class represents an archive file. It abstracts away the file format, -/// and logical operations that can be done on an archive file. It also provides -/// utilities for controlling the runtime loading/reading of the archive file -/// to provide efficient access mechanisms for JIT systems and linkers. + /// @name Types + /// @{ + public: + /// These flags are used internally by the archive member to specify various + /// characteristics of the member. The various "is" methods below provide + /// access to the flags. The flags are not user settable. + enum Flags { + CompressedFlag = 1, ///< Member is a normal compressed file + ForeignSymbolTableFlag = 2, ///< Member is a foreign symbol table + LLVMSymbolTableFlag = 4, ///< Member is an LLVM symbol table + BytecodeFlag = 8, ///< Member is uncompressed bytecode + CompressedBytecodeFlag = 16, ///< Member is compressed bytecode + HasPathFlag = 32, ///< Member has a full or partial path + HasLongFilenameFlag = 64, ///< Member uses the long filename syntax + StringTableFlag = 256, ///< Member is an ar(1) format string table + }; + + /// @} + /// @name Accessors + /// @{ + public: + /// @returns the parent Archive instance + /// @brief Get the archive associated with this member + Archive* getArchive() const { return parent; } + + /// @returns the path to the Archive's file + /// @brief Get the path to the archive member + const sys::Path& getPath() const { return path; } + + /// The "user" is the owner of the file per Unix security. This may not + /// have any applicability on non-Unix systems but is a required component + /// of the "ar" file format. + /// @brief Get the user associated with this archive member. + unsigned getUser() const { return info.user; } + + /// The "group" is the owning group of the file per Unix security. This + /// may not have any applicability on non-Unix systems but is a required + /// component of the "ar" file format. + /// @brief Get the group associated with this archive member. + unsigned getGroup() const { return info.group; } + + /// The "mode" specifies the access permissions for the file per Unix + /// security. This may not have any applicabiity on non-Unix systems but is + /// a required component of the "ar" file format. + /// @brief Get the permission mode associated with this archive member. + unsigned getMode() const { return info.mode; } + + /// This method returns the time at which the archive member was last + /// modified when it was not in the archive. + /// @brief Get the time of last modification of the archive member. + sys::TimeValue getModTime() const { return info.modTime; } + + /// @returns the size of the archive member in bytes. + /// @brief Get the size of the archive member. + unsigned getSize() const { return info.fileSize; } + + /// This method returns the total size of the archive member as it + /// appears on disk. This includes the file content, the header, the + /// long file name if any, and the padding. + /// @brief Get total on-disk member size. + unsigned getMemberSize() const; + + /// This method will return a pointer to the in-memory content of the + /// archive member, if it is available. If the data has not been loaded + /// into memory, the return value will be null. + /// @returns a pointer to the member's data. + /// @brief Get the data content of the archive member + const void* getData() const { return data; } + + /// This method determines if the member is a regular compressed file. Note + /// that compressed bytecode files will yield "false" for this method. + /// @see isCompressedBytecode() + /// @returns true iff the archive member is a compressed regular file. + /// @brief Determine if the member is a compressed regular file. + bool isCompressed() const { return flags&CompressedFlag; } + + /// @returns true iff the member is a foreign (non-LLVM) symbol table + /// @brief Determine if this member is a foreign symbol table. + bool isForeignSymbolTable() const { return flags&ForeignSymbolTableFlag; } + + /// @returns true iff the archive member is the LLVM symbol table + /// @brief Determine if this member is the LLVM symbol table. + bool isLLVMSymbolTable() const { return flags&LLVMSymbolTableFlag; } + + /// @returns true iff the archive member is the ar(1) string table + /// @brief Determine if this member is the ar(1) string table. + bool isStringTable() const { return flags&StringTableFlag; } + + /// @returns true iff the archive member is an uncompressed bytecode file. + /// @brief Determine if this member is a bytecode file. + bool isBytecode() const { return flags&BytecodeFlag; } + + /// @returns true iff the archive member is a compressed bytecode file. + /// @brief Determine if the member is a compressed bytecode file. + bool isCompressedBytecode() const { return flags&CompressedBytecodeFlag;} + + /// @returns true iff the file name contains a path (directory) component. + /// @brief Determine if the member has a path + bool hasPath() const { return flags&HasPathFlag; } + + /// Long filenames are an artifact of the ar(1) file format which allows + /// up to sixteen characters in its header and doesn't allow a path + /// separator character (/). To avoid this, a "long format" member name is + /// allowed that doesn't have this restriction. This method determines if + /// that "long format" is used for this member. + /// @returns true iff the file name uses the long form + /// @brief Determin if the member has a long file name + bool hasLongFilename() const { return flags&HasLongFilenameFlag; } + + /// This method returns the status info (like Unix stat(2)) for the archive + /// member. The status info provides the file's size, permissions, and + /// modification time. The contents of the Path::StatusInfo structure, other + /// than the size and modification time, may not have utility on non-Unix + /// systems. + /// @returns the status info for the archive member + /// @brief Obtain the status info for the archive member + const sys::Path::StatusInfo& getStatusInfo() const { return info; } + + /// This method causes the archive member to be replaced with the contents + /// of the file specified by \p File. The contents of \p this will be + /// updated to reflect the new data from \p File. The \p File must exist and + /// be readable on entry to this method. + /// @brief Replace contents of archive member with a new file. + void replaceWith(const sys::Path& aFile); + + /// @} + /// @name ilist methods - do not use + /// @{ + public: + const ArchiveMember *getNext() const { return next; } + const ArchiveMember *getPrev() const { return prev; } + ArchiveMember *getNext() { return next; } + ArchiveMember *getPrev() { return prev; } + void setPrev(ArchiveMember* p) { prev = p; } + void setNext(ArchiveMember* n) { next = n; } + + /// @} + /// @name Data + /// @{ + private: + ArchiveMember* next; ///< Pointer to next archive member + ArchiveMember* prev; ///< Pointer to previous archive member + Archive* parent; ///< Pointer to parent archive + sys::Path path; ///< Path of file containing the member + sys::Path::StatusInfo info; ///< Status info (size,mode,date) + unsigned flags; ///< Flags about the archive member + const void* data; ///< Data for the member + + /// @} + /// @name Constructors + /// @{ + public: + /// The default constructor is only used by the Archive's iplist when it + /// constructs the list's sentry node. + ArchiveMember(); + + private: + /// Used internally by the Archive class to construct an ArchiveMember. + /// The contents of the ArchiveMember are filled out by the Archive class. + ArchiveMember( Archive* PAR ); + + // So Archive can construct an ArchiveMember + friend class llvm::Archive; + /// @} +}; + +/// This class defines the interface to LLVM Archive files. The Archive class +/// presents the archive file as an ilist of ArchiveMember objects. The members +/// can be rearranged in any fashion either by directly editing the ilist or by +/// using editing methods on the Archive class (recommended). The Archive +/// class also provides several ways of accessing the archive file for various +/// purposes such as editing and linking. Full symbol table support is provided +/// for loading only those files that resolve symbols. Note that read +/// performance of this library is _crucial_ for performance of JIT type +/// applications and the linkers. Consequently, the implementation of the class +/// is optimized for reading. class Archive { /// @name Types /// @{ public: - /// The user's interface to the archive symbol table. This multimap allows - /// symbols to be looked up and modules to be instantiated from the file - /// lazily via the ModuleProvider::materializeModule method. - typedef std::map SymTab; + /// This is the ilist type over which users may iterate to examine + /// the contents of the archive + /// @brief The ilist type of ArchiveMembers that Archive contains. + typedef iplist MembersList; + + /// @brief Forward mutable iterator over ArchiveMember + typedef MembersList::iterator iterator; - /// This typedef is just shorthand for a vector of Path names - typedef std::vector PathList; + /// @brief Forward immutable iterator over ArchiveMember + typedef MembersList::const_iterator const_iterator; - /// This typedef is just shorthand for a vector of Modules - typedef std::vector ModuleList; + /// @brief Reverse mutable iterator over ArchiveMember + typedef std::reverse_iterator reverse_iterator; + + /// @brief Reverse immutable iterator over ArchiveMember + typedef std::reverse_iterator const_reverse_iterator; + + /// @brief The in-memory version of the symbol table + typedef std::map SymTabType; + + /// @} + /// @name ilist interface methods + /// @{ + public: + inline iterator begin() { return members.begin(); } + inline const_iterator begin() const { return members.begin(); } + inline iterator end () { return members.end(); } + inline const_iterator end () const { return members.end(); } + + inline reverse_iterator rbegin() { return members.rbegin(); } + inline const_reverse_iterator rbegin() const { return members.rbegin(); } + inline reverse_iterator rend () { return members.rend(); } + inline const_reverse_iterator rend () const { return members.rend(); } + + inline unsigned size() const { return members.size(); } + inline bool empty() const { return members.empty(); } + inline const ArchiveMember& front() const { return members.front(); } + inline ArchiveMember& front() { return members.front(); } + inline const ArchiveMember& back() const { return members.back(); } + inline ArchiveMember& back() { return members.back(); } /// @} /// @name Constructors /// @{ public: - /// Create an empty archive file, \p Filename. The returned Archive object - /// will have no file members and an empty symbol table. The actual archive - /// file is not created until the returned Archive object is destructed. - /// @throws std::string if an error occurs + /// Create an empty archive file and associate it with the \p Filename. This + /// method does not actually create the archive disk file. It creates an + /// empty Archive object. If the writeToDisk method is called, the archive + /// file \p Filename will be created at that point, with whatever content + /// the returned Archive object has at that time. /// @returns An Archive* that represents the new archive file. - /// @brief Create an empty archive file. + /// @brief Create an empty Archive. static Archive* CreateEmpty( - const sys::Path& Filename ///< Name of archive file + const sys::Path& Filename ///< Name of the archive to (eventually) create. ); -#if 0 - -This interface severely complicates the -Archive class. Its commented out until -a final determination is made of whether -we will support adding modules or not. - - /// Create a new archive file, \p Filename, from the LLVM modules \p Modules. - /// The module's externally visible linkage symbols will be added to the - /// archive's symbol table. The names of the file members will be obtained - /// from the Module::getModuleId() method. If that name is not unique, it will - /// be made unique by appending a monotonically increasing integer to it. If - /// \p StripName is non-empty, it specifies a prefix to be stripped from the - /// name of the file members. This allows archives with relative path names - /// to be created. The actual archive file is not created until the - /// returned Archive object is destructed. - /// @returns An Archive* that that represents the newly created archive file. - /// @throws std::string if an error occurs - /// @brief Create an archive file from modules. - static Archive* CreateFromModules( - const sys::Path& Filename, ///< Name of archive file - const ModuleList& Modules, ///< Modules to be put in archive - const std::string& StripName="" ///< Prefix to strip from member names - ); -#endif - - /// Create a new archive file, \p Filename, from a set of existing \p Files. - /// Each entry in \p Files will be added to the archive. If any file is an - /// llvm bytecode file, its externally visible linkage symbols will be added - /// to the archive's symbol table. If any of the paths in \p Files refer to - /// directories, those directories will be ignored. Full path names to - /// files must be provided. However, if \p StripName is non-empty, it - /// specifies a prefix string to be removed from each path before it is - /// written as the name of the file member. Any path names that do not have - /// the \p StripName as a prefix will be saved with the full path name - /// provided in \p Files. This permits archives relative to a top level - /// directory to be created. - /// @throws std::string if an error occurs - /// @brief Create an archive file from files. - static Archive* CreateFromFiles( - const sys::Path& Filename, ///< Name of archive file - const PathList& Files, ///< File paths to be put in archive - const std::string& StripName="" ///< Prefix path name to strip from names + /// Open an existing archive and load its contents in preparation for + /// editing. After this call, the member ilist is completely populated based + /// on the contents of the archive file. You should use this form of open if + /// you intend to modify the archive or traverse its contents (e.g. for + /// printing). + /// @brief Open and load an archive file + static Archive* OpenAndLoad(const sys::Path& filePath); + + /// This method opens an existing archive file from \p Filename and reads in + /// its symbol table without reading in any of the archive's members. This + /// reduces both I/O and cpu time in opening the archive if it is to be used + /// solely for symbol lookup (e.g. during linking). The \p Filename must + /// exist and be an archive file or an exception will be thrown. This form + /// of opening the archive is intended for read-only operations that need to + /// locate members via the symbol table for link editing. Since the archve + /// members are not read by this method, the archive will appear empty upon + /// return. If editing operations are performed on the archive, they will + /// completely replace the contents of the archive! It is recommended that + /// if this form of opening the archive is used that only the symbol table + /// lookup methods (getSymbolTable, findModuleDefiningSymbol, and + /// findModulesDefiningSymbols) be used. + /// @throws std::string if an error occurs opening the file + /// @returns an Archive* that represents the archive file. + /// @brief Open an existing archive and load its symbols. + static Archive* OpenAndLoadSymbols( + const sys::Path& Filename ///< Name of the archive file to open ); - /// Open an existing archive file from \p Filename. The necessary - /// arrangements to read the file are made, but nothing much is actually - /// read from the file. Use the Accessor methods below to lazily obtain - /// those portions of the file that are of interest. - /// @throws std::string if an error occurs - /// @brief Open an existing archive. - static Archive* Open( - const sys::Path& Filename ///< Name of the archive file - ); - - /// This destructor "finalizes" the archive. Regardless of whether the - /// archive was created or opened, all memory associated with the archive - /// is released, including any SymTab* returned by the getSymbolTable() - /// method, any ModuleProviders and their associated Modules returned by - /// any interface method, etc. Additionally, if the archive was created - /// using one of the Create* methods, the archive is written to disk in - /// its final format. After this method exits, none of the memory - /// associated with the archive is valid. It is the user's responsibility - /// to ensure that all references to such memory is removed before the - /// Archive is destructed. + /// This destructor cleans up the Archive object, releases all memory, and + /// closes files. It does nothing with the archive file on disk. If you + /// haven't used the writeToDisk method by the time the destructor is + /// called, all changes to the archive will be lost. /// @throws std::string if an error occurs /// @brief Destruct in-memory archive ~Archive(); @@ -139,6 +318,48 @@ /// @name Accessors /// @{ public: + /// @returns the path to the archive file. + /// @brief Get the archive path. + const sys::Path& getPath() { return archPath; } + + /// This method is provided so that editing methods can be invoked directly + /// on the Archive's iplist of ArchiveMember. However, it is recommended + /// that the usual STL style iterator interface be used instead. + /// @returns the iplist of ArchiveMember + /// @brief Get the iplist of the members + MembersList& getMembers() { return members; } + + /// This method allows direct query of the Archive's symbol table. The + /// symbol table is a std::map of std::string (the symbol) to unsigned (the + /// file offset). Note that for efficiency reasons, the offset stored in + /// the symbol table is not the actual offset. It is the offset from the + /// beginning of the first "real" file member (after the symbol table). Use + /// the getFirstFileOffset() to obtain that offset and add this value to the + /// offset in the symbol table to obtain the real file offset. Note that + /// there is purposefully no interface provided by Archive to look up + /// members by their offset. Use the findModulesDefiningSymbols and + /// findModuleDefiningSymbol methods instead. + /// @returns the Archive's symbol table. + /// @brief Get the archive's symbol table + const SymTabType& getSymbolTable() { return symTab; } + + /// This method returns the offset in the archive file to the first "real" + /// file member. Archive files, on disk, have a signature and might have a + /// symbol table that precedes the first actual file member. This method + /// allows you to determine what the size of those fields are. + /// @returns the offset to the first "real" file member in the archive. + /// @brief Get the offset to the first "real" file member in the archive. + unsigned getFirstFileOffset() { return firstFileOffset; } + + /// This method will scan the archive for bytecode modules, interpret them + /// and return a vector of the instantiated modules in \p Modules. If an + /// error occurs, this method will return true. If \p ErrMessage is not null + /// and an error occurs, \p *ErrMessage will be set to a string explaining + /// the error that occurred. + /// @returns true if an error occurred + /// @brief Instantiate all the bytecode modules located in the archive + bool getAllModules(std::vector& Modules, std::string* ErrMessage); + /// This accessor looks up the \p symbol in the archive's symbol table and /// returns the associated module that defines that symbol. This method can /// be called as many times as necessary. This is handy for linking the @@ -147,124 +368,123 @@ /// caller. It is managed internally by the Archive class. It is possible /// that multiple calls to this accessor will return the same ModuleProvider /// instance because the associated module defines multiple symbols. - /// @throws std::string if an error occurs /// @returns The ModuleProvider* found or null if the archive does not /// contain a module that defines the \p symbol. /// @brief Look up a module by symbol name. - ModuleProvider* findModuleContainingSymbol( + ModuleProvider* findModuleDefiningSymbol( const std::string& symbol ///< Symbol to be sought - ) const; - - /// Return the list of all the \p Paths for the file members in the archive. - /// This is handy for generating the table of contents of the archive. Note - /// that \p Paths is *not* cleared before it is populated. New entries are - /// appended to the end of the PathList. - /// @throw std::string if an error occurs - /// @returns nothing - /// @brief Get all the paths in the archive - void getAllPaths( - PathList& Paths ///< The list of paths returned ); - /// This method returns a caller readable SymTab object which is a map - /// of symbol names to ModuleProviders. Callers can traverse this symbol - /// table, look up specific symbols, etc. and materialize any Modules they - /// want with the associated ModuleProviders. It is unnecessary to call - /// this accessor more than once as the same object is alway returned, even - /// if changes have been made. - /// @returns a constant SymTab* that is the same for every invocation. The - /// caller should not attempt to free or modify this SymTab object, just use - /// it. - /// @brief Get the archive's symbol table. - const SymTab* getSymbolTable(); - - /// Extract the contents of the archive back to the file system using \p - /// RootDir as the directory at the root of the extraction. Each file - /// member is written back as a separate file. If \p flat is false, then - /// directories are created as necessary to restore the files to the correct - /// sub-directory of \p root as specified in the full path of the file - /// member. Otherwise, paths are ignored and all file members will be - /// extracted to the \p root directory using only the filename portion of - /// the path (directories ignored). If \p symtab is true, the archive's - /// symbol table will also be extracted to a file named __SYMTAB. - /// @returns nothing - /// @throws std::string if an error occurs - /// @brief Extract archive contents to a file. - void extractAllToDirectory( - const sys::Path& RootDir, ///< The root directory for extraction - bool Flat = true, ///< false = recreate directory structure - bool Symtab = false ///< true = extract symbol table too - ); - - /// Extract one file in the archive back to the file system using \p RootDir - /// as the directory at the root of the extraction. The file \p name is - /// extracted and placed into \p RootDir. If \p Flat is false, then any - /// intermediate directory names in the file member's path will also be - /// created. Otherwise, the member's file is created in RootDir ignoring - /// the leading path and using only the member's file name. - /// @throws std::string if an error occurs. - /// @returns nothing - /// @brief Extract a single archive file. - void extractOneFileToDirectory( - const sys::Path& RootDir, ///< The root directory for extraction - const sys::Path& name, ///< Name of file to extract - bool Flat = true ///< false = recreate directories + /// This method is similar to findModuleDefiningSymbol but allows lookup of + /// more than one symbol at a time. If \p symbols contains a list of + /// undefined symbols in some module, then calling this method is like + /// making one complete pass through the archive to resolve symbols but is + /// more efficient than looking at the individual members. + /// @brief Look up multiple symbols in the archive. + void findModulesDefiningSymbols( + const std::set& symbols, ///< Symbols to be sought + std::set& modules ///< The modules matching \p symbols ); /// @} /// @name Mutators /// @{ public: - /// Each entry in \p Files will be added to the archive. If any file is an - /// llvm bytecode file, its externally visible linkage symbols will be added - /// to the archive's symbol table. If any of the paths in \p Files refer to - /// directories, those directories will be ignored. Full path names to - /// files must be provided. However, if \p StripName is non-empty, it - /// specifies a prefix string to be removed from each path before it is - /// written as the name of the file member. Any path names that do not have - /// the \p StripName as a prefix will be saved with the full path name - /// provided. This permits archives relative to a top level directory - /// to be created. + /// This method is the only way to get the archive written to disk. It + /// creates or overwrites the file specified when \p this was created + /// or opened. The arguments provide options for writing the archive. If + /// \p CreateSymbolTable is true, the archive is scanned for bytecode files + /// and a symbol table of the externally visible function and global + /// variable names is created. If \p TruncateNames is true, the names of the + /// archive members will have their path component stripped and the file + /// name will be truncated at 15 characters. If \p Compress is specified, + /// all archive members will be compressed before being written. If + /// \p PrintSymTab is true, the symbol table will be printed to std::cout. /// @throws std::string if an error occurs - /// @returns nothing - /// @brief Add a set of files to the archive. - void addFiles( - const PathList& Files, ///< The names of files to add to archive - const std::string& StripName="" ///< Prefix path to strip from names + /// @brief Write (possibly modified) archive contents to disk + void writeToDisk( + bool CreateSymbolTable=false, ///< Create Symbol table + bool TruncateNames=false, ///< Truncate the filename to 15 chars + bool Compress=false, ///< Compress files + bool PrintSymTab=false ///< Dump symtab to std::out if created ); -#if 0 - -This interface severely complicates the -Archive class. Its commented out until -a final determination is made of whether -we will support adding modules or not. - - /// Add a set of Modules to the archive. Names of member files will - /// be taken from the Module identifier (Module::getModuleIdentifier) if it - /// is unique. Non-unique member names will be made unique by appending a - /// number. The symbol table will be augmented with the global symbols of - /// all the modules provided. If \p StripName is non-empty, it - /// specifies a prefix string to be removed from each moduleId before it is - /// written as the name of the file member. Any path names that do not have - /// the \p StripName as a prefix will be saved with the full path name - /// provided. This permits archives relative to a top level directory to - /// be created. - /// @throws std::string if an error occurs + /// This method adds a new file to the archive. The \p filename is examined + /// to determine just enough information to create an ArchiveMember object + /// which is then inserted into the Archive object's ilist at the location + /// given by \p where. + /// @throws std::string if an error occurs reading the \p filename. /// @returns nothing - /// @brief Add a set of modules to the archive. - void addModules( - const ModuleList& Modules, ///< The modules to add to the archive - const std::string& StripName="" ///< Prefix path to strip from names - ); -#endif + /// @brief Add a file to the archive. + void addFileBefore(const sys::Path& filename, iterator where); + + /// This method moves a \p target member to a new location in the archive, + /// just before the member given by \p iterator. When the archive is + /// written, \p target will be written in its new location. + /// @brief Move a member to a new location + void moveMemberBefore(iterator target, iterator where); + + /// This method removes a \p target member from the archive. When the + /// archive is written, it will no longer contain \p target. The associated + /// ArchiveMember is deleted. + /// @brief Remove a member. + void remove(iterator target); + + /// @} + /// @name Implementation + /// @{ + private: + /// @brief Construct an Archive for \p filename and optionally map it + /// into memory. + Archive(const sys::Path& filename, bool map = false ); + + /// @brief Parse the symbol table at \p data. + void parseSymbolTable(const void* data,unsigned len); + + /// @brief Parse the header of a member starting at \p At + ArchiveMember* parseMemberHeader(const char*&At,const char*End); + + /// @brief Check that the archive signature is correct + void checkSignature(); + + /// @brief Load the entire archive. + void loadArchive(); + + /// @brief Load just the symbol table. + void loadSymbolTable(); + + /// @brief Write the symbol table to an ofstream. + void writeSymbolTable(std::ofstream& ARFile,bool PrintSymTab); + + /// @brief Write one ArchiveMember to an ofstream. + void writeMember(const ArchiveMember& member, std::ofstream& ARFile, + bool CreateSymbolTable, bool TruncateNames, bool ShouldCompress); + + /// @brief Fill in an ArchiveMemberHeader from ArchiveMember. + bool fillHeader(const ArchiveMember&mbr, + ArchiveMemberHeader& hdr,int sz, bool TruncateNames) const; + + /// This type is used to keep track of bytecode modules loaded from the + /// symbol table. It maps the file offset to a pair that consists of the + /// associated ArchiveMember and the ModuleProvider. + /// @brief Module mapping type + typedef std::map > + ModuleMap; /// @} /// @name Data /// @{ private: - class ArchiveInternals; - ArchiveInternals* impl; ///< Implementation class + sys::Path archPath; ///< Path to the archive file we read/write + MembersList members; ///< The ilist of ArchiveMember + sys::MappedFile* mapfile; ///< Raw Archive contents mapped into memory + const char* base; ///< Base of the memory mapped file data + SymTabType symTab; ///< The symbol table + std::string strtab; ///< The string table for long file names + unsigned symTabSize; ///< Size in bytes of symbol table + unsigned firstFileOffset; ///< Offset to first normal file. + ModuleMap modules; ///< The modules loaded via symbol lookup. + /// @} /// @name Hidden /// @{ @@ -277,6 +497,4 @@ } // End llvm namespace -// vim: sw=2 ai - #endif From reid at x10sys.com Sun Nov 14 15:49:05 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:49:05 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Bytecode/Reader.h Message-ID: <200411142149.PAA20664@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Bytecode: Reader.h updated: 1.20 -> 1.21 --- Log message: Remove ReadArchiveFile (functionality moved to Archive.h). Add an alternate form for GetBytecodeSymbols. --- Diffs of the changes: (+10 -9) Index: llvm/include/llvm/Bytecode/Reader.h diff -u llvm/include/llvm/Bytecode/Reader.h:1.20 llvm/include/llvm/Bytecode/Reader.h:1.21 --- llvm/include/llvm/Bytecode/Reader.h:1.20 Sat Nov 6 02:54:47 2004 +++ llvm/include/llvm/Bytecode/Reader.h Sun Nov 14 15:48:27 2004 @@ -72,15 +72,16 @@ bool GetBytecodeSymbols(const sys::Path& fileName, std::vector& syms); -/// Read bytecode files from the specfied archive (.a) file, convert them -/// to Module* and provide them in the \p Objects argument. If an error -/// occurs, ErrorStr (if non-null) will be set to a string explaining -/// the error. -/// @return true on error, false on success. -/// @brief Get a vector of Module* from a bytecode archive file -bool ReadArchiveFile(const std::string &Filename, - std::vector &Objects, - std::string *ErrorStr = 0); +/// This function will read only the necessary parts of a bytecode buffer in +/// order to obtain a list of externally visible global symbols that the +/// bytecode module defines. This is used for archiving and linking when only +/// the list of symbols the module defines is needed and the bytecode is +/// already in memory. +/// @returns true on success, false if the bytecode can't be parsed +/// @brief Get a bytecode file's externally visibile defined global symbols. +bool llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length, + const std::string& ModuleID, + std::vector& symbols); } // End llvm namespace From reid at x10sys.com Sun Nov 14 15:49:51 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:49:51 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/CommandLine.h Message-ID: <200411142149.PAA20731@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: CommandLine.h updated: 1.37 -> 1.38 --- Log message: Add the MoreHelp function pointer. If non-null, this specifies a function to be called to print out additional help information --- Diffs of the changes: (+8 -0) Index: llvm/include/llvm/Support/CommandLine.h diff -u llvm/include/llvm/Support/CommandLine.h:1.37 llvm/include/llvm/Support/CommandLine.h:1.38 --- llvm/include/llvm/Support/CommandLine.h:1.37 Wed Oct 27 11:14:51 2004 +++ llvm/include/llvm/Support/CommandLine.h Sun Nov 14 15:49:13 2004 @@ -1046,6 +1046,14 @@ void apply(alias &A) const { A.setAliasFor(Opt); } }; +/// Permit the tool to provide additional help output after the normal +/// help output. To use this, create a function that returns void and +/// takes no arguments. Assign its address to cl::MoreHelp. If set, +/// this function will be called just before the CommandLine exits +/// after printing the help. +/// @brief Optional pointer to additional help function +extern void (*MoreHelp)(); + } // End namespace cl } // End namespace llvm From reid at x10sys.com Sun Nov 14 15:50:37 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:50:37 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/Compressor.h Message-ID: <200411142150.PAA20792@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: Compressor.h updated: 1.2 -> 1.3 --- Log message: Add higher level interface to simplify use of Compressor --- Diffs of the changes: (+88 -13) Index: llvm/include/llvm/Support/Compressor.h diff -u llvm/include/llvm/Support/Compressor.h:1.2 llvm/include/llvm/Support/Compressor.h:1.3 --- llvm/include/llvm/Support/Compressor.h:1.2 Mon Oct 4 12:29:25 2004 +++ llvm/include/llvm/Support/Compressor.h Sun Nov 14 15:50:00 2004 @@ -15,6 +15,7 @@ #define LLVM_SUPPORT_COMPRESSOR_H #include "llvm/Support/DataTypes.h" +#include namespace llvm { @@ -43,20 +44,83 @@ COMP_TYPE_BZIP2 = '2', ///< Use bzip2 algorithm (preferred) }; - /// A callback function type used by the Compressor to get the next chunk - /// of data to which (de)compressed output will be written. This function - /// must be written by the caller to provide the buffering of the output - /// data. + /// @} + /// @name High Level Interface + /// @{ + public: + /// This method compresses a block of memory pointed to by \p in with + /// size \p size to a block of memory, \p out, that is allocated with + /// malloc. It is the caller's responsibility to free \p out. The \p hint + /// indicates which type of compression the caller would *prefer*. + /// @throws std::string explaining error if a compression error occurs + /// @returns The size of the output buffer \p out. + /// @brief Compress memory to a new memory buffer. + static uint64_t compressToNewBuffer( + const char* in, ///< The buffer to be compressed + unsigned size, ///< The size of the buffer to be compressed + char*&out, ///< The returned output buffer + Algorithm hint ///< Hint for type of compression to perform + = COMP_TYPE_BZIP2 + ); + + /// This method compresses a block of memory pointed to by \p in with + /// size \p size to a stream. The stream \p out must be open and ready for + /// writing when this method is called. The stream will not be closed by + /// this method. The \p hint argument indicates which type of + /// compression the caller would *prefer*. + /// @returns The amount of data written to \p out. + /// @brief Compress memory to a file. + static uint64_t compressToStream( + const char*in, ///< The buffer to be compressed + unsigned size, ///< The size of the buffer to be compressed + std::ostream& out, ///< The output stream to write data on + Algorithm hint ///< Hint for type of compression to perform + = COMP_TYPE_BZIP2 + ); + + /// This method decompresses a block of memory pointed to by \p in with + /// size \p size to a new block of memory, \p out, \p that was allocated + /// by malloc. It is the caller's responsibility to free \p out. + /// @returns The size of the output buffer \p out. + /// @brief Decompress memory to a new memory buffer. + static uint64_t decompressToNewBuffer( + const char *in, ///< The buffer to be decompressed + unsigned size, ///< Size of the buffer to be decompressed + char*&out ///< The returned output buffer + ); + + /// This method decompresses a block of memory pointed to by \p in with + /// size \p size to a stream. The stream \p out must be open and ready for + /// writing when this method is called. The stream will not be closed by + /// this method. + /// @returns The amount of data written to \p out. + /// @brief Decompress memory to a stream. + static uint64_t decompressToStream( + const char *in, ///< The buffer to be decompressed + unsigned size, ///< Size of the buffer to be decompressed + std::ostream& out ///< The stream to write write data on + ); + + /// @} + /// @name Low Level Interface + /// @{ + public: + /// A callback function type used by the Compressor's low level interface + /// to get the next chunk of data to which (de)compressed output will be + /// written. This callback completely abstracts the notion of how to + /// handle the output data of compression or decompression. The callback + /// is responsible for determining both the storage location and the size + /// of the output. The callback may also do other things with the data + /// such as write it, transmit it, etc. Note that providing very small + /// values for \p size will make the compression run very inefficiently. + /// It is recommended that \p size be chosen based on the some multiple or + /// fraction of the object being decompressed or compressed, respetively. /// @returns 0 for success, 1 for failure /// @throws nothing /// @brief Output callback function type typedef unsigned (OutputDataCallback)(char*& buffer, unsigned& size, void* context); - /// @} - /// @name Methods - /// @{ - public: /// This function does the compression work. The block of memory starting /// at \p in and extending for \p size bytes is compressed. The compressed /// output is written to memory blocks returned by the \p cb callback. The @@ -72,9 +136,15 @@ /// @throws std::string if an error occurs /// @returns the total size of the compressed data /// @brief Compress a block of memory. - static uint64_t compress(char* in, unsigned size, OutputDataCallback* cb, - Algorithm hint = COMP_TYPE_BZIP2, - void* context = 0); + static uint64_t compress( + const char* in, ///< The buffer to be compressed + unsigned size, ///< The size of the buffer to be compressed + OutputDataCallback* cb, ///< Call back for memory allocation + Algorithm hint ///< Hint for type of compression to perform + = COMP_TYPE_BZIP2, + void* context ///< Context for callback + = 0 + ); /// This function does the decompression work. The block of memory /// starting at \p in and extending for \p size bytes is decompressed. The @@ -89,8 +159,13 @@ /// @throws std::string if an error occurs /// @returns the total size of the decompressed data /// @brief Decompress a block of memory. - static uint64_t decompress(char *in, unsigned size, - OutputDataCallback* cb, void* context = 0); + static uint64_t decompress( + const char *in, ///< The buffer to be decompressed + unsigned size, ///< Size of the buffer to be decompressed + OutputDataCallback* cb, ///< Call back for memory allocation + void* context ///< Context for callback + = 0 + ); /// @} }; From llvm at cs.uiuc.edu Sun Nov 14 15:51:28 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Sun, 14 Nov 2004 15:51:28 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/Linker.h Message-ID: <200411142151.PAA20830@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: Linker.h (r1.8) removed --- Log message: Linker is its own module now. Moved to include/llvm/Linker.h --- Diffs of the changes: (+0 -0) From reid at x10sys.com Sun Nov 14 15:52:14 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:52:14 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/System/MappedFile.h Message-ID: <200411142152.PAA20853@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: MappedFile.h updated: 1.3 -> 1.4 --- Log message: Allow explicit closing of the MappedFile, before destruction --- Diffs of the changes: (+2 -0) Index: llvm/include/llvm/System/MappedFile.h diff -u llvm/include/llvm/System/MappedFile.h:1.3 llvm/include/llvm/System/MappedFile.h:1.4 --- llvm/include/llvm/System/MappedFile.h:1.3 Wed Oct 27 11:14:51 2004 +++ llvm/include/llvm/System/MappedFile.h Sun Nov 14 15:51:36 2004 @@ -121,6 +121,8 @@ /// @brief Set the size of the file and memory mapping. void size(size_t new_size); + void close() { terminate(); } + /// @} /// @name Implementation /// @{ From reid at x10sys.com Sun Nov 14 15:53:00 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:53:00 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/System/Path.h Message-ID: <200411142153.PAA20880@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: Path.h updated: 1.8 -> 1.9 --- Log message: *Put the StatusInfo type in the right section. *Provide the ability to rename a file.*Provide the ability to get/set stat(2) information.*Provide the ability to identify LLVM file types. --- Diffs of the changes: (+72 -19) Index: llvm/include/llvm/System/Path.h diff -u llvm/include/llvm/System/Path.h:1.8 llvm/include/llvm/System/Path.h:1.9 --- llvm/include/llvm/System/Path.h:1.8 Tue Nov 9 14:26:31 2004 +++ llvm/include/llvm/System/Path.h Sun Nov 14 15:52:22 2004 @@ -43,6 +43,26 @@ /// @since 1.4 /// @brief An abstraction for operating system paths. class Path { + /// @name Types + /// @{ + public: + typedef std::vector Vector; + + /// This structure provides basic file system information about a file. + /// The structure is filled in by the getStatusInfo method. + /// @brief File status structure + struct StatusInfo { + StatusInfo() : modTime(0,0) { fileSize=0; mode=0; user=0; group=0; } + size_t fileSize; ///< Size of the file in bytes + TimeValue modTime; ///< Time of file's modification + uint32_t mode; ///< Mode of the file, if applicable + uint32_t user; ///< User ID of owner, if applicable + uint32_t group; ///< Group ID of owner, if applicable + bool isDir; ///< True if this is a directory. + }; + + + /// @} /// @name Constructors /// @{ public: @@ -125,7 +145,7 @@ static std::string GetDLLSuffix(); /// This is one of the very few ways in which a path can be constructed - /// with a syntactically invalid name. The only *legal* invalid name is an + /// with a syntactically invalid name. The only *legal* invalid name is an /// empty one. Other invalid names are not permitted. Empty paths are /// provided so that they can be used to indicate null or error results in /// other lib/System functionality. @@ -235,6 +255,14 @@ /// @brief Determine if file has a specific magic number bool hasMagicNumber(const std::string& magic) const; + /// This function retrieves the first \p len bytes of the file associated + /// with \p this. These bytes are returned as the "magic number" in the + /// \p Magic parameter. + /// @returns true if the Path is a file and the magic number is retrieved, + /// false otherwise. + /// @brief Get the file's magic number. + bool getMagicNumber(std::string& Magic, unsigned len) const; + /// This function determines if the path name in the object references an /// archive file by looking at its magic number. /// @returns true if the file starts with the magic number for an archive @@ -307,25 +335,15 @@ /// @brief Get the base name of the path std::string getBasename() const; - /// This structure provides basic file system information about a file. - /// The structure is filled in by the getStatusInfo method. - /// @brief File status structure - struct StatusInfo { - StatusInfo() : modTime(0,0) { fileSize=0; mode=0; user=0; group=0; } - size_t fileSize; ///< Size of the file in bytes - TimeValue modTime; ///< Time of file's modification - uint64_t mode; ///< Mode of the file, if applicable - uint64_t user; ///< User ID of owner, if applicable - uint64_t group; ///< Group ID of owner, if applicable - }; - - /// This function returns status information about the file. - /// @returns nothing - /// @throws std::string if an error occurs. - /// @brief Get file status. - void getStatusInfo(StatusInfo& stat) const; + /// This function builds a list of paths that are the names of the + /// files and directories in a directory. + /// @returns false if \p this is not a directory, true otherwise + /// @throws std::string if the directory cannot be searched + /// @brief Build a list of directory's contents. + bool getDirectoryContents(Vector& paths) const; - /// @returns a c string containing the path name. + /// Obtain a 'C' string for the path name. + /// @returns a 'C' string containing the path name. /// @brief Returns the path as a C string. const char* const c_str() const { return path.c_str(); } @@ -339,6 +357,14 @@ /// valid path being found. void clear() { path.clear(); } + /// This function returns status information about the file. The type of + /// path (file or directory) is updated to reflect the actual contents + /// of the file system. + /// @returns nothing + /// @throws std::string if an error occurs. + /// @brief Get file status. + void getStatusInfo(StatusInfo& stat); + /// This method attempts to set the Path object to \p unverified_path /// and interpret the name as a directory name. The \p unverified_path /// is verified. If verification succeeds then \p unverified_path @@ -476,6 +502,20 @@ /// @brief Destroy the file this Path refers to. bool destroyFile(); + /// This method renames the file referenced by \p this as \p newName. Both + /// files must exist before making this call. + /// @returns false if the Path does not refer to a file, true otherwise. + /// @throws std::string if there is an file system error. + /// @brief Rename one file as another. + bool renameFile(const Path& newName); + + /// This method sets the access time, modification time, and permission + /// mode of the file associated with \p this as given by \p si. + /// @returns false if the Path does not refer to a file, true otherwise. + /// @throws std::string if the file could not be modified + /// @brief Set file times and mode. + bool setStatusInfo(const StatusInfo& si ) const ; + /// @} /// @name Data /// @{ @@ -484,7 +524,20 @@ /// @} }; + + /// This enumeration delineates the kinds of files that LLVM knows about. + enum LLVMFileType { + UnknownFileType = 0, ///< Unrecognized file + BytecodeFileType = 1, ///< Uncompressed bytecode file + CompressedBytecodeFileType = 2, ///< Compressed bytecode file + ArchiveFileType = 3, ///< ar style archive file + }; + + /// This utility function allows any memory block to be examined in order + /// to determine its file type. + LLVMFileType IdentifyFileType(const char*magic, unsigned length); } + } // vim: sw=2 From reid at x10sys.com Sun Nov 14 15:53:46 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:53:46 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/System/Signals.h Message-ID: <200411142153.PAA20914@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: Signals.h updated: 1.12 -> 1.13 --- Log message: Make the remove*OnSignal functions deal with Paths not strings --- Diffs of the changes: (+2 -2) Index: llvm/include/llvm/System/Signals.h diff -u llvm/include/llvm/System/Signals.h:1.12 llvm/include/llvm/System/Signals.h:1.13 --- llvm/include/llvm/System/Signals.h:1.12 Sun Aug 29 14:19:07 2004 +++ llvm/include/llvm/System/Signals.h Sun Nov 14 15:53:09 2004 @@ -23,13 +23,13 @@ /// This function registers signal handlers to ensure that if a signal gets /// delivered that the named file is removed. /// @brief Remove a file if a fatal signal occurs. - void RemoveFileOnSignal(const std::string &Filename); + void RemoveFileOnSignal(const Path &Filename); /// This function registers a signal handler to ensure that if a fatal signal /// gets delivered to the process that the named directory and all its /// contents are removed. /// @brief Remove a directory if a fatal signal occurs. - void RemoveDirectoryOnSignal(const llvm::sys::Path& path); + void RemoveDirectoryOnSignal(const Path& path); /// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the /// process, print a stack trace and then exit. From reid at x10sys.com Sun Nov 14 15:54:32 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:54:32 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/System/TimeValue.h Message-ID: <200411142154.PAA20951@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: TimeValue.h updated: 1.7 -> 1.8 --- Log message: *Make naming convention consistent.*Add convertion to/from Unix Epoch time.*Add ability to convert to readable string. --- Diffs of the changes: (+16 -4) Index: llvm/include/llvm/System/TimeValue.h diff -u llvm/include/llvm/System/TimeValue.h:1.7 llvm/include/llvm/System/TimeValue.h:1.8 --- llvm/include/llvm/System/TimeValue.h:1.7 Tue Nov 9 14:29:10 2004 +++ llvm/include/llvm/System/TimeValue.h Sun Nov 14 15:53:55 2004 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/DataTypes.h" +#include #ifndef LLVM_SYSTEM_TIMEVALUE_H #define LLVM_SYSTEM_TIMEVALUE_H @@ -238,16 +239,22 @@ /// Converts the TimeValue into the corresponding number of "ticks" for /// Posix, correcting for the difference in Posix zero time. /// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970) - uint64_t ToPosixTime( void ) const { + uint64_t toPosixTime( void ) const { uint64_t result = seconds_ - PosixZeroTime.seconds_; result += nanos_ / NANOSECONDS_PER_POSIX_TICK; return result; } + /// Converts the TimeValue into the corresponding number of seconds + /// since the epoch (00:00:00 Jan 1,1970). + uint64_t toEpochTime(void) const { + return seconds_ - PosixZeroTime.seconds_; + } + /// Converts the TiemValue into the correspodning number of "ticks" for /// Win32 platforms, correcting for the difference in Win32 zero time. /// @brief Convert to windows time (seconds since 12:00:00a Jan 1, 1601) - uint64_t ToWin32Time( void ) const { + uint64_t toWin32Time( void ) const { uint64_t result = seconds_ - Win32ZeroTime.seconds_; result += nanos_ / NANOSECONDS_PER_WIN32_TICK; return result; @@ -256,11 +263,16 @@ /// Provides the seconds and nanoseconds as results in its arguments after /// correction for the Posix zero time. /// @brief Convert to timespec time (ala POSIX.1b) - void GetTimespecTime( uint64_t& seconds, uint32_t& nanos ) const { + void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const { seconds = seconds_ - PosixZeroTime.seconds_; nanos = nanos_; } + /// Provides conversion of the TimeValue into a readable time & date. + /// @returns std::string containing the readable time value + /// @brief Convert time to a string. + std::string toString(); + /// @} /// @name Mutators /// @{ @@ -318,7 +330,7 @@ /// Converts the \p seconds argument from PosixTime to the corresponding /// TimeValue and assigns that value to \p this. /// @brief Convert seconds form PosixTime to TimeValue - void fromPosixTime( SecondsType seconds ) { + void fromEpochTime( SecondsType seconds ) { seconds_ = seconds + PosixZeroTime.seconds_; nanos_ = 0; this->normalize(); From reid at x10sys.com Sun Nov 14 15:55:18 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:55:18 -0600 Subject: [llvm-commits] CVS: llvm/lib/Makefile Message-ID: <200411142155.PAA20983@zion.cs.uiuc.edu> Changes in directory llvm/lib: Makefile updated: 1.19 -> 1.20 --- Log message: Add the Linker library --- Diffs of the changes: (+1 -1) Index: llvm/lib/Makefile diff -u llvm/lib/Makefile:1.19 llvm/lib/Makefile:1.20 --- llvm/lib/Makefile:1.19 Tue Sep 14 20:34:42 2004 +++ llvm/lib/Makefile Sun Nov 14 15:54:41 2004 @@ -9,7 +9,7 @@ LEVEL = .. PARALLEL_DIRS = VMCore Analysis Transforms AsmParser Bytecode CodeGen Target \ - ExecutionEngine Debugger + ExecutionEngine Debugger Linker include $(LEVEL)/Makefile.common From reid at x10sys.com Sun Nov 14 15:56:04 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:56:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Makefile Message-ID: <200411142156.PAA21004@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode: Makefile updated: 1.5 -> 1.6 --- Log message: Add the Archive library --- Diffs of the changes: (+1 -1) Index: llvm/lib/Bytecode/Makefile diff -u llvm/lib/Bytecode/Makefile:1.5 llvm/lib/Bytecode/Makefile:1.6 --- llvm/lib/Bytecode/Makefile:1.5 Fri Oct 15 18:22:15 2004 +++ llvm/lib/Bytecode/Makefile Sun Nov 14 15:55:27 2004 @@ -8,7 +8,7 @@ ##===----------------------------------------------------------------------===## LEVEL = ../.. -PARALLEL_DIRS = Reader Writer +PARALLEL_DIRS = Reader Writer Archive include $(LEVEL)/Makefile.common From reid at x10sys.com Sun Nov 14 15:56:50 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:56:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Archive/Archive.cpp Message-ID: <200411142156.PAA21029@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Archive: Archive.cpp updated: 1.1 -> 1.2 --- Log message: First working version --- Diffs of the changes: (+128 -2) Index: llvm/lib/Bytecode/Archive/Archive.cpp diff -u llvm/lib/Bytecode/Archive/Archive.cpp:1.1 llvm/lib/Bytecode/Archive/Archive.cpp:1.2 --- llvm/lib/Bytecode/Archive/Archive.cpp:1.1 Sat Nov 6 02:51:45 2004 +++ llvm/lib/Bytecode/Archive/Archive.cpp Sun Nov 14 15:56:13 2004 @@ -7,18 +7,144 @@ // //===----------------------------------------------------------------------===// // -// Builds up standard unix archive files (.a) containing LLVM bytecode. +// This file contains the implementation of the Archive and ArchiveMember +// classes that is common to both reading and writing archives.. // //===----------------------------------------------------------------------===// #include "ArchiveInternals.h" +#include "llvm/ModuleProvider.h" using namespace llvm; -Archive::Archive() { +// getMemberSize - compute the actual physical size of the file member as seen +// on disk. This isn't the size of member's payload. Use getSize() for that. +unsigned +ArchiveMember::getMemberSize() const { + // Basically its the file size plus the header size + unsigned result = info.fileSize + sizeof(ArchiveMemberHeader); + + // If it has a long filename, include the name length + if (hasLongFilename()) + result += path.get().length() + 1; + + // If its now odd lengthed, include the padding byte + if (result % 2 != 0 ) + result++; + + return result; +} + +// This default constructor is only use by the ilist when it creates its +// sentry node. We give it specific static values to make it stand out a bit. +ArchiveMember::ArchiveMember() + : next(0), prev(0), parent(0), path(""), flags(0), data(0) +{ + info.user = 1000; + info.group = 1000; + info.mode = 0777; + info.fileSize = 0; + info.modTime = sys::TimeValue::now(); +} + +// This is the constructor that the Archive class uses when it is building or +// reading an archive. It just defaults a few things and ensures the parent is +// set for the iplist. The Archive class fills in the ArchiveMember's data. +// This is required because correctly setting the data may depend on other +// things in the Archive. +ArchiveMember::ArchiveMember(Archive* PAR) + : next(0), prev(0), parent(PAR), path(), flags(0), data(0) +{ +} + +// This method allows an ArchiveMember to be replaced with the data for a +// different file, presumably as an update to the member. It also makes sure +// the flags are reset correctly. +void ArchiveMember::replaceWith(const sys::Path& newFile) { + assert(newFile.exists() && "Can't replace with a non-existent file"); + data = 0; + path = newFile; + + // Foreign symbol tables have an empty name + if (path.get() == ARFILE_SYMTAB_NAME) + flags |= ForeignSymbolTableFlag; + else + flags &= ~ForeignSymbolTableFlag; + + // LLVM symbol tables have a very specific name + if (path.get() == ARFILE_LLVM_SYMTAB_NAME) + flags |= LLVMSymbolTableFlag; + else + flags &= ~LLVMSymbolTableFlag; + + // String table name + if (path.get() == ARFILE_STRTAB_NAME) + flags |= StringTableFlag; + else + flags &= ~StringTableFlag; + + // If it has a slash then it has a path + bool hasSlash = path.get().find('/') != std::string::npos; + if (hasSlash) + flags |= HasPathFlag; + else + flags &= ~HasPathFlag; + + // If it has a slash or its over 15 chars then its a long filename format + if (hasSlash || path.get().length() > 15) + flags |= HasLongFilenameFlag; + else + flags &= ~HasLongFilenameFlag; + + // Get the signature and status info + std::string magic; + const char* signature = (const char*) data; + if (!signature) { + path.getMagicNumber(magic,4); + signature = magic.c_str(); + path.getStatusInfo(info); + } + + // Determine what kind of file it is + switch (sys::IdentifyFileType(signature,4)) { + case sys::BytecodeFileType: + flags |= BytecodeFlag; + break; + case sys::CompressedBytecodeFileType: + flags |= CompressedBytecodeFlag; + flags &= ~CompressedFlag; + break; + default: + flags &= ~(BytecodeFlag|CompressedBytecodeFlag); + break; + } +} + +// Archive constructor - this is the only constructor that gets used for the +// Archive class. Everything else (default,copy) is deprecated. This just +// initializes and maps the file into memory, if requested. +Archive::Archive(const sys::Path& filename, bool map ) + : archPath(filename), members(), mapfile(0), base(0), symTab(), symTabSize(0) +{ + if (map) { + mapfile = new sys::MappedFile(filename); + base = (char*) mapfile->map(); + } } +// Archive destructor - just clean up memory Archive::~Archive() { + // Shutdown the file mapping + if (mapfile) { + mapfile->unmap(); + delete mapfile; + } + // Delete any ModuleProviders and ArchiveMember's we've allocated as a result + // of symbol table searches. + for (ModuleMap::iterator I=modules.begin(), E=modules.end(); I != E; ++I ) { + delete I->second.first; + delete I->second.second; + } } // vim: sw=2 ai From reid at x10sys.com Sun Nov 14 15:57:36 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:57:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Archive/ArchiveWriter.cpp Message-ID: <200411142157.PAA21054@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Archive: ArchiveWriter.cpp updated: 1.1 -> 1.2 --- Log message: First working version --- Diffs of the changes: (+362 -220) Index: llvm/lib/Bytecode/Archive/ArchiveWriter.cpp diff -u llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.1 llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.2 --- llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.1 Sat Nov 6 02:51:45 2004 +++ llvm/lib/Bytecode/Archive/ArchiveWriter.cpp Sun Nov 14 15:56:59 2004 @@ -1,284 +1,426 @@ -//===-- ArchiveWriter.cpp - LLVM archive writing --------------------------===// +//===-- ArchiveWriter.cpp - Write LLVM archive files ----------------------===// // // The LLVM Compiler Infrastructure // -// This file was developed by Reid Spencerand is distributed under the +// This file was developed by Reid Spencer and is distributed under the // University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// Builds up standard unix archive files (.a) containing LLVM bytecode. +// Builds up an LLVM archive file (.a) containing LLVM bytecode. // //===----------------------------------------------------------------------===// #include "ArchiveInternals.h" -#include "llvm/Module.h" #include "llvm/Bytecode/Reader.h" #include "llvm/Support/FileUtilities.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/System/MappedFile.h" +#include "llvm/Support/Compressor.h" +#include "llvm/System/Signals.h" #include #include +#include using namespace llvm; +namespace { + +// Write an integer using variable bit rate encoding. This saves a few bytes +// per entry in the symbol table. +inline void writeInteger(unsigned num, std::ofstream& ARFile) { + while (1) { + if (num < 0x80) { // done? + ARFile << (unsigned char)num; + return; + } + + // Nope, we are bigger than a character, output the next 7 bits and set the + // high bit to say that there is more coming... + ARFile << (unsigned char)(0x80 | ((unsigned char)num & 0x7F)); + num >>= 7; // Shift out 7 bits now... + } +} + +// Compute how many bytes are taken by a given VBR encoded value. This is needed +// to pre-compute the size of the symbol table. +inline unsigned numVbrBytes(unsigned num) { + if (num < 128) // 2^7 + return 1; + if (num < 16384) // 2^14 + return 2; + if (num < 2097152) // 2^21 + return 3; + if (num < 268435456) // 2^28 + return 4; + return 5; // anything >= 2^28 takes 5 bytes +} + +} + +// Create an empty archive. Archive* -Archive::CreateEmpty(const sys::Path& Filename) { - Archive* result = new Archive; - Archive::ArchiveInternals* impl = result->impl = new Archive::ArchiveInternals; - impl->fname = Filename; +Archive::CreateEmpty(const sys::Path& FilePath ) { + Archive* result = new Archive(FilePath,false); return result; } -Archive* -Archive::CreateFromFiles( - const sys::Path& Filename, - const PathList& Files, - const std::string& StripName -) { - Archive* result = new Archive; - Archive::ArchiveInternals* impl = result->impl = new Archive::ArchiveInternals; - impl->fname = Filename; +bool +Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr, + int sz, bool TruncateNames) const { + + // Set the permissions mode, uid and gid + hdr.init(); + char buffer[32]; + sprintf(buffer, "%-8o", mbr.getMode()); + memcpy(hdr.mode,buffer,8); + sprintf(buffer, "%-6u", mbr.getUser()); + memcpy(hdr.uid,buffer,6); + sprintf(buffer, "%-6u", mbr.getGroup()); + memcpy(hdr.gid,buffer,6); + + // Set the size field + if (sz < 0 ) { + buffer[0] = '-'; + sprintf(&buffer[1],"%-9u",(unsigned)-sz); + } else { + sprintf(buffer, "%-10u", (unsigned)sz); + } + memcpy(hdr.size,buffer,10); - try { - size_t strip_len = StripName.length(); - for (PathList::const_iterator P = Files.begin(), E = Files.end(); P != E ;++P) - { - if (P->readable()) { - std::string name(P->get()); - if (strip_len > 0 && StripName == name.substr(0,strip_len)) { - name.erase(0,strip_len); - } - if (P->isBytecodeFile()) { - std::vector syms; - if (!GetBytecodeSymbols(*P, syms)) - throw std::string("Can not get symbols from: ") + P->get(); - impl->addFileMember(*P, name, &syms); - } else { - impl->addFileMember(*P, name); - } - } - else - throw std::string("Can not read: ") + P->get(); + // Set the last modification date + uint64_t secondsSinceEpoch = mbr.getModTime().toEpochTime(); + sprintf(buffer,"%-12u", unsigned(secondsSinceEpoch)); + memcpy(hdr.date,buffer,12); + + // Set the name field in one of its various flavors. + bool writeLongName = false; + const std::string& mbrPath = mbr.getPath().get(); + if (mbr.isStringTable()) { + memcpy(hdr.name,ARFILE_STRTAB_NAME,16); + } else if (mbr.isForeignSymbolTable()) { + memcpy(hdr.name,ARFILE_SYMTAB_NAME,16); + } else if (mbr.isLLVMSymbolTable()) { + memcpy(hdr.name,ARFILE_LLVM_SYMTAB_NAME,16); + } else if (TruncateNames) { + const char* nm = mbrPath.c_str(); + unsigned len = mbrPath.length(); + size_t slashpos = mbrPath.rfind('/'); + if (slashpos != std::string::npos) { + nm += slashpos + 1; + len -= slashpos +1; } + if (len >15) + len = 15; + mbrPath.copy(hdr.name,len); + hdr.name[len] = '/'; + } else if (mbrPath.length() < 16 && mbrPath.find('/') == std::string::npos) { + mbrPath.copy(hdr.name,mbrPath.length()); + hdr.name[mbrPath.length()] = '/'; + } else { + std::string nm = "#1/"; + nm += utostr(mbrPath.length()); + nm.copy(hdr.name,nm.length()); + writeLongName = true; + } + return writeLongName; +} - // Now that we've collected everything, write the archive - impl->writeArchive(); +void +Archive::addFileBefore(const sys::Path& filePath, iterator where) { + assert(filePath.exists() && "Can't add a non-existent file"); - } catch(...) { - delete impl; - result->impl = 0; - delete result; - throw; - } + ArchiveMember* mbr = new ArchiveMember(this); - return result; + mbr->data = 0; + mbr->path = filePath; + mbr->path.getStatusInfo(mbr->info); + + unsigned flags = 0; + bool hasSlash = filePath.get().find('/') != std::string::npos; + if (hasSlash) + flags |= ArchiveMember::HasPathFlag; + if (hasSlash || filePath.get().length() > 15) + flags |= ArchiveMember::HasLongFilenameFlag; + std::string magic; + mbr->path.getMagicNumber(magic,4); + switch (sys::IdentifyFileType(magic.c_str(),4)) { + case sys::BytecodeFileType: + flags |= ArchiveMember::BytecodeFlag; + break; + case sys::CompressedBytecodeFileType: + flags |= ArchiveMember::CompressedBytecodeFlag; + break; + default: + break; + } + mbr->flags = flags; + members.insert(where,mbr); } void -Archive::ArchiveInternals::addFileMember( - const sys::Path& filePath, - const std::string& memberName, - const StrTab* symbols -) { - MemberInfo info; - info.path = filePath; - info.name = memberName; - filePath.getStatusInfo(info.status); - if (symbols) - info.symbols = *symbols; - info.offset = 0; - members.push_back(info); +Archive::moveMemberBefore(iterator target, iterator where) { + assert(target != end() && "Target iterator for moveMemberBefore is invalid"); + ArchiveMember* mbr = members.remove(target); + members.insert(where, mbr); } void -Archive::ArchiveInternals::writeInteger(int num, std::ofstream& ARFile) { - char buff[4]; - buff[0] = (num >> 24) & 255; - buff[1] = (num >> 16) & 255; - buff[2] = (num >> 8) & 255; - buff[3] = num & 255; - ARFile.write(buff, sizeof(buff)); +Archive::remove(iterator target) { + assert(target != end() && "Target iterator for remove is invalid"); + ArchiveMember* mbr = members.remove(target); + delete mbr; } - void -Archive::ArchiveInternals::writeSymbolTable( std::ofstream& ARFile ) { - - // Compute the number of symbols in the symbol table and the - // total byte size of the string pool. While we're traversing, - // build the string pool for supporting long file names. Also, - // build the table of file offsets for the symbol table and - // the - typedef std::map SymbolMap; - StrTab stringPool; - SymbolMap symbolTable; - std::vector fileOffsets; - std::string symTabStrings; - unsigned fileOffset = 0; - unsigned spOffset = 0; - unsigned numSymbols = 0; - unsigned numSymBytes = 0; - for (unsigned i = 0; i < members.size(); i++ ) { - MemberInfo& mi = members[i]; - StrTab& syms = mi.symbols; - size_t numSym = syms.size(); - numSymbols += numSym; - for (unsigned j = 0; j < numSym; j++ ) { - numSymBytes += syms[j].size() + 1; - symbolTable[syms[i]] = i; - } - if (mi.name.length() > 15 || std::string::npos != mi.name.find('/')) { - stringPool.push_back(mi.name + "/\n"); - mi.name = std::string("/") + utostr(spOffset); - spOffset += mi.name.length() + 2; - } else if (mi.name[mi.name.length()-1] != '/') { - mi.name += "/"; +Archive::writeMember( + const ArchiveMember& member, + std::ofstream& ARFile, + bool CreateSymbolTable, + bool TruncateNames, + bool ShouldCompress +) { + + unsigned filepos = ARFile.tellp(); + filepos -= 8; + + // Get the data and its size either from the + // member's in-memory data or directly from the file. + size_t fSize = member.getSize(); + const char* data = (const char*)member.getData(); + sys::MappedFile* mFile = 0; + if (!data) { + mFile = new sys::MappedFile(member.getPath()); + data = (const char*) mFile->map(); + fSize = mFile->size(); + } + + // Now that we have the data in memory, update the + // symbol table if its a bytecode file. + if (CreateSymbolTable && + (member.isBytecode() || member.isCompressedBytecode())) { + std::vector symbols; + GetBytecodeSymbols((const unsigned char*)data,fSize,member.getPath().get(), + symbols); + for (std::vector::iterator SI = symbols.begin(), + SE = symbols.end(); SI != SE; ++SI) { + + std::pair Res = + symTab.insert(std::make_pair(*SI,filepos)); + + if (Res.second) { + symTabSize += SI->length() + + numVbrBytes(SI->length()) + + numVbrBytes(filepos); + } } - fileOffsets.push_back(fileOffset); - fileOffset += sizeof(ArchiveMemberHeader) + mi.status.fileSize; } + // Determine if we actually should compress this member + bool willCompress = + (ShouldCompress && + !member.isForeignSymbolTable() && + !member.isLLVMSymbolTable() && + !member.isCompressed() && + !member.isCompressedBytecode()); + + // Perform the compression. Note that if the file is uncompressed bytecode + // then we turn the file into compressed bytecode rather than treating it as + // compressed data. This is necessary since it allows us to determine that the + // file contains bytecode instead of looking like a regular compressed data + // member. A compressed bytecode file has its content compressed but has a + // magic number of "llvc". This acounts for the +/-4 arithmetic in the code + // below. + int hdrSize; + if (willCompress) { + char* output = 0; + if (member.isBytecode()) { + data +=4; + fSize -= 4; + } + fSize = Compressor::compressToNewBuffer( + data,fSize,output,Compressor::COMP_TYPE_ZLIB); + data = output; + if (member.isBytecode()) + hdrSize = -fSize-4; + else + hdrSize = -fSize; + } else { + hdrSize = fSize; + } - // Compute the size of the symbol table file member - unsigned symTabSize = 0; - if (numSymbols != 0) - symTabSize = - sizeof(ArchiveMemberHeader) + // Size of the file header - 4 + // Size of "number of entries" - (4 * numSymbols) + // Size of member file indices - numSymBytes; // Size of the string table - - // Compute the size of the string pool - unsigned strPoolSize = 0; - if (spOffset != 0 ) - strPoolSize = - sizeof(ArchiveMemberHeader) + // Size of the file header - spOffset; // Number of bytes in the string pool - - // Compute the byte index offset created by symbol table and string pool - unsigned firstFileOffset = symTabSize + strPoolSize; - - // Create header for symbol table. This must be first if there is - // a symbol table and must have a special name. - if ( symTabSize > 0 ) { - ArchiveMemberHeader Hdr; - Hdr.init(); - - // Name of symbol table is '/ ' but "" is passed in - // because the setName method always terminates with a / - Hdr.setName(ARFILE_SYMTAB_NAME); - Hdr.setDate(); - Hdr.setSize(symTabSize - sizeof(ArchiveMemberHeader)); - Hdr.setMode(0); - Hdr.setUid(0); - Hdr.setGid(0); - - // Write header to archive file - ARFile.write((char*)&Hdr, sizeof(Hdr)); - - // Write the number of entries in the symbol table - this->writeInteger(numSymbols, ARFile); + // Compute the fields of the header + ArchiveMemberHeader Hdr; + bool writeLongName = fillHeader(member,Hdr,hdrSize,TruncateNames); - // Write the file offset indices for each symbol and build the - // symbol table string pool - std::string symTabStrPool; - symTabStrPool.reserve(256 * 1024); // Reserve 256KBytes for symbols - for (SymbolMap::iterator I = symbolTable.begin(), E = symbolTable.end(); - I != E; ++I ) { - this->writeInteger(firstFileOffset + fileOffsets[I->second], ARFile); - symTabStrPool += I->first; - symTabStrPool += "\0"; - } + // Write header to archive file + ARFile.write((char*)&Hdr, sizeof(Hdr)); - // Write the symbol table's string pool - ARFile.write(symTabStrPool.data(), symTabStrPool.size()); + // Write the long filename if its long + if (writeLongName) { + ARFile << member.getPath().c_str(); + ARFile << '\n'; } - //============== DONE WITH SYMBOL TABLE + // Make sure we write the compressed bytecode magic number if we should. + if (willCompress && member.isBytecode()) + ARFile.write("llvc",4); + + // Write the (possibly compressed) member's content to the file. + ARFile.write(data,fSize); + + // Make sure the member is an even length + if (ARFile.tellp() % 2 != 0) + ARFile << ARFILE_PAD; + + // Free the compressed data, if necessary + if (willCompress) { + free((void*)data); + } - if (strPoolSize > 0) { - // Initialize the header for the string pool - ArchiveMemberHeader Hdr; - Hdr.init(); - Hdr.setName(ARFILE_STRTAB_NAME); - Hdr.setDate(); - Hdr.setSize(spOffset); - Hdr.setMode(0); - Hdr.setUid(0); - Hdr.setGid(0); - - // Write the string pool header - ARFile.write((char*)&Hdr, sizeof(Hdr)); - - // Write the string pool - for (unsigned i = 0; i < stringPool.size(); i++) { - ARFile.write(stringPool[i].data(), stringPool[i].size()); - } + // Close the mapped file if it was opened + if (mFile != 0) { + mFile->unmap(); + delete mFile; } } void -Archive::ArchiveInternals::writeMember( - const MemberInfo& member, - std::ofstream& ARFile -) { +Archive::writeSymbolTable(std::ofstream& ARFile,bool PrintSymTab ) { - // Map the file into memory. We do this early for two reasons. First, - // if there's any kind of error, we want to know about it. Second, we - // want to ensure we're using the most recent size for this file. - sys::MappedFile mFile(member.path); - mFile.map(); - - // Header for the archive member + // Construct the symbol table's header ArchiveMemberHeader Hdr; Hdr.init(); + memcpy(Hdr.name,ARFILE_LLVM_SYMTAB_NAME,16); + uint64_t secondsSinceEpoch = sys::TimeValue::now().toEpochTime(); + char buffer[32]; + sprintf(buffer,"%-12u", unsigned(secondsSinceEpoch)); + memcpy(Hdr.date,buffer,12); + sprintf(buffer,"%-10u",symTabSize); + memcpy(Hdr.size,buffer,10); - // Set the name. If its longer than 15 chars, it will have already - // been reduced by the writeSymbolTable. - Hdr.setName(member.name); - - // Set the other header members - Hdr.setSize( mFile.size() ); - Hdr.setMode( member.status.mode); - Hdr.setUid ( member.status.user); - Hdr.setGid ( member.status.group); - Hdr.setDate( member.status.modTime.ToPosixTime() ); - - // Write header to archive file + // Write the header ARFile.write((char*)&Hdr, sizeof(Hdr)); - - //write to archive file - ARFile.write(mFile.charBase(),mFile.size()); - mFile.unmap(); + // Save the starting position of the symbol tables data content. + unsigned startpos = ARFile.tellp(); + + // Print the symbol table header if we're supposed to + if (PrintSymTab) + std::cout << "Symbol Table:\n"; + + // Write out the symbols sequentially + for ( Archive::SymTabType::iterator I = symTab.begin(), E = symTab.end(); + I != E; ++I) + { + // Write out the file index + writeInteger(I->second, ARFile); + // Write out the length of the symbol + writeInteger(I->first.length(), ARFile); + // Write out the symbol + ARFile.write(I->first.data(), I->first.length()); + + // Print this entry to std::cout if we should + if (PrintSymTab) { + unsigned filepos = I->second + symTabSize + sizeof(ArchiveMemberHeader) + + (symTabSize % 2 != 0) + 8; + std::cout << " " << std::setw(9) << filepos << "\t" << I->first << "\n"; + } + } + + // Now that we're done with the symbol table, get the ending file position + unsigned endpos = ARFile.tellp(); + + // Make sure that the amount we wrote is what we pre-computed. This is + // critical for file integrity purposes. + assert(endpos - startpos == symTabSize && "Invalid symTabSize computation"); + + // Make sure the symbol table is even sized + if (symTabSize % 2 != 0 ) + ARFile << ARFILE_PAD; } void -Archive::ArchiveInternals::writeArchive() { +Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, + bool Compress, bool PrintSymTab) { - // Create archive file for output. - std::ofstream ArchiveFile(fname.get().c_str()); + // Make sure they haven't opened up the file, not loaded it, + // but are now trying to write it which would wipe out the file. + assert(!(members.empty() && mapfile->size() > 8)); + + // Create a temporary file to store the archive in + sys::Path TmpArchive = archPath; + TmpArchive.createTemporaryFile(); + + // Make sure the temporary gets removed if we crash + sys::RemoveFileOnSignal(TmpArchive); + + // Ensure we can remove the temporary even in the face of an exception + try { + // Create archive file for output. + std::ofstream ArchiveFile(TmpArchive.c_str()); - // Check for errors opening or creating archive file. - if ( !ArchiveFile.is_open() || ArchiveFile.bad() ) { - throw std::string("Error opening archive file: ") + fname.get(); - } + // Check for errors opening or creating archive file. + if ( !ArchiveFile.is_open() || ArchiveFile.bad() ) { + throw std::string("Error opening archive file: ") + archPath.get(); + } - // Write magic string to archive. - ArchiveFile << ARFILE_MAGIC; + // If we're creating a symbol table, reset it now + if (CreateSymbolTable) { + symTabSize = 0; + symTab.clear(); + } - // Write the symbol table and string pool - writeSymbolTable(ArchiveFile); + // Write magic string to archive. + ArchiveFile << ARFILE_MAGIC; - //Loop over all member files, and add to the archive. - for ( unsigned i = 0; i < members.size(); ++i) { - if(ArchiveFile.tellp() % 2 != 0) - ArchiveFile << ARFILE_PAD; - writeMember(members[i],ArchiveFile); - } + // Loop over all member files, and write them out. Note that this also + // builds the symbol table, symTab. + for ( MembersList::iterator I = begin(), E = end(); I != E; ++I) { + writeMember(*I,ArchiveFile,CreateSymbolTable,TruncateNames,Compress); + } - //Close archive file. - ArchiveFile.close(); -} + // Close archive file. + ArchiveFile.close(); -// vim: sw=2 ai + // Write the symbol table + if (CreateSymbolTable) { + // At this point we have written a file that is a legal archive but it + // doesn't have a symbol table in it. To aid in faster reading and to + // ensure compatibility with other archivers we need to put the symbol + // table first in the file. Unfortunately, this means mapping the file + // we just wrote back in and copying it to the destination file. + sys::MappedFile arch(TmpArchive); + const char* base = (const char*) arch.map(); + + // Open the final file to write and check it. + std::ofstream FinalFile(archPath.c_str()); + if ( !FinalFile.is_open() || FinalFile.bad() ) { + throw std::string("Error opening archive file: ") + archPath.get(); + } + + // Write the file magic number + FinalFile << ARFILE_MAGIC; + + // Put out the symbol table + writeSymbolTable(FinalFile,PrintSymTab); + + // Copy the temporary file contents being sure to skip the file's magic + // number. + FinalFile.write(base + sizeof(ARFILE_MAGIC)-1, + arch.size()-sizeof(ARFILE_MAGIC)+1); + + // Close up shop + FinalFile.close(); + arch.unmap(); + TmpArchive.destroyFile(); + + } else { + // We don't have to insert the symbol table, so just renaming the temp + // file to the correct name will suffice. + TmpArchive.renameFile(archPath); + } + } catch (...) { + // Make sure we clean up. + if (TmpArchive.exists()) + TmpArchive.destroyFile(); + throw; + } +} From reid at x10sys.com Sun Nov 14 15:58:24 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:58:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Archive/ArchiveInternals.h Message-ID: <200411142158.PAA21077@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Archive: ArchiveInternals.h updated: 1.1 -> 1.2 --- Log message: Implementation declarations for Archive --- Diffs of the changes: (+24 -108) Index: llvm/lib/Bytecode/Archive/ArchiveInternals.h diff -u llvm/lib/Bytecode/Archive/ArchiveInternals.h:1.1 llvm/lib/Bytecode/Archive/ArchiveInternals.h:1.2 --- llvm/lib/Bytecode/Archive/ArchiveInternals.h:1.1 Sat Nov 6 02:51:45 2004 +++ llvm/lib/Bytecode/Archive/ArchiveInternals.h Sun Nov 14 15:57:46 2004 @@ -16,21 +16,39 @@ #include "llvm/Bytecode/Archive.h" #include "llvm/System/TimeValue.h" +#include "llvm/ADT/StringExtras.h" #define ARFILE_MAGIC "!\n" ///< magic string #define ARFILE_MAGIC_LEN (sizeof(ARFILE_MAGIC)-1) ///< length of magic string -#define ARFILE_SYMTAB_NAME "/" ///< name of symtab entry -#define ARFILE_STRTAB_NAME "//" ///< name of strtab entry -#define ARFILE_PAD '\n' ///< inter-file align padding +#define ARFILE_SYMTAB_NAME "/ " ///< regular symtab entry +#define ARFILE_STRTAB_NAME "// " ///< Name of string table +#define ARFILE_LLVM_SYMTAB_NAME "#_LLVM_SYM_TAB_#" ///< LLVM's symtab entry +#define ARFILE_PAD "\n" ///< inter-file align padding +#define ARFILE_MEMBER_MAGIC "`\n" ///< fmag field magic # namespace llvm { - /// The ArchiveMemberHeader structure is used internally for bytecode archives. + /// The ArchiveMemberHeader structure is used internally for bytecode + /// archives. /// The header precedes each file member in the archive. This structure is /// defined using character arrays for direct and correct interpretation /// regardless of the endianess of the machine that produced it. /// @brief Archive File Member Header class ArchiveMemberHeader { + /// @name Data + /// @{ + public: + char name[16];///< Name of the file member. + char date[12]; ///< File date, decimal seconds since Epoch + char uid[6]; ///< user id in ASCII decimal + char gid[6]; ///< group id in ASCII decimal + char mode[8]; ///< file mode in ASCII octal + char size[10]; ///< file size in ASCII decimal + char fmag[2]; ///< Always contains ARFILE_MAGIC_TERMINATOR + + /// @} + /// @name Methods + /// @{ public: void init() { memset(name,' ',16); @@ -42,115 +60,13 @@ fmag[0] = '`'; fmag[1] = '\n'; } - void setDate( int secondsSinceEpoch = 0 ) { - if (secondsSinceEpoch == 0) { - sys::TimeValue tv = sys::TimeValue::now(); - uint64_t secs; uint32_t nanos; - tv.GetTimespecTime(secs,nanos); - secondsSinceEpoch = (int) secs; - } - char buffer[20]; - sprintf(buffer,"%d", secondsSinceEpoch); - memcpy(date,buffer,strlen(buffer)); - } - - void setSize(size_t sz) { - char buffer[20]; - sprintf(buffer, "%u", (unsigned)sz); - memcpy(size,buffer,strlen(buffer)); - } - - void setMode(int m) { - char buffer[20]; - sprintf(buffer, "%o", m); - memcpy(mode,buffer,strlen(buffer)); - } - - void setUid(unsigned u) { - char buffer[20]; - sprintf(buffer, "%u", u); - memcpy(uid,buffer,strlen(buffer)); - } - - void setGid(unsigned g) { - char buffer[20]; - sprintf(buffer, "%u", g); - memcpy(gid,buffer,strlen(buffer)); - } - bool setName(const std::string& nm) { - if (nm.length() > 0 && nm.length() <= 16) { - memcpy(name,nm.c_str(),nm.length()); - for (int i = nm.length()+1; i < 16; i++ ) name[i] = ' '; - return true; - } - return false; + bool checkSignature() { + return 0 == memcmp(fmag, ARFILE_MEMBER_MAGIC,2); } - private: - char name[16]; ///< Name of the file member. The filename is terminated with '/' - ///< and blanks. The empty name (/ and 15 blanks) is for the - ///< symbol table. The special name "//" and 15 blanks is for - ///< the string table, used for long file names. It must be - ///< first in the archive. - char date[12]; ///< File date, decimal seconds since Epoch - char uid[6]; ///< user id in ASCII decimal - char gid[6]; ///< group id in ASCII decimal - char mode[8]; ///< file mode in ASCII octal - char size[10]; ///< file size in ASCII decimal - char fmag[2]; ///< Always contains ARFILE_MAGIC_TERMINATOR - }; - /// The ArchiveInternals class is used to hold the content of the archive - /// while it is in memory. It also provides the bulk of the implementation for - /// the llvm:Archive class's interface. - class Archive::ArchiveInternals { - /// @name Types - /// @{ - public: - typedef std::vector StrTab; - - /// This structure holds information for one member in the archive. It is - /// used temporarily while the contents of the archive are being - /// determined. - struct MemberInfo { - MemberInfo() {} - sys::Path path; - std::string name; - sys::Path::StatusInfo status; - StrTab symbols; - unsigned offset; - }; - - /// @} - /// @name Methods - /// @{ - public: - /// @brief Add a file member to the archive. - void addFileMember( - const sys::Path& path, ///< The path to the file to be added - const std::string& name, ///< The name for the member - const StrTab* syms = 0 ///< The symbol table of the member - ); - - /// @brief Write the accumulated archive information to an archive file - void writeArchive(); - void writeMember(const MemberInfo& member,std::ofstream& ARFile); - void writeSymbolTable(std::ofstream& ARFile); - void writeInteger(int num, std::ofstream& ARFile); - - /// @} - /// @name Data - /// @{ - private: - friend class Archive; ///< Parent class is a friend - sys::Path fname; ///< Path to the archive file - std::vector members; ///< Info about member files - Archive::SymTab* symtab; ///< User's symbol table - - /// @} - }; } #endif From reid at x10sys.com Sun Nov 14 15:59:11 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:59:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Archive/ArchiveReader.cpp Message-ID: <200411142159.PAA21102@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Archive: ArchiveReader.cpp updated: 1.21 -> 1.22 --- Log message: Completely rewritten to allow reading of archives and symbol table lookup in a more efficient manner. --- Diffs of the changes: (+373 -164) Index: llvm/lib/Bytecode/Archive/ArchiveReader.cpp diff -u llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.21 llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.22 --- llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.21 Sun Nov 14 13:59:40 2004 +++ llvm/lib/Bytecode/Archive/ArchiveReader.cpp Sun Nov 14 15:58:33 2004 @@ -1,194 +1,403 @@ -//===- lib/Archive/ArchiveReader.cpp - Read LLVM archive files ------------===// +//===-- ArchiveReader.cpp - Read LLVM archive files -------------*- C++ -*-===// // // 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 file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// This file implements the ReadArchiveFile interface, which allows a linker to -// read all of the LLVM bytecode files contained in a .a file. This file -// understands the standard system .a file format. This can only handle the .a -// variant prevalent on Linux systems so far, but may be extended. See -// information in this source file for more information: -// http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/archive.c?cvsroot=src +// Builds up standard unix archive files (.a) containing LLVM bytecode. // //===----------------------------------------------------------------------===// +#include "ArchiveInternals.h" #include "llvm/Bytecode/Reader.h" -#include "llvm/Module.h" -#include "llvm/Support/FileUtilities.h" -#include -#include + using namespace llvm; namespace { - struct ar_hdr { - char name[16]; - char date[12]; - char uid[6]; - char gid[6]; - char mode[8]; - char size[10]; - char fmag[2]; // Always equal to '`\n' - }; - - enum ObjectType { - UserObject, // A user .o/.bc file - Unknown, // Unknown file, just ignore it - SVR4LongFilename, // a "//" section used for long file names - ArchiveSymbolTable, // Symbol table produced by ranlib. - }; -} - -/// getObjectType - Determine the type of object that this header represents. -/// This is capable of parsing the variety of special sections used for various -/// purposes. -/// -static enum ObjectType getObjectType(ar_hdr *H, std::string MemberName, - unsigned char *MemberData, unsigned Size) { - // Check for sections with special names... - if (MemberName == "__.SYMDEF " || MemberName == "__.SYMDEF SORTED") - return ArchiveSymbolTable; - else if (MemberName == "// ") - return SVR4LongFilename; - - // Check to see if it looks like an llvm object file... - if (Size >= 4 && !memcmp(MemberData, "llvm", 4)) - return UserObject; - - if (Size >= 4 && !memcmp(MemberData, "llvc", 4)) - return UserObject; - - return Unknown; -} - -static inline bool Error(std::string *ErrorStr, const char *Message) { - if (ErrorStr) *ErrorStr = Message; - return true; -} - -static bool ParseSymbolTableSection(unsigned char *Buffer, unsigned Size, - std::string *S) { - // Currently not supported (succeeds without doing anything) - return false; + +/// Read a variable-bit-rate encoded unsigned integer +inline unsigned readInteger(const char*&At, const char*End) { + unsigned Shift = 0; + unsigned Result = 0; + + do { + if (At == End) + throw std::string("Ran out of data reading vbr_uint!"); + Result |= (unsigned)((*At++) & 0x7F) << Shift; + Shift += 7; + } while (At[-1] & 0x80); + return Result; } -static bool ReadArchiveBuffer(const std::string &ArchiveName, - unsigned char *Buffer, unsigned Length, - std::vector &Objects, - std::string *ErrorStr) { - if (Length < 8 || memcmp(Buffer, "!\n", 8)) - return Error(ErrorStr, "signature incorrect for an archive file!"); - Buffer += 8; Length -= 8; // Skip the magic string. - - std::vector LongFilenames; - - while (Length >= sizeof(ar_hdr)) { - ar_hdr *Hdr = (ar_hdr*)Buffer; - unsigned SizeFromHeader = atoi(Hdr->size); - if (SizeFromHeader + sizeof(ar_hdr) > Length) - return Error(ErrorStr, "invalid record length in archive file!"); - - unsigned char *MemberData = Buffer + sizeof(ar_hdr); - unsigned MemberSize = SizeFromHeader; - // Get name of archive member. - char *startp = Hdr->name; - char *endp = (char *) memchr (startp, '/', sizeof(ar_hdr)); - if (memcmp (Hdr->name, "#1/", 3) == 0) { - // 4.4BSD/MacOSX long filenames are abbreviated as "#1/L", where L is an - // ASCII-coded decimal number representing the length of the name buffer, - // which is prepended to the archive member's contents. - unsigned NameLength = atoi (&Hdr->name[3]); - startp = (char *) MemberData; - endp = startp + NameLength; - MemberData += NameLength; - MemberSize -= NameLength; - } else if (startp == endp && isdigit (Hdr->name[1])) { - // SVR4 long filenames are abbreviated as "/I", where I is - // an ASCII-coded decimal index into the LongFilenames vector. - unsigned NameIndex = atoi (&Hdr->name[1]); - assert (LongFilenames.size () > NameIndex - && "SVR4-style long filename for archive member not found"); - startp = &LongFilenames[NameIndex]; - endp = strchr (startp, '/'); - } else if (startp == endp && Hdr->name[1] == '/') { - // This is for the SVR4 long filename table (there might be other - // names starting with // but I don't know about them). Make sure that - // getObjectType sees it. - endp = &Hdr->name[sizeof (Hdr->name)]; - } - if (!endp) { - // 4.4BSD/MacOSX *short* filenames are not guaranteed to have a - // terminator. Start at the end of the field and backtrack over spaces. - endp = startp + sizeof(Hdr->name); - while (endp[-1] == ' ') - --endp; - } - std::string MemberName (startp, endp); - std::string FullMemberName = ArchiveName + "(" + MemberName + ")"; +} - switch (getObjectType(Hdr, MemberName, MemberData, MemberSize)) { - case SVR4LongFilename: - // If this is a long filename section, read all of the file names into the - // LongFilenames vector. - LongFilenames.assign (MemberData, MemberData + MemberSize); - break; - case UserObject: { - Module *M = ParseBytecodeBuffer(MemberData, MemberSize, - FullMemberName, ErrorStr); - if (!M) return true; - Objects.push_back(M); +// Completely parse the Archive's symbol table and populate symTab member var. +void +Archive::parseSymbolTable(const void* data, unsigned size) { + const char* At = (const char*) data; + const char* End = At + size; + while (At < End) { + unsigned offset = readInteger(At, End); + unsigned length = readInteger(At, End); + if (At + length > End) + throw std::string("malformed symbol table"); + // we don't care if it can't be inserted (duplicate entry) + symTab.insert(std::make_pair(std::string(At,length),offset)); + At += length; + } + symTabSize = size; +} + +// This member parses an ArchiveMemberHeader that is presumed to be pointed to +// by At. The At pointer is updated to the byte just after the header, which +// can be variable in size. +ArchiveMember* +Archive::parseMemberHeader(const char*& At, const char* End) { + assert(At + sizeof(ArchiveMemberHeader) < End && "Not enough data"); + + // Cast archive member header + ArchiveMemberHeader* Hdr = (ArchiveMemberHeader*)At; + At += sizeof(ArchiveMemberHeader); + + // Instantiate the ArchiveMember to be filled + ArchiveMember* member = new ArchiveMember(this); + + // Extract the size and determine if the file is + // compressed or not (negative length). + int flags = 0; + int MemberSize = atoi(Hdr->size); + if (MemberSize < 0) { + flags |= ArchiveMember::CompressedFlag; + MemberSize = -MemberSize; + } + + // Check the size of the member for sanity + if (At + MemberSize > End) + throw std::string("invalid member length in archive file"); + + // Check the member signature + if (!Hdr->checkSignature()) + throw std::string("invalid file member signature"); + + // Convert and check the member name + // The empty name ( '/' and 15 blanks) is for a foreign (non-LLVM) symbol + // table. The special name "//" and 14 blanks is for a string table, used + // for long file names. This library doesn't generate either of those but + // it will accept them. If the name starts with #1/ and the remainder is + // digits, then those digits specify the length of the name that is + // stored immediately following the header. The special name + // __LLVM_SYM_TAB__ identifies the symbol table for LLVM bytecode. + // Anything else is a regular, short filename that is terminated with + // a '/' and blanks. + + std::string pathname; + unsigned index; + switch (Hdr->name[0]) { + case '#': + if (Hdr->name[1] == '1' && Hdr->name[2] == '/') { + if (isdigit(Hdr->name[3])) { + unsigned len = atoi(&Hdr->name[3]); + pathname.assign(At,len); + At += len + 1; // terminated by \n + flags |= ArchiveMember::HasLongFilenameFlag; + } else + throw std::string("invalid long filename"); + } else if (Hdr->name[1] == '_' && + (0==memcmp(Hdr->name,ARFILE_LLVM_SYMTAB_NAME,16))) { + // The member is using a long file name (>15 chars) format. + // This format is standard for 4.4BSD and Mac OSX operating + // systems. LLVM uses it similarly. In this format, the + // remainder of the name field (after #1/) specifies the + // length of the file name which occupy the first bytes of + // the member's data. The pathname already has the #1/ stripped. + pathname.assign(ARFILE_LLVM_SYMTAB_NAME); + flags |= ArchiveMember::LLVMSymbolTableFlag; + } break; - } - case ArchiveSymbolTable: - if (ParseSymbolTableSection(MemberData, MemberSize, ErrorStr)) - return true; + case '/': + if (Hdr->name[1]== '/') { + if (0==memcmp(Hdr->name,ARFILE_STRTAB_NAME,16)) { + pathname.assign(ARFILE_STRTAB_NAME); + flags |= ArchiveMember::StringTableFlag; + } else { + throw std::string("invalid string table name"); + } + } else if (Hdr->name[1] == ' ') { + if (0==memcmp(Hdr->name,ARFILE_SYMTAB_NAME,16)) { + pathname.assign(ARFILE_SYMTAB_NAME); + flags |= ArchiveMember::ForeignSymbolTableFlag; + } else { + throw std::string("invalid foreign symbol table name"); + } + } else if (isdigit(Hdr->name[1])) { + unsigned index = atoi(&Hdr->name[1]); + if (index < strtab.length()) { + const char* namep = strtab.c_str() + index; + const char* endp = strtab.c_str() + strtab.length(); + const char* p = namep; + const char* last_p = p; + while (p < endp) { + if (*p == '\n' && *last_p == '/') { + pathname.assign(namep,last_p-namep); + flags |= ArchiveMember::HasLongFilenameFlag; + break; + } + last_p = p; + p++; + } + if (p >= endp) + throw std::string("missing name termiantor in string table"); + } else { + throw std::string("name index beyond string table"); + } + } break; + default: - std::cerr << "ReadArchiveBuffer: WARNING: Skipping unknown file: " - << FullMemberName << "\n"; - break; // Just ignore unknown files. - } + char* slash = (char*) memchr(Hdr->name,'/',16); + if (slash == 0) + throw std::string("missing name terminator"); + pathname.assign(Hdr->name,slash-Hdr->name); + break; + } - // Round SizeFromHeader up to an even number... - SizeFromHeader = (SizeFromHeader+1)/2*2; - Buffer += sizeof(ar_hdr)+SizeFromHeader; // Move to the next entry - Length -= sizeof(ar_hdr)+SizeFromHeader; + // Determine if this is a bytecode file + switch (sys::IdentifyFileType(At,4)) { + case sys::BytecodeFileType: + flags |= ArchiveMember::BytecodeFlag; + break; + case sys::CompressedBytecodeFileType: + flags |= ArchiveMember::CompressedBytecodeFlag; + flags &= ~ArchiveMember::CompressedFlag; + break; + default: + flags &= ~(ArchiveMember::BytecodeFlag| + ArchiveMember::CompressedBytecodeFlag); + break; } - return Length != 0; + // Fill in fields of the ArchiveMember + member->next = 0; + member->prev = 0; + member->parent = this; + member->path.setFile(pathname); + member->info.fileSize = MemberSize; + member->info.modTime.fromEpochTime(atoi(Hdr->date)); + sscanf(Hdr->mode,"%o",&(member->info.mode)); + member->info.user = atoi(Hdr->uid); + member->info.group = atoi(Hdr->gid); + member->flags = flags; + member->data = At; + + return member; } +void +Archive::checkSignature() { + // Check the magic string at file's header + if (mapfile->size() < 8 || memcmp(base, ARFILE_MAGIC,8)) + throw std::string("invalid signature for an archive file"); +} -// ReadArchiveFile - Read bytecode files from the specified .a file, returning -// true on error, or false on success. This does not support reading files from -// standard input. -// -bool llvm::ReadArchiveFile(const std::string &Filename, - std::vector &Objects,std::string *ErrorStr){ - unsigned Length; - - // mmap in the file all at once... - unsigned char *Buffer = - (unsigned char*)ReadFileIntoAddressSpace(Filename, Length); - if (Buffer == 0) { - if (ErrorStr) *ErrorStr = "Error reading file '" + Filename + "'!"; - return true; +// This function loads the entire archive and fully populates its ilist with +// the members of the archive file. This is typically used in preparation for +// editing the contents of the archive. +void +Archive::loadArchive() { + + // Set up parsing + members.clear(); + symTab.clear(); + const char *At = base; + const char *End = base + mapfile->size(); + + checkSignature(); + At += 8; // Skip the magic string. + + bool seenSymbolTable = false; + bool foundFirstFile = false; + while (At < End) { + // parse the member header + const char* Save = At; + ArchiveMember* mbr = parseMemberHeader(At, End); + + // check if this is the foreign symbol table + if (mbr->isForeignSymbolTable()) { + // We don't do anything with this but delete it + At += mbr->getSize(); + delete mbr; + if ((int(At) & 1) == 1) + At++; + } else if (mbr->isStringTable()) { + strtab.assign(At,mbr->getSize()); + At += mbr->getSize(); + if ((int(At) & 1) == 1) + At++; + delete mbr; + } else if (mbr->isLLVMSymbolTable()) { + if (seenSymbolTable) + throw std::string("invalid archive: multiple symbol tables"); + parseSymbolTable(mbr->getData(),mbr->getSize()); + seenSymbolTable = true; + At += mbr->getSize(); + if ((int(At) & 1) == 1) + At++; + delete mbr; + } else { + if (!foundFirstFile) { + firstFileOffset = Save - base; + foundFirstFile = true; + } + members.push_back(mbr); + At += mbr->getSize(); + if ((int(At) & 1) == 1) + At++; + } } +} + +// Open and completely load the archive file. +Archive* +Archive::OpenAndLoad(const sys::Path& file) { + + Archive* result = new Archive(file,true); + + result->loadArchive(); - // Parse the archive files we mmap'ped in - bool Result = ReadArchiveBuffer(Filename, Buffer, Length, Objects, ErrorStr); - - // Unmmap the archive... - UnmapFileFromAddressSpace(Buffer, Length); + return result; +} - if (Result) // Free any loaded objects - while (!Objects.empty()) { - delete Objects.back(); - Objects.pop_back(); +// Get all the bytecode modules from the archive +bool +Archive::getAllModules(std::vector& Modules, std::string* ErrMessage) { + + for (iterator I=begin(), E=end(); I != E; ++I) { + if (I->isBytecode() || I->isCompressedBytecode()) { + Module* M = ParseBytecodeBuffer((const unsigned char*)I->getData(), + I->getSize(), I->getPath().get(), ErrMessage); + if (!M) + return true; + + Modules.push_back(M); } - - return Result; + } + return false; +} + +// Load just the symbol table from the archive file +void +Archive::loadSymbolTable() { + + // Set up parsing + members.clear(); + symTab.clear(); + const char *At = base; + const char *End = base + mapfile->size(); + + // Make sure we're dealing with an archive + checkSignature(); + + At += 8; // Skip signature + + // Parse the first file member header + const char* FirstFile = At; + ArchiveMember* mbr = parseMemberHeader(At, End); + + if (mbr->isForeignSymbolTable()) { + // Skip the foreign symbol table, we don't do anything with it + At += mbr->getSize(); + delete mbr; + + // See if there's a string table too + FirstFile = At; + mbr = parseMemberHeader(At,End); + if (mbr->isStringTable()) { + strtab.assign((const char*)mbr->getData(),mbr->getSize()); + At += mbr->getSize(); + delete mbr; + FirstFile = At; + mbr = parseMemberHeader(At,End); + } + } + + // See if its the symbol table + if (mbr->isLLVMSymbolTable()) { + parseSymbolTable(mbr->getData(),mbr->getSize()); + FirstFile = At + mbr->getSize(); + if (mbr->getSize() % 2 != 0) + FirstFile++; + } else { + // There's no symbol table in the file. We have to rebuild it from scratch + // because the intent of this method is to get the symbol table loaded so + // it can be searched efficiently. + // Add the member to the members list + members.push_back(mbr); + } + + firstFileOffset = FirstFile - base; +} + +// Open the archive and load just the symbol tables +Archive* +Archive::OpenAndLoadSymbols(const sys::Path& file) { + Archive* result = new Archive(file,true); + + result->loadSymbolTable(); + + return result; +} + +// Look up one symbol in the symbol table and return a ModuleProvider for the +// module that defines that symbol. +ModuleProvider* +Archive::findModuleDefiningSymbol(const std::string& symbol) { + SymTabType::iterator SI = symTab.find(symbol); + if (SI == symTab.end()) + return 0; + + // The symbol table was previously constructed assuming that the members were + // written without the symbol table header. Because VBR encoding is used, the + // values could not be adjusted to account for the offset of the symbol table + // because that could affect the size of the symbol table due to VBR encoding. + // We now have to account for this by adjusting the offset by the size of the + // symbol table and its header. + unsigned fileOffset = + SI->second + // offset in symbol-table-less file + firstFileOffset; // add offset to first "real" file in archive + + // See if the module is already loaded + ModuleMap::iterator MI = modules.find(fileOffset); + if (MI != modules.end()) + return MI->second.first; + + // Module hasn't been loaded yet, we need to load it + const char* modptr = base + fileOffset; + ArchiveMember* mbr = parseMemberHeader(modptr, base + mapfile->size()); + + // Now, load the bytecode module to get the ModuleProvider + ModuleProvider* mp = getBytecodeBufferModuleProvider( + (const unsigned char*) mbr->getData(), mbr->getSize(), + mbr->getPath().get(), 0); + + modules.insert(std::make_pair(fileOffset,std::make_pair(mp,mbr))); + + return mp; +} + +// Look up multiple symbols in the symbol table and return a set of +// ModuleProviders that define those symbols. +void +Archive::findModulesDefiningSymbols(const std::set& symbols, + std::set& modules) +{ + for (std::set::const_iterator I=symbols.begin(), + E=symbols.end(); I != E; ++I) { + ModuleProvider* mp = findModuleDefiningSymbol(*I); + if (mp) { + modules.insert(mp); + } + } } From reid at x10sys.com Sun Nov 14 15:59:59 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 15:59:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/Reader.cpp Message-ID: <200411142159.PAA21124@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: Reader.cpp updated: 1.138 -> 1.139 --- Log message: Simplify decompression code by using the high level interface to the Compressor --- Diffs of the changes: (+11 -57) Index: llvm/lib/Bytecode/Reader/Reader.cpp diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.138 llvm/lib/Bytecode/Reader/Reader.cpp:1.139 --- llvm/lib/Bytecode/Reader/Reader.cpp:1.138 Sun Nov 14 15:02:55 2004 +++ llvm/lib/Bytecode/Reader/Reader.cpp Sun Nov 14 15:59:21 2004 @@ -2157,43 +2157,6 @@ error("Function declared, but bytecode stream ended before definition"); } -/// This function handles allocation of the buffer used for decompression of -/// compressed bytecode files. It is called by Compressor::decompress which is -/// called by BytecodeReader::ParseBytecode. -static unsigned GetDecompressionBuffer(char*&buff, unsigned& sz, void* ctxt){ - // Case the context variable to our BufferInfo - BytecodeReader::BufferInfo* bi = - reinterpret_cast(ctxt); - - // Compute the new, doubled, size of the block - unsigned new_size = bi->size * 2; - - // Extend or allocate the block (realloc(0,n) == malloc(n)) - char* new_buff = (char*) ::realloc(bi->buff, new_size); - - // Figure out what to return to the Compressor. If this is the first call, - // then bi->buff will be null. In this case we want to return the entire - // buffer because there was no previous allocation. Otherwise, when the - // buffer is reallocated, we save the new base pointer in the BufferInfo.buff - // field but return the address of only the extension, mid-way through the - // buffer (since its size was doubled). Furthermore, the sz result must be - // 1/2 the total size of the buffer. - if (bi->buff == 0 ) { - buff = bi->buff = new_buff; - sz = new_size; - } else { - bi->buff = new_buff; - buff = new_buff + bi->size; - sz = bi->size; - } - - // Retain the size of the allocated block - bi->size = new_size; - - // Make sure we fail (return 1) if we didn't get any memory. - return (bi->buff == 0 ? 1 : 0); -} - /// This function completely parses a bytecode buffer given by the \p Buf /// and \p Length parameters. void BytecodeReader::ParseBytecode(BufPtr Buf, unsigned Length, @@ -2214,27 +2177,18 @@ // If this is a compressed file if (Sig == ('l' | ('l' << 8) | ('v' << 16) | ('c' << 24))) { - // Compute the initial length of the uncompression buffer. Note that this - // is twice the length of the compressed buffer and will be doubled again - // in GetDecompressionBuffer for an initial allocation of 4xLength. This - // calculation is based on the typical compression ratio of bzip2 on LLVM - // bytecode files which typically ranges in the 50%-75% range. Since we - // tyipcally get at least 50%, doubling is insufficient. By using a 4x - // multiplier on the first allocation, we minimize the impact of having to - // copy the buffer on reallocation. - bi.size = Length * 2; - // Invoke the decompression of the bytecode. Note that we have to skip the // file's magic number which is not part of the compressed block. Hence, - // the Buf+4 and Length-4. - unsigned decompressedLength = Compressor::decompress((char*)Buf+4,Length-4, - GetDecompressionBuffer, (void*) &bi); + // the Buf+4 and Length-4. The result goes into decompressedBlock, a data + // member for retention until BytecodeReader is destructed. + unsigned decompressedLength = Compressor::decompressToNewBuffer( + (char*)Buf+4,Length-4,decompressedBlock); // We must adjust the buffer pointers used by the bytecode reader to point - // into the new decompressed block. After decompression, the BufferInfo - // structure (member bi), will point to a contiguous memory area that has + // into the new decompressed block. After decompression, the + // decompressedBlock will point to a contiguous memory area that has // the decompressed data. - At = MemStart = BlockStart = Buf = (BufPtr) bi.buff; + At = MemStart = BlockStart = Buf = (BufPtr) decompressedBlock; MemEnd = BlockEnd = Buf + decompressedLength; // else if this isn't a regular (uncompressed) bytecode file, then its @@ -2286,8 +2240,8 @@ freeState(); delete TheModule; TheModule = 0; - if (bi.buff != 0 ) - ::free(bi.buff); + if (decompressedBlock != 0 ) + ::free(decompressedBlock); throw; } catch (...) { std::string msg("Unknown Exception Occurred"); @@ -2295,8 +2249,8 @@ freeState(); delete TheModule; TheModule = 0; - if (bi.buff != 0 ) - ::free(bi.buff); + if (decompressedBlock != 0 ) + ::free(decompressedBlock); throw msg; } } From reid at x10sys.com Sun Nov 14 16:00:56 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:00:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/Reader.h Message-ID: <200411142200.QAA21187@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: Reader.h updated: 1.17 -> 1.18 --- Log message: Simplify handling of decompression --- Diffs of the changes: (+4 -15) Index: llvm/lib/Bytecode/Reader/Reader.h diff -u llvm/lib/Bytecode/Reader/Reader.h:1.17 llvm/lib/Bytecode/Reader/Reader.h:1.18 --- llvm/lib/Bytecode/Reader/Reader.h:1.17 Sun Nov 7 12:19:00 2004 +++ llvm/lib/Bytecode/Reader/Reader.h Sun Nov 14 16:00:09 2004 @@ -47,13 +47,14 @@ BytecodeReader( BytecodeHandler* h = 0 ) { + decompressedBlock = 0; Handler = h; } ~BytecodeReader() { freeState(); - if (bi.buff != 0) - ::free(bi.buff); + if (decompressedBlock) + ::free(decompressedBlock); } /// @} @@ -67,18 +68,6 @@ /// @brief The type used for a vector of potentially abstract types typedef std::vector TypeListTy; - /// This structure is only used when a bytecode file is compressed. - /// As bytecode is being decompressed, the memory buffer might need - /// to be reallocated. The buffer allocation is handled in a callback - /// and this structure is needed to retain information across calls - /// to the callback. - /// @brief An internal buffer object used for handling decompression - struct BufferInfo { - char* buff; - unsigned size; - BufferInfo() { buff = 0; size = 0; } - }; - /// This type provides a vector of Value* via the User class for /// storage of Values that have been constructed when reading the /// bytecode. Because of forward referencing, constant replacement @@ -251,7 +240,7 @@ /// @name Data /// @{ private: - BufferInfo bi; ///< Buffer info for decompression + char* decompressedBlock; ///< Result of decompression BufPtr MemStart; ///< Start of the memory buffer BufPtr MemEnd; ///< End of the memory buffer BufPtr BlockStart; ///< Start of current block being parsed From reid at x10sys.com Sun Nov 14 16:01:33 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:01:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/ReaderWrappers.cpp Message-ID: <200411142201.QAA21213@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: ReaderWrappers.cpp updated: 1.33 -> 1.34 --- Log message: Add wrappers to get defined symbols from bytecode --- Diffs of the changes: (+48 -19) Index: llvm/lib/Bytecode/Reader/ReaderWrappers.cpp diff -u llvm/lib/Bytecode/Reader/ReaderWrappers.cpp:1.33 llvm/lib/Bytecode/Reader/ReaderWrappers.cpp:1.34 --- llvm/lib/Bytecode/Reader/ReaderWrappers.cpp:1.33 Sat Nov 6 02:56:40 2004 +++ llvm/lib/Bytecode/Reader/ReaderWrappers.cpp Sun Nov 14 16:00:48 2004 @@ -346,6 +346,30 @@ } } +namespace { +void getSymbols(Module*M, std::vector& symbols) { + // Loop over global variables + for (Module::giterator GI = M->gbegin(), GE=M->gend(); GI != GE; ++GI) { + if (GI->hasInitializer()) { + std::string name ( GI->getName() ); + if (!name.empty()) { + symbols.push_back(name); + } + } + } + + //Loop over functions + for (Module::iterator FI = M->begin(), FE=M->end(); FI != FE; ++FI) { + if (!FI->isExternal()) { + std::string name ( FI->getName() ); + if (!name.empty()) { + symbols.push_back(name); + } + } + } +} +} + // Get just the externally visible defined symbols from the bytecode bool llvm::GetBytecodeSymbols(const sys::Path& fName, std::vector& symbols) { @@ -355,25 +379,8 @@ // Get the module from the provider Module* M = AMP->releaseModule(); - // Loop over global variables - for (Module::giterator GI = M->gbegin(), GE=M->gend(); GI != GE; ++GI) { - if (GI->hasInitializer()) { - std::string name ( GI->getName() ); - if (!name.empty()) { - symbols.push_back(name); - } - } - } - - //Loop over functions - for (Module::iterator FI = M->begin(), FE=M->end(); FI != FE; ++FI) { - if (!FI->isExternal()) { - std::string name ( FI->getName() ); - if (!name.empty()) { - symbols.push_back(name); - } - } - } + // Get the symbols + getSymbols(M, symbols); // Done with the module delete M; @@ -384,4 +391,26 @@ } } +bool llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length, + const std::string& ModuleID, + std::vector& symbols) { + + try { + std::auto_ptr + AMP(getBytecodeBufferModuleProvider(Buffer, Length, ModuleID)); + + // Get the module from the provider + Module* M = AMP->releaseModule(); + + // Get the symbols + getSymbols(M, symbols); + + // Done with the module + delete M; + return true; + + } catch (...) { + return false; + } +} // vim: sw=2 ai From reid at x10sys.com Sun Nov 14 16:02:19 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:02:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Writer/Writer.cpp Message-ID: <200411142202.QAA21238@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Writer: Writer.cpp updated: 1.86 -> 1.87 --- Log message: Simplify compression code by using the high level interface to the Compressor --- Diffs of the changes: (+4 -73) Index: llvm/lib/Bytecode/Writer/Writer.cpp diff -u llvm/lib/Bytecode/Writer/Writer.cpp:1.86 llvm/lib/Bytecode/Writer/Writer.cpp:1.87 --- llvm/lib/Bytecode/Writer/Writer.cpp:1.86 Sun Nov 7 12:17:38 2004 +++ llvm/lib/Bytecode/Writer/Writer.cpp Sun Nov 14 16:01:41 2004 @@ -1086,68 +1086,6 @@ } } -// This structure retains the context when compressing the bytecode file. The -// WriteCompressedData function below uses it to keep track of the previously -// filled chunk of memory (which it writes) and how many bytes have been -// written. -struct CompressionContext { - // Initialize the context - CompressionContext(std::ostream*OS, unsigned CS) - : chunk(0), sz(0), written(0), compSize(CS), Out(OS) {} - - // Make sure we clean up memory - ~CompressionContext() { - if (chunk) - delete [] chunk; - } - - // Write the chunk - void write(unsigned size = 0) { - unsigned write_size = (size == 0 ? sz : size); - Out->write(chunk,write_size); - written += write_size; - delete [] chunk; - chunk = 0; - sz = 0; - } - - char* chunk; // pointer to the chunk of memory filled by compression - unsigned sz; // size of chunk - unsigned written; // aggregate total of bytes written in all chunks - unsigned compSize; // size of the uncompressed buffer - std::ostream* Out; // The stream we write the data to. -}; - -// This function is a callback used by the Compressor::compress function to -// allocate memory for the compression buffer. This function fulfills that -// responsibility but also writes the previous (now filled) buffer out to the -// stream. -static unsigned WriteCompressedData(char*&buffer, unsigned& size, void* context) { - // Cast the context to the structure it must point to. - CompressionContext* ctxt = reinterpret_cast(context); - - // If there's a previously allocated chunk, it must now be filled with - // compressed data, so we write it out and deallocate it. - if (ctxt->chunk != 0 && ctxt->sz > 0 ) { - ctxt->write(); - } - - // Compute the size of the next chunk to allocate. We attempt to allocate - // enough memory to handle the compression in a single memory allocation. In - // general, the worst we do on compression of bytecode is about 50% so we - // conservatively estimate compSize / 2 as the size needed for the - // compression buffer. compSize is the size of the compressed data, provided - // by WriteBytecodeToFile. - size = ctxt->sz = ctxt->compSize / 2; - - // Allocate the chunks - buffer = ctxt->chunk = new char [size]; - - // We must return 1 if the allocation failed so that the Compressor knows - // not to use the buffer pointer. - return (ctxt->chunk == 0 ? 1 : 0); -} - void llvm::WriteBytecodeToFile(const Module *M, std::ostream &Out, bool compress ) { assert(M && "You can't write a null module!!"); @@ -1184,21 +1122,14 @@ Out.write(compressed_magic,4); - // Do the compression, writing as we go. - CompressionContext ctxt(&Out,Buffer.size()); - - // Compress everything after the magic number (which we'll alter) - uint64_t zipSize = Compressor::compress( + // Compress everything after the magic number (which we altered) + uint64_t zipSize = Compressor::compressToStream( (char*)(FirstByte+4), // Skip the magic number Buffer.size()-4, // Skip the magic number - WriteCompressedData, // use this function to allocate / write - Compressor::COMP_TYPE_BZIP2, // Try bzip2 compression first - (void*)&ctxt // Keep track of allocated memory + Out, // Where to write compressed data + Compressor::COMP_TYPE_BZIP2 // Try bzip2 compression first ); - if (ctxt.chunk) { - ctxt.write(zipSize - ctxt.written); - } } else { // We're not compressing, so just write the entire block. From reid at x10sys.com Sun Nov 14 16:03:05 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:03:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/Linker/LinkArchives.cpp Message-ID: <200411142203.QAA21265@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: LinkArchives.cpp updated: 1.31 -> 1.32 --- Log message: *Adjust prototypes for public interface. *Rewrite LinkInArchive to use symbol tables. --- Diffs of the changes: (+41 -65) Index: llvm/lib/Linker/LinkArchives.cpp diff -u llvm/lib/Linker/LinkArchives.cpp:1.31 llvm/lib/Linker/LinkArchives.cpp:1.32 --- llvm/lib/Linker/LinkArchives.cpp:1.31 Fri Nov 12 14:34:32 2004 +++ llvm/lib/Linker/LinkArchives.cpp Sun Nov 14 16:02:27 2004 @@ -12,10 +12,12 @@ // //===----------------------------------------------------------------------===// -#include "gccld.h" +#include "llvm/Linker.h" #include "llvm/Module.h" +#include "llvm/ModuleProvider.h" #include "llvm/PassManager.h" #include "llvm/Bytecode/Reader.h" +#include "llvm/Bytecode/Archive.h" #include "llvm/Bytecode/WriteBytecodePass.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/IPO.h" @@ -136,7 +138,7 @@ /// module it contains (wrapped in an auto_ptr), or 0 and set ErrorMessage if an /// error occurs. /// -std::auto_ptr llvm::LoadObject(const std::string &FN, +static std::auto_ptr LoadObject(const std::string &FN, std::string &ErrorMessage) { std::string ParserErrorMessage; Module *Result = ParseBytecodeFile(FN, &ParserErrorMessage); @@ -161,9 +163,9 @@ /// TRUE - An error occurred. /// FALSE - No errors. /// -static bool LinkInArchive(Module *M, +bool llvm::LinkInArchive(Module *M, const std::string &Filename, - std::string &ErrorMessage, + std::string* ErrorMessage, bool Verbose) { // Find all of the symbols currently undefined in the bytecode program. @@ -176,71 +178,45 @@ return false; // No need to link anything in! } - // Load in the archive objects. + // Open the archive file if (Verbose) std::cerr << " Loading archive file '" << Filename << "'\n"; - std::vector Objects; - if (ReadArchiveFile(Filename, Objects, &ErrorMessage)) - return true; - - // Figure out which symbols are defined by all of the modules in the archive. - std::vector > DefinedSymbols; - DefinedSymbols.resize(Objects.size()); - for (unsigned i = 0; i != Objects.size(); ++i) { - GetAllDefinedSymbols(Objects[i], DefinedSymbols[i]); - } + Archive* arch = Archive::OpenAndLoadSymbols(sys::Path(Filename)); // While we are linking in object files, loop. - bool Linked = true; - while (Linked) { - Linked = false; - - for (unsigned i = 0; i != Objects.size(); ++i) { - // Consider whether we need to link in this module... we only need to - // link it in if it defines some symbol which is so far undefined. - // - const std::set &DefSymbols = DefinedSymbols[i]; - - bool ObjectRequired = false; - - // - // If the object defines main() and the program currently has main() - // undefined, then automatically link in the module. Otherwise, look to - // see if it defines a symbol that is currently undefined. - // - if ((M->getMainFunction() == NULL) && - ((DefSymbols.find ("main")) != DefSymbols.end())) { - ObjectRequired = true; - } else { - for (std::set::iterator I = UndefinedSymbols.begin(), - E = UndefinedSymbols.end(); I != E; ++I) - if (DefSymbols.count(*I)) { - if (Verbose) - std::cerr << " Found object '" - << Objects[i]->getModuleIdentifier () - << "' providing symbol '" << *I << "'...\n"; - ObjectRequired = true; - break; - } + while (true) { + std::set Modules; + // Find the modules we need to link + arch->findModulesDefiningSymbols(UndefinedSymbols,Modules); + + // If we didn't find any more modules to link this time, we are done. + if (Modules.empty()) + break; + + // Loop over all the ModuleProviders that we got back from the archive + for (std::set::iterator I=Modules.begin(), E=Modules.end(); + I != E; ++I) { + // Get the module we must link in. + Module* aModule = (*I)->releaseModule(); + std::cout << "Linked: " << aModule->getModuleIdentifier() << "\n"; + + // Link it in + if (LinkModules(M, aModule, ErrorMessage)) { + // don't create a memory leak + delete aModule; + delete arch; + return true; // Couldn't link in the right object file... } - - // We DO need to link this object into the program... - if (ObjectRequired) { - if (LinkModules(M, Objects[i], &ErrorMessage)) - return true; // Couldn't link in the right object file... - - // Since we have linked in this object, delete it from the list of - // objects to consider in this archive file. - std::swap(Objects[i], Objects.back()); - std::swap(DefinedSymbols[i], DefinedSymbols.back()); - Objects.pop_back(); - DefinedSymbols.pop_back(); - --i; // Do not skip an entry - // The undefined symbols set should have shrunk. - GetAllUndefinedSymbols(M, UndefinedSymbols); - Linked = true; // We have linked something in! - } + // Since we have linked in this object, throw it away now. + delete aModule; } + + // We have linked in a set of modules determined by the archive to satisfy + // our missing symbols. Linking in the new modules will have satisfied some + // symbols but may introduce additional missing symbols. We need to update + // the list of undefined symbols and try again until the archive doesn't + // have any modules that satisfy our symbols. + GetAllUndefinedSymbols(M, UndefinedSymbols); } return false; @@ -331,7 +307,7 @@ if (Verbose) std::cerr << "Trying to link archive '" << Pathname << "'\n"; - if (LinkInArchive(HeadModule, Pathname, ErrorMessage, Verbose)) { + if (LinkInArchive(HeadModule, Pathname, &ErrorMessage, Verbose)) { std::cerr << progname << ": Error linking in archive '" << Pathname << "': " << ErrorMessage << "\n"; return true; @@ -400,7 +376,7 @@ std::cerr << "Trying to link archive '" << Pathname << "' (-l" << Libraries[i] << ")\n"; - if (LinkInArchive(HeadModule, Pathname, ErrorMessage, Verbose)) { + if (LinkInArchive(HeadModule, Pathname, &ErrorMessage, Verbose)) { std::cerr << progname << ": " << ErrorMessage << ": Error linking in archive '" << Pathname << "' (-l" << Libraries[i] << ")\n"; From reid at x10sys.com Sun Nov 14 16:03:51 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:03:51 -0600 Subject: [llvm-commits] CVS: llvm/lib/Linker/Makefile Message-ID: <200411142203.QAA21287@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: Makefile updated: 1.1 -> 1.2 --- Log message: Don't bother with a re-linked library, ensure archive library is built. --- Diffs of the changes: (+2 -0) Index: llvm/lib/Linker/Makefile diff -u llvm/lib/Linker/Makefile:1.1 llvm/lib/Linker/Makefile:1.2 --- llvm/lib/Linker/Makefile:1.1 Fri Nov 12 14:38:45 2004 +++ llvm/lib/Linker/Makefile Sun Nov 14 16:03:14 2004 @@ -8,6 +8,8 @@ ##===----------------------------------------------------------------------===## LEVEL = ../.. LIBRARYNAME = LLVMLinker +BUILD_ARCHIVE := 1 +DONT_BUILD_RELINKED := 1 include $(LEVEL)/Makefile.common From reid at x10sys.com Sun Nov 14 16:04:37 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:04:37 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/CommandLine.cpp Message-ID: <200411142204.QAA21320@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: CommandLine.cpp updated: 1.51 -> 1.52 --- Log message: Implement the MoreHelp utility that calls a function to printmore help information if the MoreHelp global is not null. --- Diffs of the changes: (+10 -0) Index: llvm/lib/Support/CommandLine.cpp diff -u llvm/lib/Support/CommandLine.cpp:1.51 llvm/lib/Support/CommandLine.cpp:1.52 --- llvm/lib/Support/CommandLine.cpp:1.51 Sat Nov 6 18:58:38 2004 +++ llvm/lib/Support/CommandLine.cpp Sun Nov 14 16:04:00 2004 @@ -834,6 +834,12 @@ //===----------------------------------------------------------------------===// // --help and --help-hidden option implementation // + +// If this variable is set, it is a pointer to a function that the user wants +// us to call after we print out the help info. Basically a hook to allow +// additional help to be printed. +void (*cl::MoreHelp)() = 0; + namespace { class HelpPrinter { @@ -907,6 +913,10 @@ for (unsigned i = 0, e = Options.size(); i != e; ++i) Options[i].second->printOptionInfo(MaxArgLen); + // Call the user's hook so help output can be extended. + if (MoreHelp != 0) + (*MoreHelp)(); + // Halt the program if help information is printed exit(1); } From reid at x10sys.com Sun Nov 14 16:05:23 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:05:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/Compressor.cpp Message-ID: <200411142205.QAA21362@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: Compressor.cpp updated: 1.5 -> 1.6 --- Log message: Implement the high level interface to make (de)compression easier. --- Diffs of the changes: (+181 -9) Index: llvm/lib/Support/Compressor.cpp diff -u llvm/lib/Support/Compressor.cpp:1.5 llvm/lib/Support/Compressor.cpp:1.6 --- llvm/lib/Support/Compressor.cpp:1.5 Tue Nov 9 11:58:09 2004 +++ llvm/lib/Support/Compressor.cpp Sun Nov 14 16:04:46 2004 @@ -111,13 +111,137 @@ void NULLCOMP_end(NULLCOMP_stream* strm) { } +/// This structure is only used when a bytecode file is compressed. +/// As bytecode is being decompressed, the memory buffer might need +/// to be reallocated. The buffer allocation is handled in a callback +/// and this structure is needed to retain information across calls +/// to the callback. +/// @brief An internal buffer object used for handling decompression +struct BufferContext { + char* buff; + unsigned size; + BufferContext(unsigned compressedSize ) { + // Null to indicate malloc of a new block + buff = 0; + + // Compute the initial length of the uncompression buffer. Note that this + // is twice the length of the compressed buffer and will be doubled again + // in the callback for an initial allocation of 4x compressedSize. This + // calculation is based on the typical compression ratio of bzip2 on LLVM + // bytecode files which typically ranges in the 50%-75% range. Since we + // tyipcally get at least 50%, doubling is insufficient. By using a 4x + // multiplier on the first allocation, we minimize the impact of having to + // copy the buffer on reallocation. + size = compressedSize*2; + } + + /// This function handles allocation of the buffer used for decompression of + /// compressed bytecode files. It is called by Compressor::decompress which is + /// called by BytecodeReader::ParseBytecode. + static unsigned callback(char*&buff, unsigned& sz, void* ctxt){ + // Case the context variable to our BufferContext + BufferContext* bc = reinterpret_cast(ctxt); + + // Compute the new, doubled, size of the block + unsigned new_size = bc->size * 2; + + // Extend or allocate the block (realloc(0,n) == malloc(n)) + char* new_buff = (char*) ::realloc(bc->buff, new_size); + + // Figure out what to return to the Compressor. If this is the first call, + // then bc->buff will be null. In this case we want to return the entire + // buffer because there was no previous allocation. Otherwise, when the + // buffer is reallocated, we save the new base pointer in the BufferContext.buff + // field but return the address of only the extension, mid-way through the + // buffer (since its size was doubled). Furthermore, the sz result must be + // 1/2 the total size of the buffer. + if (bc->buff == 0 ) { + buff = bc->buff = new_buff; + sz = new_size; + } else { + bc->buff = new_buff; + buff = new_buff + bc->size; + sz = bc->size; + } + + // Retain the size of the allocated block + bc->size = new_size; + + // Make sure we fail (return 1) if we didn't get any memory. + return (bc->buff == 0 ? 1 : 0); + } +}; + +// This structure retains the context when compressing the bytecode file. The +// WriteCompressedData function below uses it to keep track of the previously +// filled chunk of memory (which it writes) and how many bytes have been +// written. +struct WriterContext { + // Initialize the context + WriterContext(std::ostream*OS, unsigned CS) + : chunk(0), sz(0), written(0), compSize(CS), Out(OS) {} + + // Make sure we clean up memory + ~WriterContext() { + if (chunk) + delete [] chunk; + } + + // Write the chunk + void write(unsigned size = 0) { + unsigned write_size = (size == 0 ? sz : size); + Out->write(chunk,write_size); + written += write_size; + delete [] chunk; + chunk = 0; + sz = 0; + } + + // This function is a callback used by the Compressor::compress function to + // allocate memory for the compression buffer. This function fulfills that + // responsibility but also writes the previous (now filled) buffer out to the + // stream. + static unsigned callback(char*& buffer, unsigned& size, void* context) { + // Cast the context to the structure it must point to. + WriterContext* ctxt = + reinterpret_cast(context); + + // If there's a previously allocated chunk, it must now be filled with + // compressed data, so we write it out and deallocate it. + if (ctxt->chunk != 0 && ctxt->sz > 0 ) { + ctxt->write(); + } + + // Compute the size of the next chunk to allocate. We attempt to allocate + // enough memory to handle the compression in a single memory allocation. In + // general, the worst we do on compression of bytecode is about 50% so we + // conservatively estimate compSize / 2 as the size needed for the + // compression buffer. compSize is the size of the compressed data, provided + // by WriteBytecodeToFile. + size = ctxt->sz = ctxt->compSize / 2; + + // Allocate the chunks + buffer = ctxt->chunk = new char [size]; + + // We must return 1 if the allocation failed so that the Compressor knows + // not to use the buffer pointer. + return (ctxt->chunk == 0 ? 1 : 0); + } + + char* chunk; // pointer to the chunk of memory filled by compression + unsigned sz; // size of chunk + unsigned written; // aggregate total of bytes written in all chunks + unsigned compSize; // size of the uncompressed buffer + std::ostream* Out; // The stream we write the data to. +}; + } namespace llvm { // Compress in one of three ways -uint64_t Compressor::compress(char* in, unsigned size, OutputDataCallback* cb, - Algorithm hint, void* context ) { +uint64_t Compressor::compress(const char* in, unsigned size, + OutputDataCallback* cb, Algorithm hint, void* context ) { assert(in && "Can't compress null buffer"); assert(size && "Can't compress empty buffer"); assert(cb && "Can't compress without a callback function"); @@ -132,7 +256,7 @@ bzdata.bzalloc = 0; bzdata.bzfree = 0; bzdata.opaque = 0; - bzdata.next_in = in; + bzdata.next_in = (char*)in; bzdata.avail_in = size; bzdata.next_out = 0; bzdata.avail_out = 0; @@ -188,7 +312,7 @@ zdata.zalloc = Z_NULL; zdata.zfree = Z_NULL; zdata.opaque = Z_NULL; - zdata.next_in = reinterpret_cast(in); + zdata.next_in = (Bytef*)in; zdata.avail_in = size; if (Z_OK != deflateInit(&zdata,6)) throw std::string(zdata.msg ? zdata.msg : "zlib error"); @@ -227,7 +351,7 @@ case COMP_TYPE_SIMPLE: { NULLCOMP_stream sdata; - sdata.next_in = in; + sdata.next_in = (char*)in; sdata.avail_in = size; NULLCOMP_init(&sdata); @@ -254,8 +378,33 @@ return result; } +uint64_t +Compressor::compressToNewBuffer(const char* in, unsigned size, char*&out, + Algorithm hint) { + BufferContext bc(size); + unsigned result = compress(in,size,BufferContext::callback,hint,(void*)&bc); + out = bc.buff; + return result; +} + +uint64_t +Compressor::compressToStream(const char*in, unsigned size, std::ostream& out, + Algorithm hint) { + // Set up the context and writer + WriterContext ctxt(&out,size / 2); + + // Compress everything after the magic number (which we'll alter) + uint64_t zipSize = Compressor::compress(in,size, + WriterContext::callback, hint, (void*)&ctxt); + + if (ctxt.chunk) { + ctxt.write(zipSize - ctxt.written); + } + return zipSize; +} + // Decompress in one of three ways -uint64_t Compressor::decompress(char *in, unsigned size, +uint64_t Compressor::decompress(const char *in, unsigned size, OutputDataCallback* cb, void* context) { assert(in && "Can't decompress null buffer"); assert(size > 1 && "Can't decompress empty buffer"); @@ -273,7 +422,7 @@ bzdata.bzalloc = 0; bzdata.bzfree = 0; bzdata.opaque = 0; - bzdata.next_in = in; + bzdata.next_in = (char*)in; bzdata.avail_in = size - 1; bzdata.next_out = 0; bzdata.avail_out = 0; @@ -327,7 +476,7 @@ zdata.zalloc = Z_NULL; zdata.zfree = Z_NULL; zdata.opaque = Z_NULL; - zdata.next_in = reinterpret_cast(in); + zdata.next_in = (Bytef*)(in); zdata.avail_in = size - 1; if ( Z_OK != inflateInit(&zdata)) throw std::string(zdata.msg ? zdata.msg : "zlib error"); @@ -356,7 +505,7 @@ case COMP_TYPE_SIMPLE: { NULLCOMP_stream sdata; - sdata.next_in = in; + sdata.next_in = (char*)in; sdata.avail_in = size - 1; NULLCOMP_init(&sdata); @@ -382,6 +531,29 @@ return result; } +uint64_t +Compressor::decompressToNewBuffer(const char* in, unsigned size, char*&out) { + BufferContext bc(size); + unsigned result = decompress(in,size,BufferContext::callback,(void*)&bc); + out = bc.buff; + return result; +} + +uint64_t +Compressor::decompressToStream(const char*in, unsigned size, std::ostream& out){ + // Set up the context and writer + WriterContext ctxt(&out,size / 2); + + // Compress everything after the magic number (which we'll alter) + uint64_t zipSize = Compressor::decompress(in,size, + WriterContext::callback, (void*)&ctxt); + + if (ctxt.chunk) { + ctxt.write(zipSize - ctxt.written); + } + return zipSize; +} + } // vim: sw=2 ai From reid at x10sys.com Sun Nov 14 16:06:09 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:06:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Path.cpp Message-ID: <200411142206.QAA21444@zion.cs.uiuc.edu> Changes in directory llvm/lib/System: Path.cpp updated: 1.6 -> 1.7 --- Log message: Implement IdentifyFileType function --- Diffs of the changes: (+27 -0) Index: llvm/lib/System/Path.cpp diff -u llvm/lib/System/Path.cpp:1.6 llvm/lib/System/Path.cpp:1.7 --- llvm/lib/System/Path.cpp:1.6 Fri Sep 10 23:59:30 2004 +++ llvm/lib/System/Path.cpp Sun Nov 14 16:05:32 2004 @@ -21,6 +21,33 @@ //=== independent code. //===----------------------------------------------------------------------===// +LLVMFileType +IdentifyFileType(const char*magic, unsigned length) { + assert(magic && "Invalid magic number string"); + assert(length >=4 && "Invalid magic number length"); + switch (magic[0]) { + case 'l': + if (magic[1] == 'l' && magic[2] == 'v') { + if (magic[3] == 'c') + return CompressedBytecodeFileType; + else if (magic[3] == 'm') + return BytecodeFileType; + } + break; + + case '!': + if (length >= 8) { + if (memcmp(magic,"!\n",8) == 0) + return ArchiveFileType; + } + break; + + default: + break; + } + return UnknownFileType; +} + } // Include the truly platform-specific parts of this class. From reid at x10sys.com Sun Nov 14 16:06:55 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:06:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/TimeValue.cpp Message-ID: <200411142206.QAA21486@zion.cs.uiuc.edu> Changes in directory llvm/lib/System: TimeValue.cpp updated: 1.1 -> 1.2 --- Log message: Don't exceed 80 columns. --- Diffs of the changes: (+5 -5) Index: llvm/lib/System/TimeValue.cpp diff -u llvm/lib/System/TimeValue.cpp:1.1 llvm/lib/System/TimeValue.cpp:1.2 --- llvm/lib/System/TimeValue.cpp:1.1 Fri Sep 24 18:25:19 2004 +++ llvm/lib/System/TimeValue.cpp Sun Nov 14 16:06:18 2004 @@ -16,11 +16,11 @@ namespace llvm { using namespace sys; -const TimeValue TimeValue::MinTime = TimeValue ( INT64_MIN,0 ); -const TimeValue TimeValue::MaxTime = TimeValue ( INT64_MAX,0 ); -const TimeValue TimeValue::ZeroTime = TimeValue ( 0,0 ); -const TimeValue TimeValue::PosixZeroTime = TimeValue ( -946684800,0 ); -const TimeValue TimeValue::Win32ZeroTime = TimeValue ( -12591158400ULL,0 ); +const TimeValue TimeValue::MinTime = TimeValue ( INT64_MIN,0 ); +const TimeValue TimeValue::MaxTime = TimeValue ( INT64_MAX,0 ); +const TimeValue TimeValue::ZeroTime = TimeValue ( 0,0 ); +const TimeValue TimeValue::PosixZeroTime = TimeValue ( -946684800,0 ); +const TimeValue TimeValue::Win32ZeroTime = TimeValue ( -12591158400ULL,0 ); void TimeValue::normalize( void ) { From reid at x10sys.com Sun Nov 14 16:07:42 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:07:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Linux/TimeValue.cpp Message-ID: <200411142207.QAA21519@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Linux: TimeValue.cpp updated: 1.3 -> 1.4 --- Log message: Include the correct implementation file --- Diffs of the changes: (+3 -1) Index: llvm/lib/System/Linux/TimeValue.cpp diff -u llvm/lib/System/Linux/TimeValue.cpp:1.3 llvm/lib/System/Linux/TimeValue.cpp:1.4 --- llvm/lib/System/Linux/TimeValue.cpp:1.3 Sat Sep 25 03:32:37 2004 +++ llvm/lib/System/Linux/TimeValue.cpp Sun Nov 14 16:07:04 2004 @@ -12,10 +12,12 @@ //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.h" +#include "../Unix/TimeValue.cpp" + #include namespace llvm { + using namespace sys; //===----------------------------------------------------------------------===// From reid at x10sys.com Sun Nov 14 16:08:28 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:08:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/MappedFile.cpp Message-ID: <200411142208.QAA21548@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: MappedFile.cpp updated: 1.5 -> 1.6 --- Log message: Fix bugs in class invariant --- Diffs of the changes: (+3 -0) Index: llvm/lib/System/Unix/MappedFile.cpp diff -u llvm/lib/System/Unix/MappedFile.cpp:1.5 llvm/lib/System/Unix/MappedFile.cpp:1.6 --- llvm/lib/System/Unix/MappedFile.cpp:1.5 Wed Oct 27 18:18:44 2004 +++ llvm/lib/System/Unix/MappedFile.cpp Sun Nov 14 16:07:50 2004 @@ -53,6 +53,8 @@ info_ = 0; ThrowErrno(std::string("Can't stat file: ") + path_.get()); } + } else { + throw std::string("Can't open file: ") + path_.get(); } } @@ -74,6 +76,7 @@ } void* MappedFile::map() { + assert(info_ && "MappedFile not initialized"); if (!isMapped()) { int prot = PROT_NONE; int flags = 0; From reid at x10sys.com Sun Nov 14 16:09:14 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:09:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Path.cpp Message-ID: <200411142209.QAA21577@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Path.cpp updated: 1.10 -> 1.11 --- Log message: * Implement getDirectoryContents * Implement getStatusInfo * Implement setStatusInfo * Implement renameFile --- Diffs of the changes: (+81 -7) Index: llvm/lib/System/Unix/Path.cpp diff -u llvm/lib/System/Unix/Path.cpp:1.10 llvm/lib/System/Unix/Path.cpp:1.11 --- llvm/lib/System/Unix/Path.cpp:1.10 Tue Nov 9 14:26:31 2004 +++ llvm/lib/System/Unix/Path.cpp Sun Nov 14 16:08:36 2004 @@ -21,6 +21,8 @@ #include #include #include +#include +#include namespace llvm { using namespace sys; @@ -159,9 +161,21 @@ std::ifstream f(path.c_str()); f.read(buf, len); buf[len] = '\0'; + f.close(); return Magic == buf; } +bool Path::getMagicNumber(std::string& Magic, unsigned len) const { + if (!isFile()) + return false; + char buf[1 + len]; + std::ifstream f(path.c_str()); + f.read(buf,len); + buf[len] = '\0'; + Magic = buf; + return true; +} + bool Path::isBytecodeFile() const { char buffer[ 4]; @@ -170,7 +184,9 @@ f.read(buffer, 4); if (f.bad()) ThrowErrno("can't read file signature"); - return 0 == memcmp(buffer,"llvc",4) || 0 == memcmp(buffer,"llvm",4); + + return (buffer[0] == 'l' && buffer[1] == 'l' && buffer[2] == 'v' && + (buffer[3] == 'c' || buffer[3] == 'm')); } bool @@ -224,16 +240,46 @@ } void -Path::getStatusInfo(StatusInfo& info) const { +Path::getStatusInfo(StatusInfo& info) { struct stat buf; if (0 != stat(path.c_str(), &buf)) { ThrowErrno(std::string("Can't get status: ")+path); } info.fileSize = buf.st_size; - info.modTime.fromPosixTime(buf.st_mtime); + info.modTime.fromEpochTime(buf.st_mtime); info.mode = buf.st_mode; info.user = buf.st_uid; info.group = buf.st_gid; + info.isDir = S_ISDIR(buf.st_mode); + if (info.isDir && path[path.length()-1] != '/') + path += '/'; +} + +bool +Path::getDirectoryContents(Vector& result) const { + if (!isDirectory()) + return false; + DIR* direntries = ::opendir(path.c_str()); + if (direntries == 0) + ThrowErrno(path + ": can't open directory"); + + result.clear(); + struct dirent* de = ::readdir(direntries); + while (de != 0) { + if (de->d_name[0] != '.') { + Path aPath(path + (const char*)de->d_name); + struct stat buf; + if (0 != stat(aPath.path.c_str(), &buf)) + ThrowErrno(aPath.path + ": can't get status"); + if (S_ISDIR(buf.st_mode)) + aPath.path += "/"; + result.push_back(aPath); + } + de = ::readdir(direntries); + } + + closedir(direntries); + return true; } bool @@ -363,6 +409,8 @@ int lastchar = path.length() - 1 ; if (pathname[lastchar] == '/') pathname[lastchar] = 0; + else + pathname[lastchar+1] = 0; // If we're supposed to create intermediate directories if ( create_parents ) { @@ -378,12 +426,14 @@ if (0 != mkdir(pathname, S_IRWXU | S_IRWXG)) ThrowErrno(std::string(pathname) + ": Can't create directory"); char* save = next; - next = strchr(pathname,'/'); + next = strchr(next+1,'/'); *save = '/'; } - } else if (0 != mkdir(pathname, S_IRWXU | S_IRWXG)) { - ThrowErrno(std::string(pathname) + ": Can't create directory"); } + + if (0 != access(pathname, F_OK | R_OK)) + if (0 != mkdir(pathname, S_IRWXU | S_IRWXG)) + ThrowErrno(std::string(pathname) + ": Can't create directory"); return true; } @@ -409,6 +459,7 @@ // Append the filename filler char pathname[MAXPATHLEN]; path.copy(pathname,MAXPATHLEN); + pathname[path.length()] = 0; strcat(pathname,"XXXXXX"); int fd = ::mkstemp(pathname); if (fd < 0) { @@ -439,6 +490,8 @@ int lastchar = path.length() - 1 ; if (pathname[lastchar] == '/') pathname[lastchar] = 0; + else + pathname[lastchar+1] = 0; if ( 0 != rmdir(pathname)) ThrowErrno(std::string(pathname) + ": Can't destroy directory"); } @@ -449,7 +502,28 @@ Path::destroyFile() { if (!isFile()) return false; if (0 != unlink(path.c_str())) - ThrowErrno(std::string(path.c_str()) + ": Can't destroy file"); + ThrowErrno(path + ": Can't destroy file"); + return true; +} + +bool +Path::renameFile(const Path& newName) { + if (!isFile()) return false; + if (0 != rename(path.c_str(), newName.c_str())) + ThrowErrno(std::string("can't rename ") + path + " as " + newName.get()); + return true; +} + +bool +Path::setStatusInfo(const StatusInfo& si) const { + if (!isFile()) return false; + struct utimbuf utb; + utb.actime = si.modTime.toPosixTime(); + utb.modtime = utb.actime; + if (0 != ::utime(path.c_str(),&utb)) + ThrowErrno(path + ": can't set file modification time"); + if (0 != ::chmod(path.c_str(),si.mode)) + ThrowErrno(path + ": can't set mode"); return true; } From reid at x10sys.com Sun Nov 14 16:10:00 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:10:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Signals.cpp Message-ID: <200411142210.QAA21598@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Signals.cpp updated: 1.2 -> 1.3 --- Log message: Update for prototype changes --- Diffs of the changes: (+2 -2) Index: llvm/lib/System/Unix/Signals.cpp diff -u llvm/lib/System/Unix/Signals.cpp:1.2 llvm/lib/System/Unix/Signals.cpp:1.3 --- llvm/lib/System/Unix/Signals.cpp:1.2 Fri Nov 5 16:15:36 2004 +++ llvm/lib/System/Unix/Signals.cpp Sun Nov 14 16:09:22 2004 @@ -134,11 +134,11 @@ namespace llvm { // RemoveFileOnSignal - The public API -void sys::RemoveFileOnSignal(const std::string &Filename) { +void sys::RemoveFileOnSignal(const sys::Path &Filename) { if (FilesToRemove == 0) FilesToRemove = new std::vector; - FilesToRemove->push_back(Filename); + FilesToRemove->push_back(Filename.get()); std::for_each(IntSigs, IntSigsEnd, RegisterHandler); std::for_each(KillSigs, KillSigsEnd, RegisterHandler); From reid at x10sys.com Sun Nov 14 16:10:46 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:10:46 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/TimeValue.cpp Message-ID: <200411142210.QAA21636@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: TimeValue.cpp updated: 1.1 -> 1.2 --- Log message: Implement the toString method --- Diffs of the changes: (+16 -0) Index: llvm/lib/System/Unix/TimeValue.cpp diff -u llvm/lib/System/Unix/TimeValue.cpp:1.1 llvm/lib/System/Unix/TimeValue.cpp:1.2 --- llvm/lib/System/Unix/TimeValue.cpp:1.1 Sat Sep 25 00:03:54 2004 +++ llvm/lib/System/Unix/TimeValue.cpp Sun Nov 14 16:10:08 2004 @@ -18,5 +18,21 @@ #include "Unix.h" +#include + +namespace llvm { + using namespace sys; + + +std::string TimeValue::toString() { + char buffer[32]; + + time_t ourTime = time_t(this->toEpochTime()); + ::asctime_r(::localtime(&ourTime), buffer); + + std::string result(buffer); + return result.substr(0,24); +} + } // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab From reid at x10sys.com Sun Nov 14 16:11:32 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:11:32 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Unix.h Message-ID: <200411142211.QAA21658@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Unix.h updated: 1.7 -> 1.8 --- Log message: Forget strerror_r, it causes problems. Fix later when threading matters --- Diffs of the changes: (+0 -5) Index: llvm/lib/System/Unix/Unix.h diff -u llvm/lib/System/Unix/Unix.h:1.7 llvm/lib/System/Unix/Unix.h:1.8 --- llvm/lib/System/Unix/Unix.h:1.7 Mon Oct 4 19:56:46 2004 +++ llvm/lib/System/Unix/Unix.h Sun Nov 14 16:10:54 2004 @@ -28,11 +28,6 @@ #include inline void ThrowErrno(const std::string& prefix) { -#if defined __USE_XOPEN2K || defined __USE_MISC char buffer[MAXPATHLEN]; - strerror_r(errno,buffer, MAXPATHLEN); - throw prefix + ": " + buffer; -#else throw prefix + ": " + strerror(errno); -#endif } From llvm at cs.uiuc.edu Sun Nov 14 16:12:18 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Sun, 14 Nov 2004 16:12:18 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Linker.cpp Message-ID: <200411142212.QAA21689@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Linker.cpp (r1.88) removed --- Log message: Moved to lib/Linker --- Diffs of the changes: (+0 -0) From reid at x10sys.com Sun Nov 14 16:13:04 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:13:04 -0600 Subject: [llvm-commits] CVS: llvm/projects/Stacker/tools/stkrc/stkrc.cpp Message-ID: <200411142213.QAA21716@zion.cs.uiuc.edu> Changes in directory llvm/projects/Stacker/tools/stkrc: stkrc.cpp updated: 1.7 -> 1.8 --- Log message: Fix usage of changed function prototype --- Diffs of the changes: (+1 -1) Index: llvm/projects/Stacker/tools/stkrc/stkrc.cpp diff -u llvm/projects/Stacker/tools/stkrc/stkrc.cpp:1.7 llvm/projects/Stacker/tools/stkrc/stkrc.cpp:1.8 --- llvm/projects/Stacker/tools/stkrc/stkrc.cpp:1.7 Sat Sep 4 14:05:53 2004 +++ llvm/projects/Stacker/tools/stkrc/stkrc.cpp Sun Nov 14 16:12:27 2004 @@ -155,7 +155,7 @@ Out = new std::ofstream(OutputFilename.c_str()); // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT - sys::RemoveFileOnSignal(OutputFilename); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } } From reid at x10sys.com Sun Nov 14 16:13:50 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:13:50 -0600 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/crtend/Makefile Message-ID: <200411142213.QAA21753@zion.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/crtend: Makefile updated: 1.19 -> 1.20 --- Log message: Use llvm-ar not ar for constructing archive. Wrap at 80 cols. --- Diffs of the changes: (+12 -4) Index: llvm/runtime/GCCLibraries/crtend/Makefile diff -u llvm/runtime/GCCLibraries/crtend/Makefile:1.19 llvm/runtime/GCCLibraries/crtend/Makefile:1.20 --- llvm/runtime/GCCLibraries/crtend/Makefile:1.19 Sat Oct 30 04:19:36 2004 +++ llvm/runtime/GCCLibraries/crtend/Makefile Sun Nov 14 16:13:13 2004 @@ -39,6 +39,8 @@ install:: $(DESTDIR)$(bytecode_libdir)/libcrtend.a install-bytecode:: $(DESTDIR)$(bytecode_libdir)/libcrtend.a +clean-local:: + $(Verb)$(RM) -f $(CRTEND_A) # The three components described in the README Components := main genericeh sjljeh @@ -48,7 +50,7 @@ # We build libcrtend.a from the four components described in the README. $(CRTEND_A) : $(ComponentLibs) $(LibDir)/.dir $(Echo) Building final libcrtend.a file from components - $(Verb) $(Archive) $@ $(ComponentLibs) + $(Verb) $(LArchive) $@ $(ComponentLibs) MainObj := $(ObjDir)/crtend.bc $(ObjDir)/listend.bc GenericEHObj := $(ObjDir)/Exception.bc @@ -57,14 +59,20 @@ # __main and ctor/dtor support component $(ObjDir)/comp_main.bc: $(MainObj) $(Echo) Linking $(notdir $@) component... - $(Verb) $(GCCLD) -link-as-library -internalize-public-api-file=$(BUILD_SRC_DIR)/comp_main.lst $(MainObj) -o $@ + $(Verb) $(GCCLD) -link-as-library \ + -internalize-public-api-file=$(BUILD_SRC_DIR)/comp_main.lst \ + $(MainObj) -o $@ \ # Generic exception handling support runtime. $(ObjDir)/comp_genericeh.bc: $(GenericEHObj) $(Echo) Linking $(notdir $@) component... - $(Verb) $(GCCLD) -link-as-library -internalize-public-api-file=$(BUILD_SRC_DIR)/comp_genericeh.lst $(GenericEHObj) -o $@ + $(Verb) $(GCCLD) -link-as-library \ + -internalize-public-api-file=$(BUILD_SRC_DIR)/comp_genericeh.lst \ + $(GenericEHObj) -o $@ # setjmp/longjmp exception handling support runtime. $(ObjDir)/comp_sjljeh.bc: $(SJLJEHObj) $(Echo) Linking $(notdir $@) component... - $(Verb) $(GCCLD) -link-as-library -internalize-public-api-file=$(BUILD_SRC_DIR)/comp_sjljeh.lst $(SJLJEHObj) -o $@ + $(Verb) $(GCCLD) -link-as-library \ + -internalize-public-api-file=$(BUILD_SRC_DIR)/comp_sjljeh.lst \ + $(SJLJEHObj) -o $@ From reid at x10sys.com Sun Nov 14 16:14:36 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:14:36 -0600 Subject: [llvm-commits] CVS: llvm/tools/Makefile Message-ID: <200411142214.QAA21784@zion.cs.uiuc.edu> Changes in directory llvm/tools: Makefile updated: 1.34 -> 1.35 --- Log message: Add the llvm-ranlib tool --- Diffs of the changes: (+1 -1) Index: llvm/tools/Makefile diff -u llvm/tools/Makefile:1.34 llvm/tools/Makefile:1.35 --- llvm/tools/Makefile:1.34 Wed Oct 27 22:53:02 2004 +++ llvm/tools/Makefile Sun Nov 14 16:13:59 2004 @@ -10,7 +10,7 @@ LEVEL := .. PARALLEL_DIRS := llvm-as llvm-dis opt gccas llc llvm-link lli gccld llvm-stub \ analyze extract bugpoint llvm-nm llvm-prof llvm-db \ - llvm-ar llvm-bcanalyzer llee llvmc llvm-ld + llvm-ar llvm-ranlib llvm-bcanalyzer llee llvmc llvm-ld EXTRA_DIST := Makefile.JIT From reid at x10sys.com Sun Nov 14 16:15:22 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:15:22 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccas/gccas.cpp Message-ID: <200411142215.QAA21821@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccas: gccas.cpp updated: 1.102 -> 1.103 --- Log message: Fix usage of changed function prototype --- Diffs of the changes: (+1 -1) Index: llvm/tools/gccas/gccas.cpp diff -u llvm/tools/gccas/gccas.cpp:1.102 llvm/tools/gccas/gccas.cpp:1.103 --- llvm/tools/gccas/gccas.cpp:1.102 Mon Nov 8 11:37:04 2004 +++ llvm/tools/gccas/gccas.cpp Sun Nov 14 16:14:45 2004 @@ -159,7 +159,7 @@ // Make sure that the Out file gets unlinked from the disk if we get a // signal - sys::RemoveFileOnSignal(OutputFilename); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } From llvm at cs.uiuc.edu Sun Nov 14 16:16:08 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Sun, 14 Nov 2004 16:16:08 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccld/Linker.cpp Message-ID: <200411142216.QAA21850@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: Linker.cpp (r1.30) removed --- Log message: Moved to lib/Linker --- Diffs of the changes: (+0 -0) From reid at x10sys.com Sun Nov 14 16:16:54 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:16:54 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccld/Makefile Message-ID: <200411142216.QAA21869@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: Makefile updated: 1.9 -> 1.10 --- Log message: This tool needs the libLLVMArchive library now. --- Diffs of the changes: (+4 -3) Index: llvm/tools/gccld/Makefile diff -u llvm/tools/gccld/Makefile:1.9 llvm/tools/gccld/Makefile:1.10 --- llvm/tools/gccld/Makefile:1.9 Wed Oct 27 18:18:45 2004 +++ llvm/tools/gccld/Makefile Sun Nov 14 16:16:17 2004 @@ -10,8 +10,9 @@ LEVEL = ../.. TOOLNAME = gccld -USEDLIBS = LLVMipo.a LLVMTransforms.a LLVMScalarOpts.a LLVMAnalysis.a LLVMipa.a \ - LLVMTransformUtils.a LLVMTarget.a LLVMBCReader LLVMBCWriter LLVMCore \ - LLVMSupport.a LLVMSystem.a +USEDLIBS = LLVMipo.a LLVMTransforms.a LLVMScalarOpts.a LLVMAnalysis.a \ + LLVMipa.a LLVMTransformUtils.a LLVMTarget.a LLVMLinker.a \ + LLVMArchive.a LLVMBCReader LLVMBCWriter \ + LLVMCore LLVMSupport.a LLVMSystem.a include $(LEVEL)/Makefile.common From reid at x10sys.com Sun Nov 14 16:17:40 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:17:40 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccld/gccld.cpp Message-ID: <200411142217.QAA21902@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: gccld.cpp updated: 1.78 -> 1.79 --- Log message: Provide exception handling --- Diffs of the changes: (+123 -109) Index: llvm/tools/gccld/gccld.cpp diff -u llvm/tools/gccld/gccld.cpp:1.78 llvm/tools/gccld/gccld.cpp:1.79 --- llvm/tools/gccld/gccld.cpp:1.78 Wed Sep 1 17:55:37 2004 +++ llvm/tools/gccld/gccld.cpp Sun Nov 14 16:17:03 2004 @@ -157,120 +157,134 @@ cl::ParseCommandLineOptions(argc, argv, " llvm linker for GCC\n"); sys::PrintStackTraceOnErrorSignal(); - std::string ModuleID("gccld-output"); - std::auto_ptr Composite(new Module(ModuleID)); + int exitCode = 0; - // We always look first in the current directory when searching for libraries. - LibPaths.insert(LibPaths.begin(), "."); - - // If the user specified an extra search path in their environment, respect - // it. - if (char *SearchPath = getenv("LLVM_LIB_SEARCH_PATH")) - LibPaths.push_back(SearchPath); - - // Remove any consecutive duplicates of the same library... - Libraries.erase(std::unique(Libraries.begin(), Libraries.end()), - Libraries.end()); - - // Link in all of the files - if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose)) - return 1; // Error already printed - - if (!LinkAsLibrary) - LinkLibraries(argv[0], Composite.get(), Libraries, LibPaths, - Verbose, Native); - - // Link in all of the libraries next... - - // Create the output file. - std::string RealBytecodeOutput = OutputFilename; - if (!LinkAsLibrary) RealBytecodeOutput += ".bc"; - std::ofstream Out(RealBytecodeOutput.c_str()); - if (!Out.good()) - return PrintAndReturn(argv[0], "error opening '" + RealBytecodeOutput + - "' for writing!"); - - // Ensure that the bytecode file gets removed from the disk if we get a - // SIGINT signal. - sys::RemoveFileOnSignal(RealBytecodeOutput); + try { + std::string ModuleID("gccld-output"); + std::auto_ptr Composite(new Module(ModuleID)); + + // We always look first in the current directory when searching for libraries. + LibPaths.insert(LibPaths.begin(), "."); + + // If the user specified an extra search path in their environment, respect + // it. + if (char *SearchPath = getenv("LLVM_LIB_SEARCH_PATH")) + LibPaths.push_back(SearchPath); + + // Remove any consecutive duplicates of the same library... + Libraries.erase(std::unique(Libraries.begin(), Libraries.end()), + Libraries.end()); + + // Link in all of the files + if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose)) + return 1; // Error already printed + + if (!LinkAsLibrary) + LinkLibraries(argv[0], Composite.get(), Libraries, LibPaths, + Verbose, Native); + + // Link in all of the libraries next... + + // Create the output file. + std::string RealBytecodeOutput = OutputFilename; + if (!LinkAsLibrary) RealBytecodeOutput += ".bc"; + std::ofstream Out(RealBytecodeOutput.c_str()); + if (!Out.good()) + return PrintAndReturn(argv[0], "error opening '" + RealBytecodeOutput + + "' for writing!"); + + // Ensure that the bytecode file gets removed from the disk if we get a + // SIGINT signal. + sys::RemoveFileOnSignal(sys::Path(RealBytecodeOutput)); + + // Generate the bytecode file. + if (GenerateBytecode(Composite.get(), Strip, !NoInternalize, &Out)) { + Out.close(); + return PrintAndReturn(argv[0], "error generating bytecode"); + } - // Generate the bytecode file. - if (GenerateBytecode(Composite.get(), Strip, !NoInternalize, &Out)) { + // Close the bytecode file. Out.close(); - return PrintAndReturn(argv[0], "error generating bytecode"); - } - - // Close the bytecode file. - Out.close(); - - // If we are not linking a library, generate either a native executable - // or a JIT shell script, depending upon what the user wants. - if (!LinkAsLibrary) { - // If the user wants to generate a native executable, compile it from the - // bytecode file. - // - // Otherwise, create a script that will run the bytecode through the JIT. - if (Native) { - // Name of the Assembly Language output file - std::string AssemblyFile = OutputFilename + ".s"; - - // Mark the output files for removal if we get an interrupt. - sys::RemoveFileOnSignal(AssemblyFile); - sys::RemoveFileOnSignal(OutputFilename); - - // Determine the locations of the llc and gcc programs. - std::string llc = FindExecutable("llc", argv[0]); - std::string gcc = FindExecutable("gcc", argv[0]); - if (llc.empty()) - return PrintAndReturn(argv[0], "Failed to find llc"); - - if (gcc.empty()) - return PrintAndReturn(argv[0], "Failed to find gcc"); - - // Generate an assembly language file for the bytecode. - if (Verbose) std::cout << "Generating Assembly Code\n"; - GenerateAssembly(AssemblyFile, RealBytecodeOutput, llc, envp); - if (Verbose) std::cout << "Generating Native Code\n"; - GenerateNative(OutputFilename, AssemblyFile, Libraries, LibPaths, - gcc, envp); - - // Remove the assembly language file. - removeFile (AssemblyFile); - } else if (NativeCBE) { - std::string CFile = OutputFilename + ".cbe.c"; - - // Mark the output files for removal if we get an interrupt. - sys::RemoveFileOnSignal(CFile); - sys::RemoveFileOnSignal(OutputFilename); - - // Determine the locations of the llc and gcc programs. - std::string llc = FindExecutable("llc", argv[0]); - std::string gcc = FindExecutable("gcc", argv[0]); - if (llc.empty()) - return PrintAndReturn(argv[0], "Failed to find llc"); - if (gcc.empty()) - return PrintAndReturn(argv[0], "Failed to find gcc"); - - // Generate an assembly language file for the bytecode. - if (Verbose) std::cout << "Generating Assembly Code\n"; - GenerateCFile(CFile, RealBytecodeOutput, llc, envp); - if (Verbose) std::cout << "Generating Native Code\n"; - GenerateNative(OutputFilename, CFile, Libraries, LibPaths, gcc, envp); - - // Remove the assembly language file. - removeFile(CFile); - } else { - EmitShellScript(argv); + // If we are not linking a library, generate either a native executable + // or a JIT shell script, depending upon what the user wants. + if (!LinkAsLibrary) { + // If the user wants to generate a native executable, compile it from the + // bytecode file. + // + // Otherwise, create a script that will run the bytecode through the JIT. + if (Native) { + // Name of the Assembly Language output file + std::string AssemblyFile = OutputFilename + ".s"; + + // Mark the output files for removal if we get an interrupt. + sys::RemoveFileOnSignal(sys::Path(AssemblyFile)); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); + + // Determine the locations of the llc and gcc programs. + std::string llc = FindExecutable("llc", argv[0]); + std::string gcc = FindExecutable("gcc", argv[0]); + if (llc.empty()) + return PrintAndReturn(argv[0], "Failed to find llc"); + + if (gcc.empty()) + return PrintAndReturn(argv[0], "Failed to find gcc"); + + // Generate an assembly language file for the bytecode. + if (Verbose) std::cout << "Generating Assembly Code\n"; + GenerateAssembly(AssemblyFile, RealBytecodeOutput, llc, envp); + if (Verbose) std::cout << "Generating Native Code\n"; + GenerateNative(OutputFilename, AssemblyFile, Libraries, LibPaths, + gcc, envp); + + // Remove the assembly language file. + removeFile (AssemblyFile); + } else if (NativeCBE) { + std::string CFile = OutputFilename + ".cbe.c"; + + // Mark the output files for removal if we get an interrupt. + sys::RemoveFileOnSignal(sys::Path(CFile)); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); + + // Determine the locations of the llc and gcc programs. + std::string llc = FindExecutable("llc", argv[0]); + std::string gcc = FindExecutable("gcc", argv[0]); + if (llc.empty()) + return PrintAndReturn(argv[0], "Failed to find llc"); + if (gcc.empty()) + return PrintAndReturn(argv[0], "Failed to find gcc"); + + // Generate an assembly language file for the bytecode. + if (Verbose) std::cout << "Generating Assembly Code\n"; + GenerateCFile(CFile, RealBytecodeOutput, llc, envp); + if (Verbose) std::cout << "Generating Native Code\n"; + GenerateNative(OutputFilename, CFile, Libraries, LibPaths, gcc, envp); + + // Remove the assembly language file. + removeFile(CFile); + + } else { + EmitShellScript(argv); + } + + // Make the script executable... + MakeFileExecutable(OutputFilename); + + // Make the bytecode file readable and directly executable in LLEE as well + MakeFileExecutable(RealBytecodeOutput); + MakeFileReadable(RealBytecodeOutput); } - - // Make the script executable... - MakeFileExecutable(OutputFilename); - - // Make the bytecode file readable and directly executable in LLEE as well - MakeFileExecutable(RealBytecodeOutput); - MakeFileReadable(RealBytecodeOutput); + } catch (const char*msg) { + std::cerr << argv[0] << ": " << msg << "\n"; + exitCode = 1; + } catch (const std::string& msg) { + std::cerr << argv[0] << ": " << msg << "\n"; + exitCode = 2; + } catch (...) { + // This really shouldn't happen, but just in case .... + std::cerr << argv[0] << ": An nexpected unknown exception occurred.\n"; + exitCode = 3; } - return 0; + return exitCode; } From reid at x10sys.com Sun Nov 14 16:18:27 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:18:27 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccld/gccld.h Message-ID: <200411142218.QAA21932@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: gccld.h updated: 1.9 -> 1.10 --- Log message: Remove linking declarations (in Linker.h now) --- Diffs of the changes: (+1 -23) Index: llvm/tools/gccld/gccld.h diff -u llvm/tools/gccld/gccld.h:1.9 llvm/tools/gccld/gccld.h:1.10 --- llvm/tools/gccld/gccld.h:1.9 Tue Jun 1 19:22:24 2004 +++ llvm/tools/gccld/gccld.h Sun Nov 14 16:17:49 2004 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Module.h" +#include "llvm/Linker.h" #include #include @@ -19,12 +20,6 @@ namespace llvm { -void -GetAllDefinedSymbols (Module *M, std::set &DefinedSymbols); - -void -GetAllUndefinedSymbols(Module *M, std::set &UndefinedSymbols); - int GenerateBytecode (Module * M, bool Strip, @@ -47,21 +42,4 @@ const std::string & gcc, char ** const envp); -std::auto_ptr -LoadObject (const std::string & FN, std::string &OutErrorMessage); - -std::string FindLib(const std::string &Filename, - const std::vector &Paths, - bool SharedObjectOnly = false); - -void LinkLibraries (const char * progname, Module* HeadModule, - const std::vector & Libraries, - const std::vector & LibPaths, - bool Verbose, bool Native); -bool -LinkFiles (const char * progname, - Module * HeadModule, - const std::vector & Files, - bool Verbose); - } // End llvm namespace From reid at x10sys.com Sun Nov 14 16:19:13 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:19:13 -0600 Subject: [llvm-commits] CVS: llvm/tools/llc/llc.cpp Message-ID: <200411142219.QAA21974@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: llc.cpp updated: 1.102 -> 1.103 --- Log message: Fix usage of changed function prototype --- Diffs of the changes: (+2 -2) Index: llvm/tools/llc/llc.cpp diff -u llvm/tools/llc/llc.cpp:1.102 llvm/tools/llc/llc.cpp:1.103 --- llvm/tools/llc/llc.cpp:1.102 Wed Sep 1 17:55:37 2004 +++ llvm/tools/llc/llc.cpp Sun Nov 14 16:18:35 2004 @@ -115,7 +115,7 @@ // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT - sys::RemoveFileOnSignal(OutputFilename); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } else { Out = &std::cout; } @@ -148,7 +148,7 @@ // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT - sys::RemoveFileOnSignal(OutputFilename); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } } From reid at x10sys.com Sun Nov 14 16:19:59 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:19:59 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ar/Makefile Message-ID: <200411142219.QAA22000@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ar: Makefile updated: 1.4 -> 1.5 --- Log message: This tool needs the libLLVMArchive library now. --- Diffs of the changes: (+6 -1) Index: llvm/tools/llvm-ar/Makefile diff -u llvm/tools/llvm-ar/Makefile:1.4 llvm/tools/llvm-ar/Makefile:1.5 --- llvm/tools/llvm-ar/Makefile:1.4 Wed Oct 27 18:18:45 2004 +++ llvm/tools/llvm-ar/Makefile Sun Nov 14 16:19:21 2004 @@ -9,6 +9,11 @@ LEVEL = ../.. TOOLNAME = llvm-ar -USEDLIBS = LLVMBCReader LLVMCore LLVMSupport.a LLVMSystem.a +USEDLIBS = LLVMArchive.a LLVMBCReader LLVMCore LLVMSupport.a LLVMSystem.a include $(LEVEL)/Makefile.common + +check-local:: + $(ToolDir)/llvm-ar zRrS nada.a . + $(ToolDir)/llvm-ar tv nada.a | grep Debug/llvm-ar.d >/dev/null 2>&1 + $(RM) -f nada.a From reid at x10sys.com Sun Nov 14 16:20:45 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:20:45 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ar/llvm-ar.cpp Message-ID: <200411142220.QAA22037@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ar: llvm-ar.cpp updated: 1.15 -> 1.16 --- Log message: Total rewrite using Archive library & new functionality --- Diffs of the changes: (+637 -483) Index: llvm/tools/llvm-ar/llvm-ar.cpp diff -u llvm/tools/llvm-ar/llvm-ar.cpp:1.15 llvm/tools/llvm-ar/llvm-ar.cpp:1.16 --- llvm/tools/llvm-ar/llvm-ar.cpp:1.15 Wed Sep 1 17:55:37 2004 +++ llvm/tools/llvm-ar/llvm-ar.cpp Sun Nov 14 16:20:07 2004 @@ -2,559 +2,713 @@ // // 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 file was developed by the Reid Spencer based on the original design by +// Tanya Lattner and is distributed by the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// Builds up standard unix archive files (.a) containing LLVM bytecode. +// Builds up (relatively) standard unix archive files (.a) containing LLVM +// bytecode or other files. // //===----------------------------------------------------------------------===// #include "llvm/Module.h" -#include "llvm/Bytecode/Reader.h" +#include "llvm/Bytecode/Archive.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Compressor.h" #include "llvm/Support/FileUtilities.h" #include "llvm/System/Signals.h" -#include -#include #include -#include -#include -#include -#include -#include -#include -using namespace llvm; - -using std::string; - - -#define ARFMAG "\n" /* header trailer string */ -#define ARMAG "!\n" /* magic string */ -#define SARMAG 8 /* length of magic string */ -#define VERSION "llvm-ar is a part of the LLVM compiler infrastructure.\nPlease see http://llvm.cs.uiuc.edu for more information.\n"; +#include +#include +using namespace llvm; -// Each file member is preceded by a file member header. Which is -// of the following format: -// -// char ar_name[16] - '/' terminated file member name. -// If the file name does not fit, a dummy name is used. -// char ar_date[12] - file date in decimal -// char ar_uid[6] - User id of file owner in decimal. -// char ar_gid[6] - Group ID file belongs to in decimal. -// char ar_mode[8] - File mode in octal. -// char ar_size[10] - Size of file in decimal. -// char ar_fmag[2] - Trailer of header file, a newline. -struct ar_hdr { - char name[16]; - char date[12]; - char uid[6]; - char gid[6]; - char mode[8]; - char size[10]; - char fmag[2]; - void init() { - memset(name,' ',16); - memset(date,' ',12); - memset(uid,' ',6); - memset(gid,' ',6); - memset(mode,' ',8); - memset(size,' ',10); - memset(fmag,' ',2); - } +// Option for compatibility with ASIX, not used but must allow it to be present. +cl::opt +X32Option ("X32_64", cl::desc("Ignored option for compatibility with AIX")); + +// llvm-ar operation code and modifier flags. This must come first +cl::opt +Options(cl::Positional, cl::Required, cl::desc("{operation}[modifiers]...")); + +// llvm-ar remaining positional arguments +cl::list +RestOfArgs(cl::Positional, cl::OneOrMore, + cl::desc("[relpos] [count] [members]...")); + +// This enumeration delineates the kinds of operations on an archive +// that are permitted. +enum ArchiveOperation { + NoOperation, ///< An operation hasn't been specified + Print, ///< Print the contents of the archive + Delete, ///< Delete the specified members + Move, ///< Move members to end or as given by {a,b,i} modifiers + QuickAppend, ///< Quickly append to end of archive + ReplaceOrInsert, ///< Replace or Insert members + DisplayTable, ///< Display the table of contents + Extract, ///< Extract files back to file system }; - -//Option for X32_64, not used but must allow it to be present. -cl::opt X32Option ("X32_64", cl::desc("Ignored option spelt -X32_64, for compatibility with AIX"), cl::Optional); - -//llvm-ar options -cl::opt Options(cl::Positional, cl::desc("{dmpqrstx}[abcfilNoPsSuvV] "), cl::Required); - -//llvm-ar options -cl::list RestofArgs(cl::Positional, cl::desc("[relpos] [count]] [members..]"), cl::Optional); - -//booleans to represent Operation, only one can be preformed at a time -bool Print, Delete, Move, QuickAppend, InsertWithReplacement, DisplayTable; -bool Extract; - -//Modifiers to follow operation to vary behavior -bool AddAfter, AddBefore, Create, TruncateNames, InsertBefore, UseCount; -bool OriginalDates, FullPath, SymTable, OnlyUpdate, Verbose; - -//Realtive Pos Arg -string RelPos; - -//Count, use for multiple entries in the archive with the same name -int Count; - -//Archive -string Archive; - -//Member Files -std::vector Members; - - -// WriteSymbolTable - Writes symbol table to ArchiveFile, return false -// on errors. Also returns by reference size of symbol table. -// -// Overview of method: -// 1) Generate the header for the symbol table. This is a normal -// archive member header, but it has a zero length name. -// 2) For each archive member file, stat the file and parse the bytecode -// Store cumulative offset (file size + header size). -// 3) Loop over all the symbols for the current member file, -// add offset entry to offset vector, and add symbol name to its vector. -// Note: The symbol name vector is a vector of chars to speed up calculating -// the total size of the symbol table. -// 4) Update offset vector once we know the total size of symbol table. This is -// because the symbol table appears before all archive member file contents. -// We add the size of magic string, and size of symbol table to each offset. -// 5) If the new updated offset it not even, we add 1 byte to offset because -// a newline will be inserted when writing member files. This adjustment is -// cummulative (ie. each time we have an odd offset we add 1 to total adjustment). -// 6) Lastly, write symbol table to file. -// -bool WriteSymbolTable(std::ofstream &ArchiveFile) { - - //Create header for symbol table. This is essentially an empty header with the - //name set to a '/' to indicate its a symbol table. - ar_hdr Hdr; - Hdr.init(); - - //Name of symbol table is '/' - Hdr.name[0] = '/'; - Hdr.name[1] = '\0'; - - //Set the header trailer to a newline - memcpy(Hdr.fmag,ARFMAG,sizeof(ARFMAG)); - - - //Write header to archive file - ArchiveFile.write((char*)&Hdr, sizeof(Hdr)); - - - unsigned memoff = 0; //Keep Track of total size of files added to archive - std::vector offsets; //Vector of offsets into archive file - std::vector names; //Vector of characters that are the symbol names. - - //Loop over archive member files, parse bytecode, and generate symbol table. - for(unsigned i=0; ibegin(), E=M->end(); I != E; ++I) { - - //get function name - string NM = ((Function*)I)->getName(); - - //Loop over the characters in the name and add to symbol name vector - for(unsigned i=0; i> 24) & 255; - num[1] = (temp >> 16) & 255; - num[2] = (temp >> 8) & 255; - num[3] = temp & 255; - - //Write number of symbols to archive file - ArchiveFile.write(num,4); - - //Adjustment to offset to start files on even byte boundaries - unsigned adjust = 0; - - //Update offsets write symbol table to archive. - for(unsigned i=0; i> 24) & 255; - output[1] = (offsets[i] >> 16) & 255; - output[2] = (offsets[i] >> 8) & 255; - output[3] = offsets[i] & 255; - ArchiveFile.write(output,4); - } - - - //Write out symbol name vector. - for(unsigned i=0; i Members; + +// This variable holds the (possibly expanded) list of path objects that +// correspond to files we will +sys::Path::Vector Paths; + +// The Archive object to which all the editing operations will be sent. +Archive* TheArchive = 0; + +// printMoreHelp - Provide additional help output explaining the operations and +// modifiers of llvm-ar. This function is called by the CommandLine library +// when the --help option is given because we set the global cl::MoreHelp +// variable to the address of this function. +void printMoreHelp() { + std::cout + << "\nOPERATIONS:\n" + << " d[NsS] - delete file(s) from the archive\n" + << " m[abiSs] - move file(s) in the archive\n" + << " p[kN] - print file(s) found in the archive\n" + << " q[ufsS] - quick append file(s) to the archive\n" + << " r[abfiuzRsS] - replace or insert file(s) into the archive\n" + << " t - display contents of archive\n" + << " x[No] - extract file(s) from the archive\n"; + + std::cout + << "\nMODIFIERS (operation specific):\n" + << " [a] - put file(s) after [relpos]\n" + << " [b] - put file(s) before [relpos] (same as [i])\n" + << " [f] - truncate inserted file names\n" + << " [i] - put file(s) before [relpos] (same as [b])\n" + << " [k] - always print bytecode files (default is to skip them)\n" + << " [N] - use instance [count] of name\n" + << " [o] - preserve original dates\n" + << " [P] - use full path names when matching\n" + << " [R] - recurse through directories when inserting\n" + << " [s] - create an archive index (cf. ranlib)\n" + << " [S] - do not build a symbol table\n" + << " [u] - update only files newer than archive contents\n" + << " [z] - compress files before inserting/extracting\n"; + + std::cout + << "\nMODIFIERS (generic):\n" + << " [c] - do not warn if the library had to be created\n" + << " [v] - be verbose about actions taken\n" + << " [V] - be *really* verbose about actions taken\n"; } -//Print out usage for errors in command line +// printUse - Print out our usage information. This is used in cases where the +// user has made a mistake on the command line syntax. void printUse() { - std::cout << "USAGE: ar [-X32_64] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file [files..]\n\n"; + std::cout + << "OVERVIEW: LLVM Archiver (llvm-ar)\n\n" + << " This program archives bytecode files into single libraries\n\n" + << "USAGE: llvm-ar [-X32_64] [-]{operation}[modifiers]... " + << "[relpos] [count] archive-file [files..]\n"; - std::cout << "commands:\n" << - "d - delete file(s) from the archive\n" - << "m[ab] - move file(s) in the archive\n" - << "p - print file(s) found in the archive\n" - << "q[f] - quick append file(s) to the archive\n" - << "r[ab][f][u] - replace existing or insert new file(s) into the archive\n" - << "t - display contents of archive\n" - << "x[o] - extract file(s) from the archive\n"; - - std::cout << "\ncommand specific modifiers:\n" - << "[a] - put file(s) after [member-name]\n" - << "[b] - put file(s) before [member-name] (same as [i])\n" - << "[N] - use instance [count] of name\n" - << "[f] - truncate inserted file names\n" - << "[P] - use full path names when matching\n" - << "[o] - preserve original dates\n" - << "[u] - only replace files that are newer than current archive contents\n"; - - std::cout << "generic modifiers:\n" - << "[c] - do not warn if the library had to be created\n" - << "[s] - create an archive index (cf. ranlib)\n" - << "[S] - do not build a symbol table\n" - << "[v] - be verbose\n" - << "[V] - display the version number\n"; + printMoreHelp(); exit(1); } - -//Print version -void printVersion() { - std::cout << VERSION; - exit(0); -} - -//Extract the memberfile name from the command line +// getRelPos - Extract the member filename from the command line for +// the [relpos] argument associated with a, b, and i modifiers void getRelPos() { - if(RestofArgs.size() > 0) { - RelPos = RestofArgs[0]; - RestofArgs.erase(RestofArgs.begin()); + if(RestOfArgs.size() > 0) { + RelPos = RestOfArgs[0]; + RestOfArgs.erase(RestOfArgs.begin()); } - //Throw error if needed and not present else - printUse(); + throw "Expected [relpos] for a, b, or i modifier"; } -//Extract count from the command line +// getCount - Extract the [count] argument associated with the N modifier +// from the command line and check its value. void getCount() { - if(RestofArgs.size() > 0) { - Count = atoi(RestofArgs[0].c_str()); - RestofArgs.erase(RestofArgs.begin()); + if(RestOfArgs.size() > 0) { + Count = atoi(RestOfArgs[0].c_str()); + RestOfArgs.erase(RestOfArgs.begin()); } - //Throw error if needed and not present else - printUse(); + throw "Expected [count] value with N modifier"; + + // Non-positive counts are not allowed + if (Count < 1) + throw "Invalid [count] value (not a positive integer)"; } -//Get the Archive File Name from the command line +// getArchive - Get the archive file name from the command line void getArchive() { - std::cerr << RestofArgs.size() << "\n"; - if(RestofArgs.size() > 0) { - Archive = RestofArgs[0]; - RestofArgs.erase(RestofArgs.begin()); + if(RestOfArgs.size() > 0) { + ArchiveName = RestOfArgs[0]; + RestOfArgs.erase(RestOfArgs.begin()); } - //Throw error if needed and not present else - printUse(); + throw "An archive name must be specified."; } - -//Copy over remaining items in RestofArgs to our Member File vector. -//This is just for clarity. +// getMembers - Copy over remaining items in RestOfArgs to our Members vector +// This is just for clarity. void getMembers() { - std::cerr << RestofArgs.size() << "\n"; - if(RestofArgs.size() > 0) - Members = std::vector(RestofArgs); + if(RestOfArgs.size() > 0) + Members = std::vector(RestOfArgs); } -// Parse the operations and operation modifiers -// FIXME: Not all of these options has been implemented, but we still -// do all the command line parsing for them. -void parseCL() { +// parseCommandLine - Parse the command line options as presented and return the +// operation specified. Process all modifiers and check to make sure that +// constraints on modifier/operation pairs have not been violated. +ArchiveOperation parseCommandLine() { - //Keep track of number of operations. We can only specify one - //per execution + // Keep track of number of operations. We can only specify one + // per execution. unsigned NumOperations = 0; + // Keep track of the number of positional modifiers (a,b,i). Only + // one can be specified. + unsigned NumPositional = 0; + + // Keep track of which operation was requested + ArchiveOperation Operation = NoOperation; + for(unsigned i=0; i 1) - printUse(); - + // At this point, the next thing on the command line must be + // the archive name. getArchive(); + + // Everything on the command line at this point is a member. getMembers(); + // Perform various checks on the operation/modifier specification + // to make sure we are dealing with a legal request. + if (NumOperations == 0) + throw "You must specify at least one of the operations"; + if (NumOperations > 1) + throw "Only one operation may be specified"; + if (NumPositional > 1) + throw "You may only specify one of a, b, and i modifiers"; + if (AddAfter || AddBefore || InsertBefore) + if (Operation != Move && Operation != ReplaceOrInsert) + throw "The 'a', 'b' and 'i' modifiers can only be specified with " + "the 'm' or 'r' operations"; + if (RecurseDirectories && Operation != ReplaceOrInsert) + throw "The 'R' modifiers is only applicabe to the 'r' operation"; + if (OriginalDates && Operation != Extract) + throw "The 'o' modifier is only applicable to the 'x' operation"; + if (TruncateNames && Operation!=QuickAppend && Operation!=ReplaceOrInsert) + throw "The 'f' modifier is only applicable to the 'q' and 'r' operations"; + if (OnlyUpdate && Operation != ReplaceOrInsert) + throw "The 'u' modifier is only applicable to the 'r' operation"; + if (Compression && Operation!=ReplaceOrInsert && Operation!=Extract) + throw "The 'z' modifier is only applicable to the 'r' and 'x' operations"; + if (Count > 1 && Members.size() > 1) + throw "Only one member name may be specified with the 'N' modifier"; + + // Return the parsed operation to the caller + return Operation; +} + +// recurseDirectories - Implements the "R" modifier. This function scans through +// the Paths vector (built by buildPaths, below) and replaces any directories it +// finds with all the files in that directory (recursively). It uses the +// sys::Path::getDirectoryContent method to perform the actual directory scans. +sys::Path::Vector recurseDirectories(const sys::Path& path) { + assert(path.isDirectory() && "Oops, can't recurse a file"); + sys::Path::Vector result; + if (RecurseDirectories) { + sys::Path::Vector content; + path.getDirectoryContents(content); + for (sys::Path::Vector::iterator I = content.begin(), E = content.end(); + I != E; ++I) { + if (I->isDirectory()) { + sys::Path::Vector moreResults = recurseDirectories(*I); + result.insert(result.begin(), moreResults.begin(), moreResults.end()); + } else { + result.push_back(*I); + } + } + } + return result; +} + +// buildPaths - Convert the strings in the Members vector to sys::Path objects +// and make sure they are valid and exist exist. This check is only needed for +// the operations that add/replace files to the archive ('q' and 'r') +void buildPaths(bool checkExistence = true) { + for (unsigned i = 0; i < Members.size(); i++) { + sys::Path aPath; + if (!aPath.setFile(Members[i])) + throw std::string("File member name invalid: ") + Members[i]; + if (checkExistence) { + if (!aPath.exists()) + throw std::string("File does not exist: ") + Members[i]; + sys::Path::StatusInfo si; + aPath.getStatusInfo(si); + if (si.isDir) { + sys::Path::Vector dirpaths = recurseDirectories(aPath); + Paths.insert(Paths.end(),dirpaths.begin(),dirpaths.end()); + } else { + Paths.push_back(aPath); + } + } else { + Paths.push_back(aPath); + } + } +} + +// doPrint - Implements the 'p' operation. This function traverses the archive +// looking for members that match the path list. It is careful to uncompress +// things that should be and to skip bytecode files unless the 'k' modifier was +// given. +void doPrint() { + buildPaths(false); + unsigned countDown = Count; + for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end(); + I != E; ++I ) { + if (Paths.empty() || + (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end())) { + if (countDown == 1) { + const char* data = reinterpret_cast(I->getData()); + + // Skip things that don't make sense to print + if (I->isLLVMSymbolTable() || I->isForeignSymbolTable() || + (!DontSkipBytecode && + (I->isBytecode() || I->isCompressedBytecode()))) + continue; + + if (Verbose) + std::cout << "Printing " << I->getPath().get() << "\n"; + + if (I->isCompressedBytecode()) + Compressor::decompressToFile(data+4,I->getSize()-4,std::cout); + else if (I->isCompressed()) { + Compressor::decompressToFile(data,I->getSize(),std::cout); + } else { + unsigned len = I->getSize(); + std::cout.write(data, len); + } + } else { + countDown--; + } + } + } +} + +// putMode - utility function for printing out the file mode when the 't' +// operation is in verbose mode. +void putMode(unsigned mode) { + if (mode & 004) + std::cout << "r"; + else + std::cout << "-"; + if (mode & 002) + std::cout << "w"; + else + std::cout << "-"; + if (mode & 001) + std::cout << "x"; + else + std::cout << "-"; +} + +// doDisplayTable - Implement the 't' operation. This function prints out just +// the file names of each of the members. However, if verbose mode is requested +// ('v' modifier) then the file type, permission mode, user, group, size, and +// modification time are also printed. +void doDisplayTable() { + buildPaths(false); + for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end(); + I != E; ++I ) { + if (Paths.empty() || + (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end())) { + if (Verbose) { + // FIXME: Output should be this format: + // Zrw-r--r-- 500/ 500 525 Nov 8 17:42 2004 Makefile + if (I->isBytecode()) + std::cout << "b"; + else if (I->isCompressedBytecode()) + std::cout << "B"; + else if (I->isForeignSymbolTable()) + std::cout << "s"; + else if (I->isLLVMSymbolTable()) + std::cout << "S"; + else if (I->isCompressed()) + std::cout << "Z"; + else + std::cout << " "; + unsigned mode = I->getMode(); + putMode((mode >> 6) & 007); + putMode((mode >> 3) & 007); + putMode(mode & 007); + std::cout << " " << std::setw(4) << I->getUser(); + std::cout << "/" << std::setw(4) << I->getGroup(); + std::cout << " " << std::setw(8) << I->getSize(); + std::cout << " " << std::setw(20) << + I->getModTime().ToString().substr(4); + std::cout << " " << I->getPath().get() << "\n"; + } else { + std::cout << I->getPath().get() << "\n"; + } + } + } + if (ReallyVerbose) { + std::cout << "\nArchive Symbol Table:\n"; + const Archive::SymTabType& symtab = TheArchive->getSymbolTable(); + for (Archive::SymTabType::const_iterator I=symtab.begin(), E=symtab.end(); + I != E; ++I ) { + unsigned offset = TheArchive->getFirstFileOffset() + I->second; + std::cout << " " << std::setw(9) << offset << "\t" << I->first <<"\n"; + } + } +} + +// doExtract - Implement the 'x' operation. This function extracts files back to +// the file system, making sure to uncompress any that were compressed. +void doExtract() { + buildPaths(false); + unsigned countDown = Count; + for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end(); + I != E; ++I ) { + if (Paths.empty() || + (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end())) { + + // Make sure the intervening directories are created + if (I->hasPath()) { + sys::Path dirs(I->getPath()); + dirs.elideFile(); + dirs.createDirectory(/*create_parents=*/true); + } + + // Open up a file stream for writing + std::ofstream file(I->getPath().c_str()); + + // Get the data and its length + const char* data = reinterpret_cast(I->getData()); + unsigned len = I->getSize(); + + // Write the data, making sure to uncompress things first + if (I->isCompressed()) { + Compressor::decompressToFile(data,len,file); + } else { + file.write(data,len); + } + file.close(); + + // If we're supposed to retain the original modification times, etc. do so + // now. + if (OriginalDates) + I->getPath().setStatusInfo(I->getStatusInfo()); + } + } +} + +// doDelete - Implement the delete operation. This function deletes zero or more +// members from the archive. Note that if the count is specified, there should +// be no more than one path in the Paths list or else this algorithm breaks. +// That check is enforced in parseCommandLine (above). +void doDelete() { + buildPaths(false); + if (Paths.empty()) return; + unsigned countDown = Count; + for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end(); + I != E; ) { + if (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end()) { + if (countDown == 1) { + Archive::iterator J = I; + ++I; + TheArchive->remove(J); + } else + countDown--; + } else { + ++I; + } + } + + // We're done editting, reconstruct the archive. + TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ReallyVerbose); } +// doMore - Implement the move operation. This function re-arranges just the +// order of the archive members so that when the archive is written the move +// of the members is accomplished. Note the use of the RelPos variable to +// determine where the items should be moved to. +void doMove() { + + buildPaths(false); + + // By default and convention the place to move members to is the end of the + // archive. + Archive::iterator moveto_spot = TheArchive->end(); + + // However, if the relative positioning modifiers were used, we need to scan + // the archive to find the member in question. If we don't find it, its no + // crime, we just move to the end. + if (AddBefore || InsertBefore || AddAfter) { + for (Archive::iterator I = TheArchive->begin(), E= TheArchive->end(); + I != E; ++I ) { + if (RelPos == I->getPath().get()) { + if (AddAfter) { + moveto_spot = I; + moveto_spot++; + } else { + moveto_spot = I; + } + break; + } + } + } + + // Keep a list of the paths remaining to be moved + sys::Path::Vector remaining(Paths); + + // Scan the archive again, this time looking for the members to move to the + // moveto_spot. + for (Archive::iterator I = TheArchive->begin(), E= TheArchive->end(); + I != E && !remaining.empty(); ++I ) { + sys::Path::Vector::iterator found = + std::find(remaining.begin(),remaining.end(),I->getPath()); + if (found != remaining.end()) { + if (I != moveto_spot) + TheArchive->moveMemberBefore(I,moveto_spot); + remaining.erase(found); + } + } + + // We're done editting, reconstruct the archive. + TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ReallyVerbose); +} + +// doQuickAppend - Implements the 'q' operation. This function just +// indiscriminantly adds the members to the archive and rebuilds it. +void doQuickAppend() { + // Get the list of paths to append. + buildPaths(true); + if (Paths.empty()) return; + + // Append them quickly. + for (sys::Path::Vector::iterator PI = Paths.begin(), PE = Paths.end(); + PI != PE; ++PI) { + TheArchive->addFileBefore(*PI,TheArchive->end()); + } + + // We're done editting, reconstruct the archive. + TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ReallyVerbose); +} + +// doReplaceOrInsert - Implements the 'r' operation. This function will replace +// any existing files or insert new ones into the archive. +void doReplaceOrInsert() { + + // Build the list of files to be added/replaced. + buildPaths(true); + if (Paths.empty()) return; + + // Keep track of the paths that remain to be inserted. + sys::Path::Vector remaining(Paths); + + // Default the insertion spot to the end of the archive + Archive::iterator insert_spot = TheArchive->end(); + + // Iterate over the archive contents + for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end(); + I != E && !remaining.empty(); ++I ) { + + // Determine if this archive member matches one of the paths we're trying + // to replace. + sys::Path::Vector::iterator found = + std::find(remaining.begin(),remaining.end(), I->getPath()); + if (found != remaining.end()) { + if (OnlyUpdate) { + // Replace the item only if it is newer. + sys::Path::StatusInfo si; + found->getStatusInfo(si); + if (si.modTime > I->getModTime()) + I->replaceWith(*found); + } else { + // Replace the item regardless of time stamp + I->replaceWith(*found); + } + + // Remove it from our "to do" list + remaining.erase(found); + } + + // Determine if this is the place where we should insert + if ((AddBefore || InsertBefore) && (RelPos == I->getPath().get())) + insert_spot = I; + else if (AddAfter && (RelPos == I->getPath().get())) { + insert_spot = I; + insert_spot++; + } + } + + // If we didn't replace all the members, some will remain and need to be + // inserted at the previously computed insert-spot. + if (!remaining.empty()) { + for (sys::Path::Vector::iterator PI = remaining.begin(), + PE = remaining.end(); PI != PE; ++PI) { + TheArchive->addFileBefore(*PI,insert_spot); + } + } + + // We're done editting, reconstruct the archive. + TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ReallyVerbose); +} + +// main - main program for llvm-ar .. see comments in the code int main(int argc, char **argv) { - cl::ParseCommandLineOptions(argc, argv); + + // Ensure we initialize the global MoreHelp to tell the command line utility + // that we have a MoreHelp function. This function is called to print more + // help if the --help option is given on the command line + cl::MoreHelp = printMoreHelp; + + // Have the command line options parsed and handle things + // like --help and --version. + cl::ParseCommandLineOptions(argc, argv, + " LLVM Archiver (llvm-ar)\n\n" + " This program archives bytecode files into single libraries\n" + ); + + // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); - parseCL(); + int exitCode = 0; + + // Make sure we don't exit with "unhandled exception". + try { + // Do our own parsing of the command line because the CommandLine utility + // can't handle the grouped positional parameters without a dash. + ArchiveOperation Operation = parseCommandLine(); + + // Check the path name of the archive + sys::Path ArchivePath; + if (!ArchivePath.setFile(ArchiveName)) + throw std::string("Archive name invalid: ") + ArchiveName; + + // Create or open the archive object. + if (!ArchivePath.exists()) { + // Produce a warning if we should and we're creating the archive + if (!Create) + std::cerr << argv[0] << ": creating " << ArchivePath.get() << "\n"; + TheArchive = Archive::CreateEmpty(ArchivePath); + } else { + TheArchive = Archive::OpenAndLoad(ArchivePath); + } - //Create archive! - if(Create) - CreateArchive(); + // Make sure we're not fooling ourselves. + assert(TheArchive && "Unable to instantiate the archive"); - return 0; -} + // Perform the operation + switch (Operation) { + case Print: doPrint(); break; + case Delete: doDelete(); break; + case Move: doMove(); break; + case QuickAppend: /* FALL THROUGH */ + case ReplaceOrInsert: doReplaceOrInsert(); break; + case DisplayTable: doDisplayTable(); break; + case Extract: doExtract(); break; + case NoOperation: + std::cerr << argv[0] << ": No operation was selected.\n"; + break; + } + + // Close up shop + delete TheArchive; + } catch (const char*msg) { + // These errors are usage errors, thrown only by the various checks in the + // code above. + std::cerr << argv[0] << ": " << msg << "\n\n"; + printUse(); + exitCode = 1; + } catch (const std::string& msg) { + // These errors are thrown by LLVM libraries (e.g. lib System) and represent + // a more serious error so we bump the exitCode and don't print the usage. + std::cerr << argv[0] << ": " << msg << "\n"; + exitCode = 2; + } catch (...) { + // This really shouldn't happen, but just in case .... + std::cerr << argv[0] << ": An nexpected unknown exception occurred.\n"; + exitCode = 3; + } + + // Return result code back to operating system. + return exitCode; +} From reid at x10sys.com Sun Nov 14 16:21:48 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:21:48 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-as/llvm-as.cpp Message-ID: <200411142221.QAA22076@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-as: llvm-as.cpp updated: 1.37 -> 1.38 --- Log message: Fix usage of changed function prototype --- Diffs of the changes: (+4 -3) Index: llvm/tools/llvm-as/llvm-as.cpp diff -u llvm/tools/llvm-as/llvm-as.cpp:1.37 llvm/tools/llvm-as/llvm-as.cpp:1.38 --- llvm/tools/llvm-as/llvm-as.cpp:1.37 Sat Nov 6 23:50:16 2004 +++ llvm/tools/llvm-as/llvm-as.cpp Sun Nov 14 16:20:53 2004 @@ -40,8 +40,9 @@ static cl::opt DumpAsm("d", cl::desc("Print assembly as parsed"), cl::Hidden); -static cl::opt NoCompress("disable-compression", cl::init(false), - cl::desc("Don't ompress the generated bytecode")); +static cl::opt +NoCompress("disable-compression", cl::init(false), + cl::desc("Don't ompress the generated bytecode")); static cl::opt DisableVerify("disable-verify", cl::Hidden, @@ -113,7 +114,7 @@ std::ios_base::trunc | std::ios_base::binary); // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT - sys::RemoveFileOnSignal(OutputFilename); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } } From reid at x10sys.com Sun Nov 14 16:22:37 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:22:37 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-dis/llvm-dis.cpp Message-ID: <200411142222.QAA22101@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-dis: llvm-dis.cpp updated: 1.46 -> 1.47 --- Log message: Fix usage of changed function prototype --- Diffs of the changes: (+1 -1) Index: llvm/tools/llvm-dis/llvm-dis.cpp diff -u llvm/tools/llvm-dis/llvm-dis.cpp:1.46 llvm/tools/llvm-dis/llvm-dis.cpp:1.47 --- llvm/tools/llvm-dis/llvm-dis.cpp:1.46 Wed Sep 1 17:55:37 2004 +++ llvm/tools/llvm-dis/llvm-dis.cpp Sun Nov 14 16:21:57 2004 @@ -95,7 +95,7 @@ // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT - sys::RemoveFileOnSignal(OutputFilename); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } } } From llvm at cs.uiuc.edu Sun Nov 14 16:23:23 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Sun, 14 Nov 2004 16:23:23 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ld/Linker.cpp Message-ID: <200411142223.QAA22130@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ld: Linker.cpp (r1.4) removed --- Log message: Moved to lib/Linker (common with gccld) --- Diffs of the changes: (+0 -0) From reid at x10sys.com Sun Nov 14 16:24:09 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:24:09 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ld/Makefile Message-ID: <200411142224.QAA22162@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ld: Makefile updated: 1.3 -> 1.4 --- Log message: We need the libLLVMArchive library now --- Diffs of the changes: (+4 -3) Index: llvm/tools/llvm-ld/Makefile diff -u llvm/tools/llvm-ld/Makefile:1.3 llvm/tools/llvm-ld/Makefile:1.4 --- llvm/tools/llvm-ld/Makefile:1.3 Wed Oct 27 22:50:43 2004 +++ llvm/tools/llvm-ld/Makefile Sun Nov 14 16:23:31 2004 @@ -10,8 +10,9 @@ LEVEL = ../.. TOOLNAME = llvm-ld -USEDLIBS = LLVMipo.a LLVMTransforms.a LLVMScalarOpts.a LLVMAnalysis.a LLVMipa.a \ - LLVMTransformUtils.a LLVMTarget.a LLVMBCReader LLVMBCWriter LLVMCore \ - LLVMSupport.a LLVMSystem.a +USEDLIBS = LLVMipo.a LLVMTransforms.a LLVMScalarOpts.a LLVMAnalysis.a \ + LLVMipa.a LLVMTransformUtils.a LLVMTarget.a LLVMLinker.a \ + LLVMArchive.a LLVMBCReader LLVMBCWriter \ + LLVMCore LLVMSupport.a LLVMSystem.a include $(LEVEL)/Makefile.common From reid at x10sys.com Sun Nov 14 16:25:09 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:25:09 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ld/llvm-ld.cpp Message-ID: <200411142225.QAA22210@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ld: llvm-ld.cpp updated: 1.2 -> 1.3 --- Log message: Fix usage of changed function prototype --- Diffs of the changes: (+5 -5) Index: llvm/tools/llvm-ld/llvm-ld.cpp diff -u llvm/tools/llvm-ld/llvm-ld.cpp:1.2 llvm/tools/llvm-ld/llvm-ld.cpp:1.3 --- llvm/tools/llvm-ld/llvm-ld.cpp:1.2 Sat Sep 25 11:00:07 2004 +++ llvm/tools/llvm-ld/llvm-ld.cpp Sun Nov 14 16:24:17 2004 @@ -223,7 +223,7 @@ // Ensure that the bytecode file gets removed from the disk if we get a // terminating signal. - sys::RemoveFileOnSignal(RealBytecodeOutput); + sys::RemoveFileOnSignal(sys::Path(RealBytecodeOutput)); // Generate the bytecode file. if (GenerateBytecode(Composite.get(), Strip, !NoInternalize, &Out)) { @@ -246,8 +246,8 @@ std::string AssemblyFile = OutputFilename + ".s"; // Mark the output files for removal if we get an interrupt. - sys::RemoveFileOnSignal(AssemblyFile); - sys::RemoveFileOnSignal(OutputFilename); + sys::RemoveFileOnSignal(sys::Path(AssemblyFile)); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); // Determine the locations of the llc and gcc programs. std::string llc = FindExecutable("llc", argv[0]); @@ -271,8 +271,8 @@ std::string CFile = OutputFilename + ".cbe.c"; // Mark the output files for removal if we get an interrupt. - sys::RemoveFileOnSignal(CFile); - sys::RemoveFileOnSignal(OutputFilename); + sys::RemoveFileOnSignal(sys::Path(CFile)); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); // Determine the locations of the llc and gcc programs. std::string llc = FindExecutable("llc", argv[0]); From reid at x10sys.com Sun Nov 14 16:26:04 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:26:04 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ld/llvm-ld.h Message-ID: <200411142226.QAA22242@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ld: llvm-ld.h updated: 1.1 -> 1.2 --- Log message: Remove linking declarations (in Linker.h now) --- Diffs of the changes: (+1 -26) Index: llvm/tools/llvm-ld/llvm-ld.h diff -u llvm/tools/llvm-ld/llvm-ld.h:1.1 llvm/tools/llvm-ld/llvm-ld.h:1.2 --- llvm/tools/llvm-ld/llvm-ld.h:1.1 Sun Sep 12 20:27:53 2004 +++ llvm/tools/llvm-ld/llvm-ld.h Sun Nov 14 16:25:26 2004 @@ -12,19 +12,11 @@ //===----------------------------------------------------------------------===// #include "llvm/Module.h" - -#include -#include +#include "llvm/Linker.h" #include namespace llvm { -void -GetAllDefinedSymbols (Module *M, std::set &DefinedSymbols); - -void -GetAllUndefinedSymbols(Module *M, std::set &UndefinedSymbols); - int GenerateBytecode (Module * M, bool Strip, @@ -47,21 +39,4 @@ const std::string & gcc, char ** const envp); -std::auto_ptr -LoadObject (const std::string & FN, std::string &OutErrorMessage); - -std::string FindLib(const std::string &Filename, - const std::vector &Paths, - bool SharedObjectOnly = false); - -void LinkLibraries (const char * progname, Module* HeadModule, - const std::vector & Libraries, - const std::vector & LibPaths, - bool Verbose, bool Native); -bool -LinkFiles (const char * progname, - Module * HeadModule, - const std::vector & Files, - bool Verbose); - } // End llvm namespace From reid at x10sys.com Sun Nov 14 16:26:51 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:26:51 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-link/llvm-link.cpp Message-ID: <200411142226.QAA22275@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-link: llvm-link.cpp updated: 1.48 -> 1.49 --- Log message: Fix usage of changed function prototype --- Diffs of the changes: (+1 -1) Index: llvm/tools/llvm-link/llvm-link.cpp diff -u llvm/tools/llvm-link/llvm-link.cpp:1.48 llvm/tools/llvm-link/llvm-link.cpp:1.49 --- llvm/tools/llvm-link/llvm-link.cpp:1.48 Sat Nov 6 23:50:16 2004 +++ llvm/tools/llvm-link/llvm-link.cpp Sun Nov 14 16:26:14 2004 @@ -128,7 +128,7 @@ // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT - sys::RemoveFileOnSignal(OutputFilename); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } if (verifyModule(*Composite.get())) { From reid at x10sys.com Sun Nov 14 16:27:37 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:27:37 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-nm/Makefile Message-ID: <200411142227.QAA22295@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-nm: Makefile updated: 1.4 -> 1.5 --- Log message: This tool needs libLLVMArchive now --- Diffs of the changes: (+1 -1) Index: llvm/tools/llvm-nm/Makefile diff -u llvm/tools/llvm-nm/Makefile:1.4 llvm/tools/llvm-nm/Makefile:1.5 --- llvm/tools/llvm-nm/Makefile:1.4 Wed Oct 27 18:18:45 2004 +++ llvm/tools/llvm-nm/Makefile Sun Nov 14 16:27:00 2004 @@ -9,5 +9,5 @@ LEVEL = ../.. TOOLNAME = llvm-nm -USEDLIBS = LLVMBCReader LLVMCore LLVMSupport.a LLVMSystem.a +USEDLIBS = LLVMArchive.a LLVMBCReader LLVMCore LLVMSupport.a LLVMSystem.a include $(LEVEL)/Makefile.common From reid at x10sys.com Sun Nov 14 16:28:23 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:28:23 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-nm/llvm-nm.cpp Message-ID: <200411142228.QAA22330@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-nm: llvm-nm.cpp updated: 1.18 -> 1.19 --- Log message: *Fix usage of changed function prototype*Use Archive interface to symbol table for archives --- Diffs of the changes: (+7 -4) Index: llvm/tools/llvm-nm/llvm-nm.cpp diff -u llvm/tools/llvm-nm/llvm-nm.cpp:1.18 llvm/tools/llvm-nm/llvm-nm.cpp:1.19 --- llvm/tools/llvm-nm/llvm-nm.cpp:1.18 Wed Sep 1 17:55:37 2004 +++ llvm/tools/llvm-nm/llvm-nm.cpp Sun Nov 14 16:27:46 2004 @@ -18,6 +18,7 @@ #include "llvm/Module.h" #include "llvm/Bytecode/Reader.h" +#include "llvm/Bytecode/Archive.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" #include "llvm/System/Signals.h" @@ -132,11 +133,13 @@ std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; return; } - } else if (IsArchive (Filename)) { + } else if (IsArchive(Filename)) { + Archive* archive = Archive::OpenAndLoad(sys::Path(Filename)); + if (!archive) + std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; std::vector Modules; - if (ReadArchiveFile (Filename, Modules, &ErrorMessage)) { - std::cerr << ToolName << ": " << Filename << ": " - << ErrorMessage << "\n"; + if (archive->getAllModules(Modules,&ErrorMessage)) { + std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; return; } MultipleFiles = true; From reid at x10sys.com Sun Nov 14 16:29:11 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:29:11 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ranlib/Makefile Message-ID: <200411142229.QAA22353@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ranlib: Makefile added (r1.1) --- Log message: Makefile for llvm-ranlib tool --- Diffs of the changes: (+14 -0) Index: llvm/tools/llvm-ranlib/Makefile diff -c /dev/null llvm/tools/llvm-ranlib/Makefile:1.1 *** /dev/null Sun Nov 14 16:28:52 2004 --- llvm/tools/llvm-ranlib/Makefile Sun Nov 14 16:28:33 2004 *************** *** 0 **** --- 1,14 ---- + ##===- tools/llvm-ranlib/Makefile --------------------------*- Makefile -*-===## + # + # 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. + # + ##===----------------------------------------------------------------------===## + + LEVEL = ../.. + TOOLNAME = llvm-ranlib + USEDLIBS = LLVMArchive.a LLVMBCReader LLVMCore LLVMSupport.a LLVMSystem.a + + include $(LEVEL)/Makefile.common From reid at x10sys.com Sun Nov 14 16:29:58 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:29:58 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ranlib/llvm-ranlib.cpp Message-ID: <200411142229.QAA22389@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ranlib: llvm-ranlib.cpp added (r1.1) --- Log message: A tool for adding a symbol table to LLVM Archives --- Diffs of the changes: (+88 -0) Index: llvm/tools/llvm-ranlib/llvm-ranlib.cpp diff -c /dev/null llvm/tools/llvm-ranlib/llvm-ranlib.cpp:1.1 *** /dev/null Sun Nov 14 16:29:40 2004 --- llvm/tools/llvm-ranlib/llvm-ranlib.cpp Sun Nov 14 16:29:21 2004 *************** *** 0 **** --- 1,88 ---- + //===-- llvm-ranlib.cpp - LLVM archive index generator --------------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Reid Spencer and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // Adds or updates an index (symbol table) for an LLVM archive file. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Module.h" + #include "llvm/Bytecode/Archive.h" + #include "llvm/Support/CommandLine.h" + #include "llvm/Support/FileUtilities.h" + #include "llvm/System/Signals.h" + #include + #include + #include + + using namespace llvm; + + // llvm-ar operation code and modifier flags + cl::opt + ArchiveName(cl::Positional, cl::Optional, cl::desc("...")); + + cl::opt + Verbose("verbose",cl::Optional,cl::init(false), + cl::desc("Print the symbol table")); + + sys::Path TmpArchive; + + void cleanup() { + if (TmpArchive.exists()) + TmpArchive.destroyFile(); + } + + int main(int argc, char **argv) { + + // Have the command line options parsed and handle things + // like --help and --version. + cl::ParseCommandLineOptions(argc, argv, + " LLVM Archive Index Generator (llvm-ranlib)\n\n" + " This program adds or updates an index of bytecode symbols\n" + " to an LLVM archive file." + ); + + // Print a stack trace if we signal out. + sys::PrintStackTraceOnErrorSignal(); + + int exitCode = 0; + + // Make sure we don't exit with "unhandled exception". + try { + + // Check the path name of the archive + sys::Path ArchivePath; + if (!ArchivePath.setFile(ArchiveName)) + throw std::string("Archive name invalid: ") + ArchiveName; + + // Make sure it exists, we don't create empty archives + if (!ArchivePath.exists()) + throw "Archive file does not exist"; + + // Archive* TheArchive = Archive::OpenAndLoad(ArchivePath); + Archive* TheArchive = Archive::OpenAndLoad(ArchivePath); + + assert(TheArchive && "Unable to instantiate the archive"); + + TheArchive->writeToDisk(true,false,false,Verbose); + + delete TheArchive; + + } catch (const char*msg) { + std::cerr << argv[0] << ": " << msg << "\n\n"; + exitCode = 1; + } catch (const std::string& msg) { + std::cerr << argv[0] << ": " << msg << "\n"; + exitCode = 2; + } catch (...) { + std::cerr << argv[0] << ": An nexpected unknown exception occurred.\n"; + exitCode = 3; + } + cleanup(); + return exitCode; + } From reid at x10sys.com Sun Nov 14 16:30:46 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:30:46 -0600 Subject: [llvm-commits] CVS: llvm/tools/opt/opt.cpp Message-ID: <200411142230.QAA22429@zion.cs.uiuc.edu> Changes in directory llvm/tools/opt: opt.cpp updated: 1.98 -> 1.99 --- Log message: Fix usage of changed function prototype --- Diffs of the changes: (+1 -1) Index: llvm/tools/opt/opt.cpp diff -u llvm/tools/opt/opt.cpp:1.98 llvm/tools/opt/opt.cpp:1.99 --- llvm/tools/opt/opt.cpp:1.98 Fri Oct 15 18:22:48 2004 +++ llvm/tools/opt/opt.cpp Sun Nov 14 16:30:08 2004 @@ -111,7 +111,7 @@ // Make sure that the Output file gets unlinked from the disk if we get a // SIGINT - sys::RemoveFileOnSignal(OutputFilename); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } // If the output is set to be emitted to standard out, and standard out is a From reid at x10sys.com Sun Nov 14 16:31:32 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 16:31:32 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/TableGen.cpp Message-ID: <200411142231.QAA22450@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: TableGen.cpp updated: 1.35 -> 1.36 --- Log message: Fix usage of changed function prototype --- Diffs of the changes: (+1 -1) Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.35 llvm/utils/TableGen/TableGen.cpp:1.36 --- llvm/utils/TableGen/TableGen.cpp:1.35 Fri Sep 3 18:17:54 2004 +++ llvm/utils/TableGen/TableGen.cpp Sun Nov 14 16:30:54 2004 @@ -426,7 +426,7 @@ } // Make sure the file gets removed if *gasp* tablegen crashes... - sys::RemoveFileOnSignal(OutputFilename); + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } try { From alkis at cs.uiuc.edu Sun Nov 14 16:37:52 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun, 14 Nov 2004 16:37:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Path.cpp Message-ID: <200411142237.QAA22553@zion.cs.uiuc.edu> Changes in directory llvm/lib/System: Path.cpp updated: 1.7 -> 1.8 --- Log message: Add missing include. --- Diffs of the changes: (+1 -0) Index: llvm/lib/System/Path.cpp diff -u llvm/lib/System/Path.cpp:1.7 llvm/lib/System/Path.cpp:1.8 --- llvm/lib/System/Path.cpp:1.7 Sun Nov 14 16:05:32 2004 +++ llvm/lib/System/Path.cpp Sun Nov 14 16:37:42 2004 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/System/Path.h" +#include namespace llvm { using namespace sys; From llvm at cs.uiuc.edu Sun Nov 14 16:39:09 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Sun, 14 Nov 2004 16:39:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/ArchiveReader.cpp Message-ID: <200411142239.QAA22677@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: ArchiveReader.cpp (r1.20) removed --- Log message: Moved to lib/Bytecode/Archive. --- Diffs of the changes: (+0 -0) From reid at x10sys.com Sun Nov 14 17:00:46 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:00:46 -0600 Subject: [llvm-commits] CVS: llvm/lib/Linker/LinkArchives.cpp Message-ID: <200411142300.RAA22997@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: LinkArchives.cpp updated: 1.32 -> 1.33 --- Log message: Linker.h has a new home. --- Diffs of the changes: (+0 -1) Index: llvm/lib/Linker/LinkArchives.cpp diff -u llvm/lib/Linker/LinkArchives.cpp:1.32 llvm/lib/Linker/LinkArchives.cpp:1.33 --- llvm/lib/Linker/LinkArchives.cpp:1.32 Sun Nov 14 16:02:27 2004 +++ llvm/lib/Linker/LinkArchives.cpp Sun Nov 14 16:59:59 2004 @@ -22,7 +22,6 @@ #include "llvm/Target/TargetData.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Support/Linker.h" #include "llvm/Config/config.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" From reid at x10sys.com Sun Nov 14 17:00:55 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:00:55 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ld/GenerateCode.cpp llvm-ld.cpp Message-ID: <200411142300.RAA23002@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ld: GenerateCode.cpp updated: 1.2 -> 1.3 llvm-ld.cpp updated: 1.3 -> 1.4 --- Log message: Linker.h has a new home. --- Diffs of the changes: (+2 -2) Index: llvm/tools/llvm-ld/GenerateCode.cpp diff -u llvm/tools/llvm-ld/GenerateCode.cpp:1.2 llvm/tools/llvm-ld/GenerateCode.cpp:1.3 --- llvm/tools/llvm-ld/GenerateCode.cpp:1.2 Wed Oct 6 23:11:24 2004 +++ llvm/tools/llvm-ld/GenerateCode.cpp Sun Nov 14 17:00:08 2004 @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "llvm-ld.h" +#include "llvm/Linker.h" #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Analysis/LoadValueNumbering.h" @@ -23,7 +24,6 @@ #include "llvm/Target/TargetData.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Support/Linker.h" #include "llvm/Support/SystemUtils.h" #include "llvm/Support/CommandLine.h" using namespace llvm; Index: llvm/tools/llvm-ld/llvm-ld.cpp diff -u llvm/tools/llvm-ld/llvm-ld.cpp:1.3 llvm/tools/llvm-ld/llvm-ld.cpp:1.4 --- llvm/tools/llvm-ld/llvm-ld.cpp:1.3 Sun Nov 14 16:24:17 2004 +++ llvm/tools/llvm-ld/llvm-ld.cpp Sun Nov 14 17:00:08 2004 @@ -21,6 +21,7 @@ //===----------------------------------------------------------------------===// #include "llvm-ld.h" +#include "llvm/Linker.h" #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Bytecode/Reader.h" @@ -30,7 +31,6 @@ #include "llvm/Target/TargetMachineRegistry.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Support/Linker.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" #include "llvm/System/Signals.h" From reid at x10sys.com Sun Nov 14 17:00:55 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:00:55 -0600 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/BugDriver.cpp Miscompilation.cpp Message-ID: <200411142300.RAA23010@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: BugDriver.cpp updated: 1.37 -> 1.38 Miscompilation.cpp updated: 1.52 -> 1.53 --- Log message: Linker.h has a new home. --- Diffs of the changes: (+2 -2) Index: llvm/tools/bugpoint/BugDriver.cpp diff -u llvm/tools/bugpoint/BugDriver.cpp:1.37 llvm/tools/bugpoint/BugDriver.cpp:1.38 --- llvm/tools/bugpoint/BugDriver.cpp:1.37 Wed Sep 1 17:55:37 2004 +++ llvm/tools/bugpoint/BugDriver.cpp Sun Nov 14 17:00:08 2004 @@ -14,11 +14,11 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" +#include "llvm/Linker.h" #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Assembly/Parser.h" #include "llvm/Bytecode/Reader.h" -#include "llvm/Support/Linker.h" #include "llvm/Support/ToolRunner.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.52 llvm/tools/bugpoint/Miscompilation.cpp:1.53 --- llvm/tools/bugpoint/Miscompilation.cpp:1.52 Wed Sep 1 17:55:37 2004 +++ llvm/tools/bugpoint/Miscompilation.cpp Sun Nov 14 17:00:08 2004 @@ -17,12 +17,12 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" +#include "llvm/Linker.h" #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Support/Mangler.h" #include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/Support/Linker.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" using namespace llvm; From reid at x10sys.com Sun Nov 14 17:00:55 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:00:55 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccld/GenerateCode.cpp gccld.cpp Message-ID: <200411142300.RAA23009@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: GenerateCode.cpp updated: 1.34 -> 1.35 gccld.cpp updated: 1.79 -> 1.80 --- Log message: Linker.h has a new home. --- Diffs of the changes: (+2 -2) Index: llvm/tools/gccld/GenerateCode.cpp diff -u llvm/tools/gccld/GenerateCode.cpp:1.34 llvm/tools/gccld/GenerateCode.cpp:1.35 --- llvm/tools/gccld/GenerateCode.cpp:1.34 Sun Oct 10 23:47:18 2004 +++ llvm/tools/gccld/GenerateCode.cpp Sun Nov 14 17:00:08 2004 @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "gccld.h" +#include "llvm/Linker.h" #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Analysis/LoadValueNumbering.h" @@ -23,7 +24,6 @@ #include "llvm/Target/TargetData.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Support/Linker.h" #include "llvm/Support/SystemUtils.h" #include "llvm/Support/CommandLine.h" using namespace llvm; Index: llvm/tools/gccld/gccld.cpp diff -u llvm/tools/gccld/gccld.cpp:1.79 llvm/tools/gccld/gccld.cpp:1.80 --- llvm/tools/gccld/gccld.cpp:1.79 Sun Nov 14 16:17:03 2004 +++ llvm/tools/gccld/gccld.cpp Sun Nov 14 17:00:08 2004 @@ -21,6 +21,7 @@ //===----------------------------------------------------------------------===// #include "gccld.h" +#include "llvm/Linker.h" #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Bytecode/Reader.h" @@ -28,7 +29,6 @@ #include "llvm/Target/TargetData.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Support/Linker.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" #include "llvm/System/Signals.h" From reid at x10sys.com Sun Nov 14 17:12:59 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:12:59 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-link/Makefile Message-ID: <200411142312.RAA23128@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-link: Makefile updated: 1.10 -> 1.11 --- Log message: This program needs libLLVMLinker.a now --- Diffs of the changes: (+2 -1) Index: llvm/tools/llvm-link/Makefile diff -u llvm/tools/llvm-link/Makefile:1.10 llvm/tools/llvm-link/Makefile:1.11 --- llvm/tools/llvm-link/Makefile:1.10 Wed Oct 27 18:18:45 2004 +++ llvm/tools/llvm-link/Makefile Sun Nov 14 17:12:22 2004 @@ -9,6 +9,7 @@ LEVEL = ../.. TOOLNAME = llvm-link -USEDLIBS = LLVMBCReader LLVMBCWriter LLVMCore LLVMSupport.a LLVMSystem.a +USEDLIBS = LLVMLinker.a LLVMBCReader LLVMBCWriter \ + LLVMCore LLVMSupport.a LLVMSystem.a include $(LEVEL)/Makefile.common From reid at x10sys.com Sun Nov 14 17:18:28 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:18:28 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ar/llvm-ar.cpp Message-ID: <200411142318.RAA23233@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ar: llvm-ar.cpp updated: 1.16 -> 1.17 --- Log message: Correct call of methods whose names have changed. --- Diffs of the changes: (+4 -4) Index: llvm/tools/llvm-ar/llvm-ar.cpp diff -u llvm/tools/llvm-ar/llvm-ar.cpp:1.16 llvm/tools/llvm-ar/llvm-ar.cpp:1.17 --- llvm/tools/llvm-ar/llvm-ar.cpp:1.16 Sun Nov 14 16:20:07 2004 +++ llvm/tools/llvm-ar/llvm-ar.cpp Sun Nov 14 17:17:41 2004 @@ -356,9 +356,9 @@ std::cout << "Printing " << I->getPath().get() << "\n"; if (I->isCompressedBytecode()) - Compressor::decompressToFile(data+4,I->getSize()-4,std::cout); + Compressor::decompressToStream(data+4,I->getSize()-4,std::cout); else if (I->isCompressed()) { - Compressor::decompressToFile(data,I->getSize(),std::cout); + Compressor::decompressToStream(data,I->getSize(),std::cout); } else { unsigned len = I->getSize(); std::cout.write(data, len); @@ -420,7 +420,7 @@ std::cout << "/" << std::setw(4) << I->getGroup(); std::cout << " " << std::setw(8) << I->getSize(); std::cout << " " << std::setw(20) << - I->getModTime().ToString().substr(4); + I->getModTime().toString().substr(4); std::cout << " " << I->getPath().get() << "\n"; } else { std::cout << I->getPath().get() << "\n"; @@ -464,7 +464,7 @@ // Write the data, making sure to uncompress things first if (I->isCompressed()) { - Compressor::decompressToFile(data,len,file); + Compressor::decompressToStream(data,len,file); } else { file.write(data,len); } From reid at x10sys.com Sun Nov 14 17:24:05 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:24:05 -0600 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/Makefile Message-ID: <200411142324.RAA23322@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: Makefile updated: 1.9 -> 1.10 --- Log message: bugpoint needs LLVMLinker.a now. --- Diffs of the changes: (+3 -2) Index: llvm/tools/bugpoint/Makefile diff -u llvm/tools/bugpoint/Makefile:1.9 llvm/tools/bugpoint/Makefile:1.10 --- llvm/tools/bugpoint/Makefile:1.9 Wed Oct 27 18:18:45 2004 +++ llvm/tools/bugpoint/Makefile Sun Nov 14 17:23:18 2004 @@ -14,8 +14,9 @@ ANALIBS = LLVMDataStructure LLVMipa LLVMTarget.a USEDLIBS = LLVMipo LLVMScalarOpts LLVMAnalysis $(OPTLIBS) $(ANALIBS) \ - LLVMTransformUtils LLVMAsmParser LLVMBCReader LLVMBCWriter LLVMCore \ - LLVMSupport.a LLVMSystem.a + LLVMTransformUtils \ + LLVMAsmParser LLVMLinker.a LLVMBCReader LLVMBCWriter \ + LLVMCore LLVMSupport.a LLVMSystem.a TOOLLINKOPTS = $(PLATFORMLIBDL) From reid at x10sys.com Sun Nov 14 17:26:09 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:26:09 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-link/llvm-link.cpp Message-ID: <200411142326.RAA23383@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-link: llvm-link.cpp updated: 1.49 -> 1.50 --- Log message: Linker.h moved to include/llvm. --- Diffs of the changes: (+1 -1) Index: llvm/tools/llvm-link/llvm-link.cpp diff -u llvm/tools/llvm-link/llvm-link.cpp:1.49 llvm/tools/llvm-link/llvm-link.cpp:1.50 --- llvm/tools/llvm-link/llvm-link.cpp:1.49 Sun Nov 14 16:26:14 2004 +++ llvm/tools/llvm-link/llvm-link.cpp Sun Nov 14 17:25:32 2004 @@ -12,11 +12,11 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Linker.h" #include "llvm/Module.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Bytecode/Reader.h" #include "llvm/Bytecode/Writer.h" -#include "llvm/Support/Linker.h" #include "llvm/Support/CommandLine.h" #include "llvm/System/Signals.h" #include "llvm/System/Path.h" From reid at x10sys.com Sun Nov 14 17:26:55 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:26:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Path.cpp Message-ID: <200411142326.RAA23409@zion.cs.uiuc.edu> Changes in directory llvm/lib/System: Path.cpp updated: 1.8 -> 1.9 --- Log message: Make sure IdentifyFileType is in the sys namespace. --- Diffs of the changes: (+1 -1) Index: llvm/lib/System/Path.cpp diff -u llvm/lib/System/Path.cpp:1.8 llvm/lib/System/Path.cpp:1.9 --- llvm/lib/System/Path.cpp:1.8 Sun Nov 14 16:37:42 2004 +++ llvm/lib/System/Path.cpp Sun Nov 14 17:26:18 2004 @@ -23,7 +23,7 @@ //===----------------------------------------------------------------------===// LLVMFileType -IdentifyFileType(const char*magic, unsigned length) { +sys::IdentifyFileType(const char*magic, unsigned length) { assert(magic && "Invalid magic number string"); assert(length >=4 && "Invalid magic number length"); switch (magic[0]) { From reid at x10sys.com Sun Nov 14 17:27:48 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:27:48 -0600 Subject: [llvm-commits] CVS: llvm/lib/Linker/LinkModules.cpp Message-ID: <200411142327.RAA23440@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: LinkModules.cpp updated: 1.89 -> 1.90 --- Log message: Linker.h moved to include/llvm from include/llvm/Support. --- Diffs of the changes: (+1 -2) Index: llvm/lib/Linker/LinkModules.cpp diff -u llvm/lib/Linker/LinkModules.cpp:1.89 llvm/lib/Linker/LinkModules.cpp:1.90 --- llvm/lib/Linker/LinkModules.cpp:1.89 Fri Nov 12 14:37:43 2004 +++ llvm/lib/Linker/LinkModules.cpp Sun Nov 14 17:27:04 2004 @@ -16,7 +16,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/Linker.h" +#include "llvm/Linker.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" @@ -848,7 +848,6 @@ // error occurs, true is returned and ErrorMsg (if not null) is set to indicate // the problem. Upon failure, the Dest module could be in a modified state, and // shouldn't be relied on to be consistent. -// bool llvm::LinkModules(Module *Dest, const Module *Src, std::string *ErrorMsg) { assert(Dest != 0 && "Invalid Destination module"); assert(Src != 0 && "Invalid Source Module"); From reid at x10sys.com Sun Nov 14 17:29:37 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:29:37 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/System/Path.h Message-ID: <200411142329.RAA23465@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: Path.h updated: 1.9 -> 1.10 --- Log message: Changes per code review: * Document StatusInfo fields better * No lines > 80 cols * Have getStatusInfo return bool if file doesn't exist * Don't document in detail how temporary file name should be created. --- Diffs of the changes: (+21 -14) Index: llvm/include/llvm/System/Path.h diff -u llvm/include/llvm/System/Path.h:1.9 llvm/include/llvm/System/Path.h:1.10 --- llvm/include/llvm/System/Path.h:1.9 Sun Nov 14 15:52:22 2004 +++ llvm/include/llvm/System/Path.h Sun Nov 14 17:29:00 2004 @@ -22,7 +22,7 @@ namespace sys { /// This class provides an abstraction for the path to a file or directory - /// in the operating system's filesystem and provides various basic operations + /// in the operating system's filesystem and provides various basic operations /// on it. Note that this class only represents the name of a path to a file /// or directory which may or may not be valid for a given machine's file /// system. A Path ensures that the name it encapsulates is syntactical valid @@ -48,8 +48,14 @@ public: typedef std::vector Vector; - /// This structure provides basic file system information about a file. - /// The structure is filled in by the getStatusInfo method. + /// This structure provides basic file system information about a file. It + /// is patterned after the stat(2) Unix operating system call but made + /// platform independent and eliminates many of the unix-specific fields. + /// However, to support llvm-ar, the mode, user, and group fields are + /// retained. These pertain to unix security and may not have a meaningful + /// value on non-Unix platforms. However, the fileSize and modTime fields + /// should always be applicabe on all platforms. The structure is + /// filled in by the getStatusInfo method. /// @brief File status structure struct StatusInfo { StatusInfo() : modTime(0,0) { fileSize=0; mode=0; user=0; group=0; } @@ -61,7 +67,6 @@ bool isDir; ///< True if this is a directory. }; - /// @} /// @name Constructors /// @{ @@ -359,11 +364,14 @@ /// This function returns status information about the file. The type of /// path (file or directory) is updated to reflect the actual contents - /// of the file system. - /// @returns nothing + /// of the file system. If the file does not exist, false is returned. + /// For other (hard I/O) errors, a std::string is throwing indicating the + /// problem. + /// @returns true if the status info was obtained, false if the file does + /// not exist. /// @throws std::string if an error occurs. /// @brief Get file status. - void getStatusInfo(StatusInfo& stat); + bool getStatusInfo(StatusInfo& stat); /// This method attempts to set the Path object to \p unverified_path /// and interpret the name as a directory name. The \p unverified_path @@ -435,11 +443,11 @@ bool appendSuffix(const std::string& suffix); /// The suffix of the filename is removed. The suffix begins with and - /// includes the last . character in the filename after the last directory + /// includes the last . character in the filename after the last directory /// separator and extends until the end of the name. If no . character is /// after the last directory separator, then the file name is left - /// unchanged (i.e. it was already without a suffix) but the function return - /// false. + /// unchanged (i.e. it was already without a suffix) but the function + /// returns false. /// @returns false if there was no suffix to remove, true otherwise. /// @throws nothing /// @brief Remove the suffix from a path name. @@ -474,11 +482,10 @@ /// unique temporary file name is generated based on the contents of /// \p this before the call. The new name is assigned to \p this and the /// file is created. Note that this will both change the Path object - /// *and* create the corresponding file. The path of \p this will have - /// six characters added to it (per mkstemp(3)) that ensure the file - /// name is unique. + /// *and* create the corresponding file. This function will ensure that + /// the newly generated temporary file name is unique in the file system. /// @throws std::string if there is an error - /// @brief Create a temporary file + /// @brief Create a unique temporary file bool createTemporaryFile(); /// This method attempts to destroy the directory named by the last in From reid at x10sys.com Sun Nov 14 17:31:16 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:31:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Path.cpp Message-ID: <200411142331.RAA23505@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Path.cpp updated: 1.11 -> 1.12 --- Log message: Implement functionality suggested from code review: getStatusInfo should returnn false if the file doesn't exist rather than throw ane exception. --- Diffs of the changes: (+4 -1) Index: llvm/lib/System/Unix/Path.cpp diff -u llvm/lib/System/Unix/Path.cpp:1.11 llvm/lib/System/Unix/Path.cpp:1.12 --- llvm/lib/System/Unix/Path.cpp:1.11 Sun Nov 14 16:08:36 2004 +++ llvm/lib/System/Unix/Path.cpp Sun Nov 14 17:30:38 2004 @@ -239,8 +239,10 @@ return path.substr(pos+1); } -void +bool Path::getStatusInfo(StatusInfo& info) { + if (!isFile() || !readable()) + return false; struct stat buf; if (0 != stat(path.c_str(), &buf)) { ThrowErrno(std::string("Can't get status: ")+path); @@ -253,6 +255,7 @@ info.isDir = S_ISDIR(buf.st_mode); if (info.isDir && path[path.length()-1] != '/') path += '/'; + return true; } bool From reid at x10sys.com Sun Nov 14 17:50:33 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 17:50:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Linker/LinkArchives.cpp Message-ID: <200411142350.RAA23727@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: LinkArchives.cpp updated: 1.33 -> 1.34 --- Log message: Remove a forgotten debug output line. --- Diffs of the changes: (+0 -1) Index: llvm/lib/Linker/LinkArchives.cpp diff -u llvm/lib/Linker/LinkArchives.cpp:1.33 llvm/lib/Linker/LinkArchives.cpp:1.34 --- llvm/lib/Linker/LinkArchives.cpp:1.33 Sun Nov 14 16:59:59 2004 +++ llvm/lib/Linker/LinkArchives.cpp Sun Nov 14 17:49:55 2004 @@ -196,7 +196,6 @@ I != E; ++I) { // Get the module we must link in. Module* aModule = (*I)->releaseModule(); - std::cout << "Linked: " << aModule->getModuleIdentifier() << "\n"; // Link it in if (LinkModules(M, aModule, ErrorMessage)) { From reid at x10sys.com Sun Nov 14 19:20:48 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 19:20:48 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Bytecode/Reader.h Message-ID: <200411150120.TAA25238@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Bytecode: Reader.h updated: 1.21 -> 1.22 --- Log message: Changes necessary to enable linking of archives without LLVM symbol tables. --- Diffs of the changes: (+7 -4) Index: llvm/include/llvm/Bytecode/Reader.h diff -u llvm/include/llvm/Bytecode/Reader.h:1.21 llvm/include/llvm/Bytecode/Reader.h:1.22 --- llvm/include/llvm/Bytecode/Reader.h:1.21 Sun Nov 14 15:48:27 2004 +++ llvm/include/llvm/Bytecode/Reader.h Sun Nov 14 19:20:02 2004 @@ -77,11 +77,14 @@ /// bytecode module defines. This is used for archiving and linking when only /// the list of symbols the module defines is needed and the bytecode is /// already in memory. -/// @returns true on success, false if the bytecode can't be parsed +/// @returns the ModuleProvider on success, 0 if the bytecode can't be parsed /// @brief Get a bytecode file's externally visibile defined global symbols. -bool llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length, - const std::string& ModuleID, - std::vector& symbols); +ModuleProvider* llvm::GetBytecodeSymbols( + const unsigned char*Buffer, ///< The buffer to be parsed + unsigned Length, ///< The length of \p Buffer + const std::string& ModuleID, ///< An identifier for the module + std::vector& symbols ///< The symbols defined in the module +); } // End llvm namespace From reid at x10sys.com Sun Nov 14 19:20:57 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 19:20:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/ReaderWrappers.cpp Message-ID: <200411150120.TAA25241@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: ReaderWrappers.cpp updated: 1.34 -> 1.35 --- Log message: Changes necessary to enable linking of archives without LLVM symbol tables. --- Diffs of the changes: (+8 -7) Index: llvm/lib/Bytecode/Reader/ReaderWrappers.cpp diff -u llvm/lib/Bytecode/Reader/ReaderWrappers.cpp:1.34 llvm/lib/Bytecode/Reader/ReaderWrappers.cpp:1.35 --- llvm/lib/Bytecode/Reader/ReaderWrappers.cpp:1.34 Sun Nov 14 16:00:48 2004 +++ llvm/lib/Bytecode/Reader/ReaderWrappers.cpp Sun Nov 14 19:20:11 2004 @@ -391,26 +391,27 @@ } } -bool llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length, +ModuleProvider* +llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length, const std::string& ModuleID, std::vector& symbols) { try { - std::auto_ptr - AMP(getBytecodeBufferModuleProvider(Buffer, Length, ModuleID)); + ModuleProvider* MP = + getBytecodeBufferModuleProvider(Buffer, Length, ModuleID); // Get the module from the provider - Module* M = AMP->releaseModule(); + Module* M = MP->materializeModule(); // Get the symbols getSymbols(M, symbols); // Done with the module - delete M; - return true; + return MP; } catch (...) { - return false; + // Fall through } + return 0; } // vim: sw=2 ai From reid at x10sys.com Sun Nov 14 19:20:57 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 19:20:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Archive/ArchiveReader.cpp ArchiveWriter.cpp Message-ID: <200411150120.TAA25246@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Archive: ArchiveReader.cpp updated: 1.22 -> 1.23 ArchiveWriter.cpp updated: 1.2 -> 1.3 --- Log message: Changes necessary to enable linking of archives without LLVM symbol tables. --- Diffs of the changes: (+68 -14) Index: llvm/lib/Bytecode/Archive/ArchiveReader.cpp diff -u llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.22 llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.23 --- llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.22 Sun Nov 14 15:58:33 2004 +++ llvm/lib/Bytecode/Archive/ArchiveReader.cpp Sun Nov 14 19:20:11 2004 @@ -391,13 +391,58 @@ // ModuleProviders that define those symbols. void Archive::findModulesDefiningSymbols(const std::set& symbols, - std::set& modules) + std::set& result) { + assert(mapfile && base && "Can't findModulesDefiningSymbols on new archive"); + if (symTab.empty()) { + // We don't have a symbol table, so we must build it now but lets also + // make sure that we populate the modules table as we do this to ensure + // that we don't load them twice when findModuleDefiningSymbol is called + // below. + + // Get a pointer to the first file + const char* At = ((const char*)base) + firstFileOffset; + const char* End = ((const char*)base) + mapfile->size(); + + while ( At < End) { + // Compute the offset to be put in the symbol table + unsigned offset = At - base - firstFileOffset; + + // Parse the file's header + ArchiveMember* mbr = parseMemberHeader(At, End); + + // If it contains symbols + if (mbr->isBytecode() || mbr->isCompressedBytecode()) { + // Get the symbols + std::vector symbols; + ModuleProvider* MP = GetBytecodeSymbols((const unsigned char*)At, + mbr->getSize(), mbr->getPath().get(),symbols); + + if (MP) { + // Insert the module's symbols into the symbol table + for (std::vector::iterator I = symbols.begin(), + E=symbols.end(); I != E; ++I ) { + symTab.insert(std::make_pair(*I,offset)); + } + // Insert the ModuleProvider and the ArchiveMember into the table of + // modules. + modules.insert(std::make_pair(offset,std::make_pair(MP,mbr))); + } else { + throw std::string("Can't parse bytecode member: ") + + mbr->getPath().get(); + } + } + } + } + + // At this point we have a valid symbol table (one way or another) so we + // just use it to quickly find the symbols requested. + for (std::set::const_iterator I=symbols.begin(), E=symbols.end(); I != E; ++I) { ModuleProvider* mp = findModuleDefiningSymbol(*I); if (mp) { - modules.insert(mp); + result.insert(mp); } } } Index: llvm/lib/Bytecode/Archive/ArchiveWriter.cpp diff -u llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.2 llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.3 --- llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.2 Sun Nov 14 15:56:59 2004 +++ llvm/lib/Bytecode/Archive/ArchiveWriter.cpp Sun Nov 14 19:20:11 2004 @@ -197,19 +197,28 @@ if (CreateSymbolTable && (member.isBytecode() || member.isCompressedBytecode())) { std::vector symbols; - GetBytecodeSymbols((const unsigned char*)data,fSize,member.getPath().get(), - symbols); - for (std::vector::iterator SI = symbols.begin(), - SE = symbols.end(); SI != SE; ++SI) { - - std::pair Res = - symTab.insert(std::make_pair(*SI,filepos)); - - if (Res.second) { - symTabSize += SI->length() + - numVbrBytes(SI->length()) + - numVbrBytes(filepos); + ModuleProvider* MP = GetBytecodeSymbols( + (const unsigned char*)data,fSize,member.getPath().get(), symbols); + + // If the bytecode parsed successfully + if ( MP ) { + for (std::vector::iterator SI = symbols.begin(), + SE = symbols.end(); SI != SE; ++SI) { + + std::pair Res = + symTab.insert(std::make_pair(*SI,filepos)); + + if (Res.second) { + symTabSize += SI->length() + + numVbrBytes(SI->length()) + + numVbrBytes(filepos); + } } + // We don't need this module any more. + delete MP; + } else { + throw std::string("Can't parse bytecode member: ") + + member.getPath().get(); } } From reid at x10sys.com Sun Nov 14 19:40:58 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 19:40:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Archive/ArchiveReader.cpp Message-ID: <200411150140.TAA25530@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Archive: ArchiveReader.cpp updated: 1.23 -> 1.24 --- Log message: * Make sure the string table gets read even if there isn't a foreign symbol table. * Make sure we update the file pointer for each member when rebuilding the symbol table. --- Diffs of the changes: (+20 -8) Index: llvm/lib/Bytecode/Archive/ArchiveReader.cpp diff -u llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.23 llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.24 --- llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.23 Sun Nov 14 19:20:11 2004 +++ llvm/lib/Bytecode/Archive/ArchiveReader.cpp Sun Nov 14 19:40:20 2004 @@ -309,18 +309,25 @@ if (mbr->isForeignSymbolTable()) { // Skip the foreign symbol table, we don't do anything with it At += mbr->getSize(); + if (mbr->getSize() % 2 != 0) + At++; delete mbr; - // See if there's a string table too + // Read the next one + FirstFile = At; + mbr = parseMemberHeader(At,End); + } + + if (mbr->isStringTable()) { + // Process the string table entry + strtab.assign((const char*)mbr->getData(),mbr->getSize()); + At += mbr->getSize(); + if (mbr->getSize() % 2 != 0) + At++; + delete mbr; + // Get the next one FirstFile = At; mbr = parseMemberHeader(At,End); - if (mbr->isStringTable()) { - strtab.assign((const char*)mbr->getData(),mbr->getSize()); - At += mbr->getSize(); - delete mbr; - FirstFile = At; - mbr = parseMemberHeader(At,End); - } } // See if its the symbol table @@ -432,6 +439,11 @@ mbr->getPath().get(); } } + + // Go to the next file location + At += mbr->getSize(); + if (mbr->getSize() % 2 != 0) + At++; } } From reid at x10sys.com Sun Nov 14 22:37:12 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:37:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/AIX/TimeValue.cpp Message-ID: <200411150437.WAA27085@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/AIX: TimeValue.cpp updated: 1.1 -> 1.2 --- Log message: Consolidate the implementation of TimeValue::now() for Unix to use the seemingly ubiquitous gettimeofday(3) call. --- Diffs of the changes: (+1 -3) Index: llvm/lib/System/AIX/TimeValue.cpp diff -u llvm/lib/System/AIX/TimeValue.cpp:1.1 llvm/lib/System/AIX/TimeValue.cpp:1.2 --- llvm/lib/System/AIX/TimeValue.cpp:1.1 Sat Sep 25 00:03:53 2004 +++ llvm/lib/System/AIX/TimeValue.cpp Sun Nov 14 22:36:25 2004 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.h" +#include "../Unix/Unix.cpp" namespace llvm { using namespace sys; @@ -22,8 +22,6 @@ //=== and must not be generic UNIX code (see ../Unix/TimeValue.cpp) //===----------------------------------------------------------------------===// -// FIXME: Need TimeValue::now() - // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab } From reid at x10sys.com Sun Nov 14 22:37:22 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:37:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Linux/TimeValue.cpp Message-ID: <200411150437.WAA27090@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Linux: TimeValue.cpp updated: 1.4 -> 1.5 --- Log message: Consolidate the implementation of TimeValue::now() for Unix to use the seemingly ubiquitous gettimeofday(3) call. --- Diffs of the changes: (+0 -13) Index: llvm/lib/System/Linux/TimeValue.cpp diff -u llvm/lib/System/Linux/TimeValue.cpp:1.4 llvm/lib/System/Linux/TimeValue.cpp:1.5 --- llvm/lib/System/Linux/TimeValue.cpp:1.4 Sun Nov 14 16:07:04 2004 +++ llvm/lib/System/Linux/TimeValue.cpp Sun Nov 14 22:36:34 2004 @@ -14,8 +14,6 @@ // Include the generic Unix implementation #include "../Unix/TimeValue.cpp" -#include - namespace llvm { using namespace sys; @@ -25,17 +23,6 @@ //=== and must not be generic UNIX code (see ../Unix/TimeValue.cpp) //===----------------------------------------------------------------------===// -TimeValue TimeValue::now() { - struct timeval the_time; - timerclear(&the_time); - if (0 != ::gettimeofday(&the_time,0)) - ThrowErrno("Couldn't obtain time of day"); - - return TimeValue( - static_cast( the_time.tv_sec ), - static_cast( the_time.tv_usec * - NANOSECONDS_PER_MICROSECOND ) ); -} // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab } From reid at x10sys.com Sun Nov 14 22:37:22 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:37:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Linux/TimeValue.cpp Message-ID: <200411150437.WAA27093@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Linux: TimeValue.cpp updated: 1.4 -> 1.6 --- Log message: Consolidate the implementation of TimeValue::now() for Unix to use the seemingly ubiquitous gettimeofday(3) call. --- Diffs of the changes: (+0 -13) Index: llvm/lib/System/Linux/TimeValue.cpp diff -u llvm/lib/System/Linux/TimeValue.cpp:1.4 llvm/lib/System/Linux/TimeValue.cpp:1.6 --- llvm/lib/System/Linux/TimeValue.cpp:1.4 Sun Nov 14 16:07:04 2004 +++ llvm/lib/System/Linux/TimeValue.cpp Sun Nov 14 22:36:35 2004 @@ -14,8 +14,6 @@ // Include the generic Unix implementation #include "../Unix/TimeValue.cpp" -#include - namespace llvm { using namespace sys; @@ -25,17 +23,6 @@ //=== and must not be generic UNIX code (see ../Unix/TimeValue.cpp) //===----------------------------------------------------------------------===// -TimeValue TimeValue::now() { - struct timeval the_time; - timerclear(&the_time); - if (0 != ::gettimeofday(&the_time,0)) - ThrowErrno("Couldn't obtain time of day"); - - return TimeValue( - static_cast( the_time.tv_sec ), - static_cast( the_time.tv_usec * - NANOSECONDS_PER_MICROSECOND ) ); -} // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab } From reid at x10sys.com Sun Nov 14 22:37:23 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:37:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Darwin/TimeValue.cpp Message-ID: <200411150437.WAA27094@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Darwin: TimeValue.cpp updated: 1.1 -> 1.2 --- Log message: Consolidate the implementation of TimeValue::now() for Unix to use the seemingly ubiquitous gettimeofday(3) call. --- Diffs of the changes: (+1 -3) Index: llvm/lib/System/Darwin/TimeValue.cpp diff -u llvm/lib/System/Darwin/TimeValue.cpp:1.1 llvm/lib/System/Darwin/TimeValue.cpp:1.2 --- llvm/lib/System/Darwin/TimeValue.cpp:1.1 Sat Sep 25 00:03:54 2004 +++ llvm/lib/System/Darwin/TimeValue.cpp Sun Nov 14 22:36:34 2004 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.h" +#include "../Unix/Unix.cpp" namespace llvm { using namespace sys; @@ -22,8 +22,6 @@ //=== and must not be generic UNIX code (see ../Unix/TimeValue.cpp) //===----------------------------------------------------------------------===// -// FIXME: Need TimeValue::now() - // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab } From reid at x10sys.com Sun Nov 14 22:37:23 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:37:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/SunOS/TimeValue.cpp Message-ID: <200411150437.WAA27096@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/SunOS: TimeValue.cpp updated: 1.2 -> 1.3 --- Log message: Consolidate the implementation of TimeValue::now() for Unix to use the seemingly ubiquitous gettimeofday(3) call. --- Diffs of the changes: (+1 -14) Index: llvm/lib/System/SunOS/TimeValue.cpp diff -u llvm/lib/System/SunOS/TimeValue.cpp:1.2 llvm/lib/System/SunOS/TimeValue.cpp:1.3 --- llvm/lib/System/SunOS/TimeValue.cpp:1.2 Sat Sep 25 03:32:37 2004 +++ llvm/lib/System/SunOS/TimeValue.cpp Sun Nov 14 22:36:35 2004 @@ -12,8 +12,7 @@ //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.h" -#include +#include "../Unix/Unix.cpp" namespace llvm { using namespace sys; @@ -23,18 +22,6 @@ //=== and must not be generic UNIX code (see ../Unix/TimeValue.cpp) //===----------------------------------------------------------------------===// -TimeValue TimeValue::now() { - struct timeval the_time; - timerclear(&the_time); - if (0 != ::gettimeofday(&the_time,0)) - ThrowErrno("Couldn't obtain time of day"); - - return TimeValue( - static_cast( the_time.tv_sec ), - static_cast( the_time.tv_usec * - NANOSECONDS_PER_MICROSECOND ) ); -} - // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab } From reid at x10sys.com Sun Nov 14 22:37:23 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:37:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/FreeBSD/TimeValue.cpp Message-ID: <200411150437.WAA27103@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/FreeBSD: TimeValue.cpp updated: 1.2 -> 1.3 --- Log message: Consolidate the implementation of TimeValue::now() for Unix to use the seemingly ubiquitous gettimeofday(3) call. --- Diffs of the changes: (+1 -14) Index: llvm/lib/System/FreeBSD/TimeValue.cpp diff -u llvm/lib/System/FreeBSD/TimeValue.cpp:1.2 llvm/lib/System/FreeBSD/TimeValue.cpp:1.3 --- llvm/lib/System/FreeBSD/TimeValue.cpp:1.2 Tue Sep 28 18:54:12 2004 +++ llvm/lib/System/FreeBSD/TimeValue.cpp Sun Nov 14 22:36:34 2004 @@ -12,8 +12,7 @@ //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.h" -#include +#include "../Unix/Unix.cpp" namespace llvm { using namespace sys; @@ -23,18 +22,6 @@ //=== and must not be generic UNIX code (see ../Unix/TimeValue.cpp) //===----------------------------------------------------------------------===// -TimeValue TimeValue::now() { - struct timeval the_time; - timerclear(&the_time); - if (0 != ::gettimeofday(&the_time,0)) - ThrowErrno("Couldn't obtain time of day"); - - return TimeValue( - static_cast( the_time.tv_sec + - PosixZeroTime.seconds_ ), - static_cast( the_time.tv_usec * - NANOSECONDS_PER_MICROSECOND ) ); -} // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab } From reid at x10sys.com Sun Nov 14 22:37:23 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:37:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Interix/TimeValue.cpp Message-ID: <200411150437.WAA27107@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Interix: TimeValue.cpp updated: 1.1 -> 1.2 --- Log message: Consolidate the implementation of TimeValue::now() for Unix to use the seemingly ubiquitous gettimeofday(3) call. --- Diffs of the changes: (+1 -3) Index: llvm/lib/System/Interix/TimeValue.cpp diff -u llvm/lib/System/Interix/TimeValue.cpp:1.1 llvm/lib/System/Interix/TimeValue.cpp:1.2 --- llvm/lib/System/Interix/TimeValue.cpp:1.1 Sat Sep 25 00:03:54 2004 +++ llvm/lib/System/Interix/TimeValue.cpp Sun Nov 14 22:36:34 2004 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.h" +#include "../Unix/Unix.cpp" namespace llvm { using namespace sys; @@ -22,8 +22,6 @@ //=== and must not be generic UNIX code (see ../Unix/TimeValue.cpp) //===----------------------------------------------------------------------===// -// FIXME: Need TimeValue::now() - // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab } From reid at x10sys.com Sun Nov 14 22:37:23 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:37:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/TimeValue.cpp Message-ID: <200411150437.WAA27095@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: TimeValue.cpp updated: 1.2 -> 1.3 --- Log message: Consolidate the implementation of TimeValue::now() for Unix to use the seemingly ubiquitous gettimeofday(3) call. --- Diffs of the changes: (+13 -0) Index: llvm/lib/System/Unix/TimeValue.cpp diff -u llvm/lib/System/Unix/TimeValue.cpp:1.2 llvm/lib/System/Unix/TimeValue.cpp:1.3 --- llvm/lib/System/Unix/TimeValue.cpp:1.2 Sun Nov 14 16:10:08 2004 +++ llvm/lib/System/Unix/TimeValue.cpp Sun Nov 14 22:36:35 2004 @@ -19,6 +19,7 @@ #include "Unix.h" #include +#include namespace llvm { using namespace sys; @@ -34,5 +35,17 @@ return result.substr(0,24); } +TimeValue TimeValue::now() { + struct timeval the_time; + ::timerclear(&the_time); + if (0 != ::gettimeofday(&the_time,0)) + ThrowErrno("Couldn't obtain time of day"); + + return TimeValue( + static_cast( the_time.tv_sec ), + static_cast( the_time.tv_usec * + NANOSECONDS_PER_MICROSECOND ) ); +} + } // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab From reid at x10sys.com Sun Nov 14 22:37:23 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:37:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Cygwin/TimeValue.cpp Message-ID: <200411150437.WAA27111@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Cygwin: TimeValue.cpp updated: 1.1 -> 1.2 --- Log message: Consolidate the implementation of TimeValue::now() for Unix to use the seemingly ubiquitous gettimeofday(3) call. --- Diffs of the changes: (+1 -3) Index: llvm/lib/System/Cygwin/TimeValue.cpp diff -u llvm/lib/System/Cygwin/TimeValue.cpp:1.1 llvm/lib/System/Cygwin/TimeValue.cpp:1.2 --- llvm/lib/System/Cygwin/TimeValue.cpp:1.1 Sat Sep 25 00:03:54 2004 +++ llvm/lib/System/Cygwin/TimeValue.cpp Sun Nov 14 22:36:34 2004 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.h" +#include "../Unix/Unix.cpp" namespace llvm { using namespace sys; @@ -22,8 +22,6 @@ //=== and must not be generic UNIX code (see ../Unix/TimeValue.cpp) //===----------------------------------------------------------------------===// -// FIXME: Need TimeValue::now() - // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab } From reid at x10sys.com Sun Nov 14 22:43:21 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:43:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/TimeValue.cpp Message-ID: <200411150443.WAA27173@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: TimeValue.cpp updated: 1.3 -> 1.4 --- Log message: Make it actually compile on Solaris. --- Diffs of the changes: (+1 -1) Index: llvm/lib/System/Unix/TimeValue.cpp diff -u llvm/lib/System/Unix/TimeValue.cpp:1.3 llvm/lib/System/Unix/TimeValue.cpp:1.4 --- llvm/lib/System/Unix/TimeValue.cpp:1.3 Sun Nov 14 22:36:35 2004 +++ llvm/lib/System/Unix/TimeValue.cpp Sun Nov 14 22:42:34 2004 @@ -37,7 +37,7 @@ TimeValue TimeValue::now() { struct timeval the_time; - ::timerclear(&the_time); + timerclear(&the_time); if (0 != ::gettimeofday(&the_time,0)) ThrowErrno("Couldn't obtain time of day"); From reid at x10sys.com Sun Nov 14 22:43:30 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:43:30 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/SunOS/TimeValue.cpp Message-ID: <200411150443.WAA27178@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/SunOS: TimeValue.cpp updated: 1.3 -> 1.4 --- Log message: Make it actually compile on Solaris. --- Diffs of the changes: (+1 -1) Index: llvm/lib/System/SunOS/TimeValue.cpp diff -u llvm/lib/System/SunOS/TimeValue.cpp:1.3 llvm/lib/System/SunOS/TimeValue.cpp:1.4 --- llvm/lib/System/SunOS/TimeValue.cpp:1.3 Sun Nov 14 22:36:35 2004 +++ llvm/lib/System/SunOS/TimeValue.cpp Sun Nov 14 22:42:44 2004 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.cpp" +#include "../Unix/TimeValue.cpp" namespace llvm { using namespace sys; From lattner at cs.uiuc.edu Sun Nov 14 22:44:35 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 22:44:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200411150444.iAF4iZmj030233@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: SCCP.cpp updated: 1.105 -> 1.106 --- Log message: Substantially refactor the SCCP class into an SCCP pass and an SCCPSolver class. The only changes are minor: * Do not try to SCCP instructions that return void in the rewrite loop. This is silly and fool hardy, wasting a map lookup and adding an entry to the map which is never used. * If we decide something has an undefined value, rewrite it to undef, potentially leading to further simplications. --- Diffs of the changes: (+210 -169) Index: llvm/lib/Transforms/Scalar/SCCP.cpp diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.105 llvm/lib/Transforms/Scalar/SCCP.cpp:1.106 --- llvm/lib/Transforms/Scalar/SCCP.cpp:1.105 Wed Oct 27 11:12:28 2004 +++ llvm/lib/Transforms/Scalar/SCCP.cpp Sun Nov 14 22:44:20 2004 @@ -89,12 +89,11 @@ //===----------------------------------------------------------------------===// -// SCCP Class // -// This class does all of the work of Sparse Conditional Constant Propagation. -// -namespace { -class SCCP : public FunctionPass, public InstVisitor { +/// SCCPSolver - This class is a general purpose solver for Sparse Conditional +/// Constant Propagation. +/// +class SCCPSolver : public InstVisitor { std::set BBExecutable;// The basic blocks that are executable hash_map ValueState; // The state each value is in... @@ -121,22 +120,31 @@ std::set KnownFeasibleEdges; public: - // runOnFunction - Run the Sparse Conditional Constant Propagation algorithm, - // and return true if the function was modified. - // - bool runOnFunction(Function &F); - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesCFG(); + /// MarkBlockExecutable - This method can be used by clients to mark all of + /// the blocks that are known to be intrinsically live in the processed unit. + void MarkBlockExecutable(BasicBlock *BB) { + DEBUG(std::cerr << "Marking Block Executable: " << BB->getName() << "\n"); + BBExecutable.insert(BB); // Basic block is executable! + BBWorkList.push_back(BB); // Add the block to the work list! + } + + /// Solve - Solve for constants and executable blocks. + /// + void Solve(); + + /// getExecutableBlocks - Once we have solved for constants, return the set of + /// blocks that is known to be executable. + std::set &getExecutableBlocks() { + return BBExecutable; + } + + /// getValueMapping - Once we have solved for constants, return the mapping of + /// LLVM values to InstVals. + hash_map &getValueMapping() { + return ValueState; } - - //===--------------------------------------------------------------------===// - // The implementation of this class - // private: - friend struct InstVisitor; // Allow callbacks from visitor - // markConstant - Make a value be marked as "constant". If the value // is not already a constant, add it to the instruction work list so that // the users of the instruction are updated later. @@ -158,7 +166,8 @@ inline void markOverdefined(InstVal &IV, Instruction *I) { if (IV.markOverdefined()) { DEBUG(std::cerr << "markOverdefined: " << *I); - OverdefinedInstWorkList.push_back(I); // Only instructions go on the work list + // Only instructions go on the work list + OverdefinedInstWorkList.push_back(I); } } inline void markOverdefined(Instruction *I) { @@ -206,12 +215,33 @@ } } else { - DEBUG(std::cerr << "Marking Block Executable: " << Dest->getName()<<"\n"); - BBExecutable.insert(Dest); // Basic block is executable! - BBWorkList.push_back(Dest); // Add the block to the work list! + MarkBlockExecutable(Dest); } } + // getFeasibleSuccessors - Return a vector of booleans to indicate which + // successors are reachable from a given terminator instruction. + // + void getFeasibleSuccessors(TerminatorInst &TI, std::vector &Succs); + + // isEdgeFeasible - Return true if the control flow edge from the 'From' basic + // block to the 'To' basic block is currently feasible... + // + bool isEdgeFeasible(BasicBlock *From, BasicBlock *To); + + // OperandChangedState - This method is invoked on all of the users of an + // instruction that was just changed state somehow.... Based on this + // information, we need to update the specified user of this instruction. + // + void OperandChangedState(User *U) { + // Only instructions use other variable values! + Instruction &I = cast(*U); + if (BBExecutable.count(I.getParent())) // Inst is executable? + visit(I); + } + +private: + friend class InstVisitor; // visit implementations - Something changed in this instruction... Either an // operand made a transition, or the instruction is newly executable. Change @@ -249,149 +279,13 @@ std::cerr << "SCCP: Don't know how to handle: " << I; markOverdefined(&I); // Just in case } - - // getFeasibleSuccessors - Return a vector of booleans to indicate which - // successors are reachable from a given terminator instruction. - // - void getFeasibleSuccessors(TerminatorInst &TI, std::vector &Succs); - - // isEdgeFeasible - Return true if the control flow edge from the 'From' basic - // block to the 'To' basic block is currently feasible... - // - bool isEdgeFeasible(BasicBlock *From, BasicBlock *To); - - // OperandChangedState - This method is invoked on all of the users of an - // instruction that was just changed state somehow.... Based on this - // information, we need to update the specified user of this instruction. - // - void OperandChangedState(User *U) { - // Only instructions use other variable values! - Instruction &I = cast(*U); - if (BBExecutable.count(I.getParent())) // Inst is executable? - visit(I); - } }; - RegisterOpt X("sccp", "Sparse Conditional Constant Propagation"); -} // end anonymous namespace - - -// createSCCPPass - This is the public interface to this file... -FunctionPass *llvm::createSCCPPass() { - return new SCCP(); -} - - -//===----------------------------------------------------------------------===// -// SCCP Class Implementation - - -// runOnFunction() - Run the Sparse Conditional Constant Propagation algorithm, -// and return true if the function was modified. -// -bool SCCP::runOnFunction(Function &F) { - // Mark the first block of the function as being executable... - BBExecutable.insert(F.begin()); // Basic block is executable! - BBWorkList.push_back(F.begin()); // Add the block to the work list! - - // Process the work lists until they are empty! - while (!BBWorkList.empty() || !InstWorkList.empty() || - !OverdefinedInstWorkList.empty()) { - // Process the instruction work list... - while (!OverdefinedInstWorkList.empty()) { - Instruction *I = OverdefinedInstWorkList.back(); - OverdefinedInstWorkList.pop_back(); - - DEBUG(std::cerr << "\nPopped off OI-WL: " << I); - - // "I" got into the work list because it either made the transition from - // bottom to constant - // - // Anything on this worklist that is overdefined need not be visited - // since all of its users will have already been marked as overdefined - // Update all of the users of this instruction's value... - // - for_each(I->use_begin(), I->use_end(), - bind_obj(this, &SCCP::OperandChangedState)); - } - // Process the instruction work list... - while (!InstWorkList.empty()) { - Instruction *I = InstWorkList.back(); - InstWorkList.pop_back(); - - DEBUG(std::cerr << "\nPopped off I-WL: " << *I); - - // "I" got into the work list because it either made the transition from - // bottom to constant - // - // Anything on this worklist that is overdefined need not be visited - // since all of its users will have already been marked as overdefined. - // Update all of the users of this instruction's value... - // - InstVal &Ival = getValueState (I); - if (!Ival.isOverdefined()) - for_each(I->use_begin(), I->use_end(), - bind_obj(this, &SCCP::OperandChangedState)); - } - - // Process the basic block work list... - while (!BBWorkList.empty()) { - BasicBlock *BB = BBWorkList.back(); - BBWorkList.pop_back(); - - DEBUG(std::cerr << "\nPopped off BBWL: " << *BB); - - // Notify all instructions in this basic block that they are newly - // executable. - visit(BB); - } - } - - DEBUG(for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) - if (!BBExecutable.count(I)) - std::cerr << "BasicBlock Dead:" << *I); - - // Iterate over all of the instructions in a function, replacing them with - // constants if we have found them to be of constant values. - // - bool MadeChanges = false; - for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) - for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) { - Instruction &Inst = *BI; - InstVal &IV = ValueState[&Inst]; - if (IV.isConstant()) { - Constant *Const = IV.getConstant(); - DEBUG(std::cerr << "Constant: " << *Const << " = " << Inst); - - // Replaces all of the uses of a variable with uses of the constant. - Inst.replaceAllUsesWith(Const); - - // Remove the operator from the list of definitions... and delete it. - BI = BB->getInstList().erase(BI); - - // Hey, we just changed something! - MadeChanges = true; - ++NumInstRemoved; - } else { - ++BI; - } - } - - // Reset state so that the next invocation will have empty data structures - BBExecutable.clear(); - ValueState.clear(); - std::vector().swap(OverdefinedInstWorkList); - std::vector().swap(InstWorkList); - std::vector().swap(BBWorkList); - - return MadeChanges; -} - - // getFeasibleSuccessors - Return a vector of booleans to indicate which // successors are reachable from a given terminator instruction. // -void SCCP::getFeasibleSuccessors(TerminatorInst &TI, std::vector &Succs) { +void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI, + std::vector &Succs) { Succs.resize(TI.getNumSuccessors()); if (BranchInst *BI = dyn_cast(&TI)) { if (BI->isUnconditional()) { @@ -441,7 +335,7 @@ // isEdgeFeasible - Return true if the control flow edge from the 'From' basic // block to the 'To' basic block is currently feasible... // -bool SCCP::isEdgeFeasible(BasicBlock *From, BasicBlock *To) { +bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) { assert(BBExecutable.count(To) && "Dest should always be alive!"); // Make sure the source basic block is executable!! @@ -514,7 +408,7 @@ // 7. If a conditional branch has a value that is overdefined, make all // successors executable. // -void SCCP::visitPHINode(PHINode &PN) { +void SCCPSolver::visitPHINode(PHINode &PN) { InstVal &PNIV = getValueState(&PN); if (PNIV.isOverdefined()) { // There may be instructions using this PHI node that are not overdefined @@ -586,7 +480,7 @@ markConstant(PNIV, &PN, OperandVal); // Acquire operand value } -void SCCP::visitTerminatorInst(TerminatorInst &TI) { +void SCCPSolver::visitTerminatorInst(TerminatorInst &TI) { std::vector SuccFeasible; getFeasibleSuccessors(TI, SuccFeasible); @@ -598,7 +492,7 @@ markEdgeExecutable(BB, TI.getSuccessor(i)); } -void SCCP::visitCastInst(CastInst &I) { +void SCCPSolver::visitCastInst(CastInst &I) { Value *V = I.getOperand(0); InstVal &VState = getValueState(V); if (VState.isOverdefined()) // Inherit overdefinedness of operand @@ -607,7 +501,7 @@ markConstant(&I, ConstantExpr::getCast(VState.getConstant(), I.getType())); } -void SCCP::visitSelectInst(SelectInst &I) { +void SCCPSolver::visitSelectInst(SelectInst &I) { InstVal &CondValue = getValueState(I.getCondition()); if (CondValue.isOverdefined()) markOverdefined(&I); @@ -630,7 +524,7 @@ } // Handle BinaryOperators and Shift Instructions... -void SCCP::visitBinaryOperator(Instruction &I) { +void SCCPSolver::visitBinaryOperator(Instruction &I) { InstVal &IV = ValueState[&I]; if (IV.isOverdefined()) return; @@ -716,7 +610,7 @@ // Handle getelementptr instructions... if all operands are constants then we // can turn this into a getelementptr ConstantExpr. // -void SCCP::visitGetElementPtrInst(GetElementPtrInst &I) { +void SCCPSolver::visitGetElementPtrInst(GetElementPtrInst &I) { InstVal &IV = ValueState[&I]; if (IV.isOverdefined()) return; @@ -769,7 +663,7 @@ // Handle load instructions. If the operand is a constant pointer to a constant // global, we can replace the load with the loaded constant value! -void SCCP::visitLoadInst(LoadInst &I) { +void SCCPSolver::visitLoadInst(LoadInst &I) { InstVal &IV = ValueState[&I]; if (IV.isOverdefined()) return; @@ -807,7 +701,7 @@ markOverdefined(IV, &I); } -void SCCP::visitCallInst(CallInst &I) { +void SCCPSolver::visitCallInst(CallInst &I) { InstVal &IV = ValueState[&I]; if (IV.isOverdefined()) return; @@ -837,3 +731,150 @@ else markOverdefined(IV, &I); } + + +void SCCPSolver::Solve() { + // Process the work lists until they are empty! + while (!BBWorkList.empty() || !InstWorkList.empty() || + !OverdefinedInstWorkList.empty()) { + // Process the instruction work list... + while (!OverdefinedInstWorkList.empty()) { + Instruction *I = OverdefinedInstWorkList.back(); + OverdefinedInstWorkList.pop_back(); + + DEBUG(std::cerr << "\nPopped off OI-WL: " << I); + + // "I" got into the work list because it either made the transition from + // bottom to constant + // + // Anything on this worklist that is overdefined need not be visited + // since all of its users will have already been marked as overdefined + // Update all of the users of this instruction's value... + // + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); + UI != E; ++UI) + OperandChangedState(*UI); + } + // Process the instruction work list... + while (!InstWorkList.empty()) { + Instruction *I = InstWorkList.back(); + InstWorkList.pop_back(); + + DEBUG(std::cerr << "\nPopped off I-WL: " << *I); + + // "I" got into the work list because it either made the transition from + // bottom to constant + // + // Anything on this worklist that is overdefined need not be visited + // since all of its users will have already been marked as overdefined. + // Update all of the users of this instruction's value... + // + if (!getValueState(I).isOverdefined()) + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); + UI != E; ++UI) + OperandChangedState(*UI); + } + + // Process the basic block work list... + while (!BBWorkList.empty()) { + BasicBlock *BB = BBWorkList.back(); + BBWorkList.pop_back(); + + DEBUG(std::cerr << "\nPopped off BBWL: " << *BB); + + // Notify all instructions in this basic block that they are newly + // executable. + visit(BB); + } + } +} + + +namespace { +//===----------------------------------------------------------------------===// +// +/// SCCP Class - This class does all of the work of Sparse Conditional Constant +/// Propagation. +/// +class SCCP : public FunctionPass, public InstVisitor { +public: + + // runOnFunction - Run the Sparse Conditional Constant Propagation algorithm, + // and return true if the function was modified. + // + bool runOnFunction(Function &F); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); + } +}; + + RegisterOpt X("sccp", "Sparse Conditional Constant Propagation"); +} // end anonymous namespace + + +// createSCCPPass - This is the public interface to this file... +FunctionPass *llvm::createSCCPPass() { + return new SCCP(); +} + + +//===----------------------------------------------------------------------===// +// SCCP Class Implementation + + +// runOnFunction() - Run the Sparse Conditional Constant Propagation algorithm, +// and return true if the function was modified. +// +bool SCCP::runOnFunction(Function &F) { + SCCPSolver Solver; + + // Mark the first block of the function as being executable. + Solver.MarkBlockExecutable(F.begin()); + + // Solve for constants. + Solver.Solve(); + + DEBUG(std::cerr << "SCCP on function '" << F.getName() << "'\n"); + DEBUG(std::set &ExecutableBBs = Solver.getExecutableBlocks(); + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) + if (!ExecutableBBs.count(I)) + std::cerr << " BasicBlock Dead:" << *I); + + // Iterate over all of the instructions in a function, replacing them with + // constants if we have found them to be of constant values. + // + bool MadeChanges = false; + hash_map &Values = Solver.getValueMapping(); + for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) + for (BasicBlock::iterator BI = BB->begin(), E = BB->end(); BI != E; ) { + Instruction *Inst = BI++; + if (Inst->getType() != Type::VoidTy) { + InstVal &IV = Values[Inst]; + if (IV.isConstant() || IV.isUndefined()) { + Constant *Const; + if (IV.isConstant()) { + Const = IV.getConstant(); + DEBUG(std::cerr << " Constant: " << *Const << " = " << *Inst); + } else { + Const = UndefValue::get(Inst->getType()); + DEBUG(std::cerr << " Undefined: " << *Inst); + } + + // Replaces all of the uses of a variable with uses of the constant. + Inst->replaceAllUsesWith(Const); + + // Delete the instruction. + BB->getInstList().erase(Inst); + + // Hey, we just changed something! + MadeChanges = true; + ++NumInstRemoved; + } + } + } + + return MadeChanges; +} + + From reid at x10sys.com Sun Nov 14 22:48:00 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:48:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/AIX/TimeValue.cpp Message-ID: <200411150448.WAA27380@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/AIX: TimeValue.cpp updated: 1.2 -> 1.3 --- Log message: Actually get the #include correct so it compiles .. duh. --- Diffs of the changes: (+1 -1) Index: llvm/lib/System/AIX/TimeValue.cpp diff -u llvm/lib/System/AIX/TimeValue.cpp:1.2 llvm/lib/System/AIX/TimeValue.cpp:1.3 --- llvm/lib/System/AIX/TimeValue.cpp:1.2 Sun Nov 14 22:36:25 2004 +++ llvm/lib/System/AIX/TimeValue.cpp Sun Nov 14 22:47:13 2004 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.cpp" +#include "../Unix/TimeValue.cpp" namespace llvm { using namespace sys; From reid at x10sys.com Sun Nov 14 22:48:09 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:48:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Cygwin/TimeValue.cpp Message-ID: <200411150448.WAA27384@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Cygwin: TimeValue.cpp updated: 1.2 -> 1.3 --- Log message: Actually get the #include correct so it compiles .. duh. --- Diffs of the changes: (+1 -1) Index: llvm/lib/System/Cygwin/TimeValue.cpp diff -u llvm/lib/System/Cygwin/TimeValue.cpp:1.2 llvm/lib/System/Cygwin/TimeValue.cpp:1.3 --- llvm/lib/System/Cygwin/TimeValue.cpp:1.2 Sun Nov 14 22:36:34 2004 +++ llvm/lib/System/Cygwin/TimeValue.cpp Sun Nov 14 22:47:22 2004 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.cpp" +#include "../Unix/TimeValue.cpp" namespace llvm { using namespace sys; From reid at x10sys.com Sun Nov 14 22:48:09 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:48:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Darwin/TimeValue.cpp Message-ID: <200411150448.WAA27383@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Darwin: TimeValue.cpp updated: 1.2 -> 1.3 --- Log message: Actually get the #include correct so it compiles .. duh. --- Diffs of the changes: (+1 -1) Index: llvm/lib/System/Darwin/TimeValue.cpp diff -u llvm/lib/System/Darwin/TimeValue.cpp:1.2 llvm/lib/System/Darwin/TimeValue.cpp:1.3 --- llvm/lib/System/Darwin/TimeValue.cpp:1.2 Sun Nov 14 22:36:34 2004 +++ llvm/lib/System/Darwin/TimeValue.cpp Sun Nov 14 22:47:22 2004 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.cpp" +#include "../Unix/TimeValue.cpp" namespace llvm { using namespace sys; From reid at x10sys.com Sun Nov 14 22:48:10 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:48:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Interix/TimeValue.cpp Message-ID: <200411150448.WAA27390@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Interix: TimeValue.cpp updated: 1.2 -> 1.3 --- Log message: Actually get the #include correct so it compiles .. duh. --- Diffs of the changes: (+1 -1) Index: llvm/lib/System/Interix/TimeValue.cpp diff -u llvm/lib/System/Interix/TimeValue.cpp:1.2 llvm/lib/System/Interix/TimeValue.cpp:1.3 --- llvm/lib/System/Interix/TimeValue.cpp:1.2 Sun Nov 14 22:36:34 2004 +++ llvm/lib/System/Interix/TimeValue.cpp Sun Nov 14 22:47:22 2004 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.cpp" +#include "../Unix/TimeValue.cpp" namespace llvm { using namespace sys; From reid at x10sys.com Sun Nov 14 22:48:10 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:48:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Linux/TimeValue.cpp Message-ID: <200411150448.WAA27389@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Linux: TimeValue.cpp updated: 1.6 -> 1.7 --- Log message: Actually get the #include correct so it compiles .. duh. --- Diffs of the changes: (+1 -1) Index: llvm/lib/System/Linux/TimeValue.cpp diff -u llvm/lib/System/Linux/TimeValue.cpp:1.6 llvm/lib/System/Linux/TimeValue.cpp:1.7 --- llvm/lib/System/Linux/TimeValue.cpp:1.6 Sun Nov 14 22:36:35 2004 +++ llvm/lib/System/Linux/TimeValue.cpp Sun Nov 14 22:47:22 2004 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file provides the Linux specific implementation of the TimeValue class. +// This file provides the Linux implementation of the TimeValue class. // //===----------------------------------------------------------------------===// From reid at x10sys.com Sun Nov 14 22:48:10 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:48:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/SunOS/TimeValue.cpp Message-ID: <200411150448.WAA27391@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/SunOS: TimeValue.cpp updated: 1.4 -> 1.5 --- Log message: Actually get the #include correct so it compiles .. duh. --- Diffs of the changes: (+1 -1) Index: llvm/lib/System/SunOS/TimeValue.cpp diff -u llvm/lib/System/SunOS/TimeValue.cpp:1.4 llvm/lib/System/SunOS/TimeValue.cpp:1.5 --- llvm/lib/System/SunOS/TimeValue.cpp:1.4 Sun Nov 14 22:42:44 2004 +++ llvm/lib/System/SunOS/TimeValue.cpp Sun Nov 14 22:47:22 2004 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file provides the SunOS specific implementation of the TimeValue class. +// This file provides the SunOS implementation of the TimeValue class. // //===----------------------------------------------------------------------===// From reid at x10sys.com Sun Nov 14 22:48:10 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:48:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/FreeBSD/TimeValue.cpp Message-ID: <200411150448.WAA27401@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/FreeBSD: TimeValue.cpp updated: 1.3 -> 1.4 --- Log message: Actually get the #include correct so it compiles .. duh. --- Diffs of the changes: (+2 -2) Index: llvm/lib/System/FreeBSD/TimeValue.cpp diff -u llvm/lib/System/FreeBSD/TimeValue.cpp:1.3 llvm/lib/System/FreeBSD/TimeValue.cpp:1.4 --- llvm/lib/System/FreeBSD/TimeValue.cpp:1.3 Sun Nov 14 22:36:34 2004 +++ llvm/lib/System/FreeBSD/TimeValue.cpp Sun Nov 14 22:47:22 2004 @@ -7,12 +7,12 @@ // //===----------------------------------------------------------------------===// // -// This file provides the FreeBSD specific implementation of the TimeValue class. +// This file provides the FreeBSD implementation of the TimeValue class. // //===----------------------------------------------------------------------===// // Include the generic Unix implementation -#include "../Unix/Unix.cpp" +#include "../Unix/TimeValue.cpp" namespace llvm { using namespace sys; From reid at x10sys.com Sun Nov 14 22:48:10 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 14 Nov 2004 22:48:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/TimeValue.cpp Message-ID: <200411150448.WAA27398@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: TimeValue.cpp updated: 1.2 -> 1.3 --- Log message: Actually get the #include correct so it compiles .. duh. --- Diffs of the changes: (+1 -1) Index: llvm/lib/System/Win32/TimeValue.cpp diff -u llvm/lib/System/Win32/TimeValue.cpp:1.2 llvm/lib/System/Win32/TimeValue.cpp:1.3 --- llvm/lib/System/Win32/TimeValue.cpp:1.2 Tue Sep 28 18:56:20 2004 +++ llvm/lib/System/Win32/TimeValue.cpp Sun Nov 14 22:47:22 2004 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file provides the Win32 specific implementation of the TimeValue class. +// This file provides the Win32 implementation of the TimeValue class. // //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Sun Nov 14 23:03:44 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 23:03:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200411150503.iAF53ixg031228@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: SCCP.cpp updated: 1.106 -> 1.107 --- Log message: rename InstValue to LatticeValue, as it holds for more than instructions. --- Diffs of the changes: (+37 -35) Index: llvm/lib/Transforms/Scalar/SCCP.cpp diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.106 llvm/lib/Transforms/Scalar/SCCP.cpp:1.107 --- llvm/lib/Transforms/Scalar/SCCP.cpp:1.106 Sun Nov 14 22:44:20 2004 +++ llvm/lib/Transforms/Scalar/SCCP.cpp Sun Nov 14 23:03:30 2004 @@ -21,6 +21,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "sccp" #include "llvm/Transforms/Scalar.h" #include "llvm/Constants.h" #include "llvm/Function.h" @@ -38,13 +39,13 @@ #include using namespace llvm; -// InstVal class - This class represents the different lattice values that an +// LatticeVal class - This class represents the different lattice values that an // instruction may occupy. It is a simple class with value semantics. // namespace { Statistic<> NumInstRemoved("sccp", "Number of instructions removed"); -class InstVal { +class LatticeVal { enum { undefined, // This instruction has no known value constant, // This instruction has a constant value @@ -52,7 +53,7 @@ } LatticeValue; // The current lattice position Constant *ConstantVal; // If Constant value, the current value public: - inline InstVal() : LatticeValue(undefined), ConstantVal(0) {} + inline LatticeVal() : LatticeValue(undefined), ConstantVal(0) {} // markOverdefined - Return true if this is a new status to be in... inline bool markOverdefined() { @@ -95,7 +96,7 @@ /// class SCCPSolver : public InstVisitor { std::set BBExecutable;// The basic blocks that are executable - hash_map ValueState; // The state each value is in... + hash_map ValueState; // The state each value is in... // The reason for two worklists is that overdefined is the lowest state // on the lattice, and moving things to overdefined as fast as possible @@ -139,8 +140,8 @@ } /// getValueMapping - Once we have solved for constants, return the mapping of - /// LLVM values to InstVals. - hash_map &getValueMapping() { + /// LLVM values to LatticeVals. + hash_map &getValueMapping() { return ValueState; } @@ -149,7 +150,7 @@ // is not already a constant, add it to the instruction work list so that // the users of the instruction are updated later. // - inline void markConstant(InstVal &IV, Instruction *I, Constant *C) { + inline void markConstant(LatticeVal &IV, Instruction *I, Constant *C) { if (IV.markConstant(C)) { DEBUG(std::cerr << "markConstant: " << *C << ": " << *I); InstWorkList.push_back(I); @@ -163,7 +164,7 @@ // value is not already overdefined, add it to the overdefined instruction // work list so that the users of the instruction are updated later. - inline void markOverdefined(InstVal &IV, Instruction *I) { + inline void markOverdefined(LatticeVal &IV, Instruction *I) { if (IV.markOverdefined()) { DEBUG(std::cerr << "markOverdefined: " << *I); // Only instructions go on the work list @@ -174,14 +175,14 @@ markOverdefined(ValueState[I], I); } - // getValueState - Return the InstVal object that corresponds to the value. + // getValueState - Return the LatticeVal object that corresponds to the value. // This function is necessary because not all values should start out in the // underdefined state... Argument's should be overdefined, and // constants should be marked as constants. If a value is not known to be an // Instruction object, then use this accessor to get its value from the map. // - inline InstVal &getValueState(Value *V) { - hash_map::iterator I = ValueState.find(V); + inline LatticeVal &getValueState(Value *V) { + hash_map::iterator I = ValueState.find(V); if (I != ValueState.end()) return I->second; // Common case, in the map if (isa(V)) { @@ -291,7 +292,7 @@ if (BI->isUnconditional()) { Succs[0] = true; } else { - InstVal &BCValue = getValueState(BI->getCondition()); + LatticeVal &BCValue = getValueState(BI->getCondition()); if (BCValue.isOverdefined() || (BCValue.isConstant() && !isa(BCValue.getConstant()))) { // Overdefined condition variables, and branches on unfoldable constant @@ -306,7 +307,7 @@ // Invoke instructions successors are always executable. Succs[0] = Succs[1] = true; } else if (SwitchInst *SI = dyn_cast(&TI)) { - InstVal &SCValue = getValueState(SI->getCondition()); + LatticeVal &SCValue = getValueState(SI->getCondition()); if (SCValue.isOverdefined() || // Overdefined condition? (SCValue.isConstant() && !isa(SCValue.getConstant()))) { // All destinations are executable! @@ -347,7 +348,7 @@ if (BI->isUnconditional()) return true; else { - InstVal &BCValue = getValueState(BI->getCondition()); + LatticeVal &BCValue = getValueState(BI->getCondition()); if (BCValue.isOverdefined()) { // Overdefined condition variables mean the branch could go either way. return true; @@ -365,7 +366,7 @@ // Invoke instructions successors are always executable. return true; } else if (SwitchInst *SI = dyn_cast(TI)) { - InstVal &SCValue = getValueState(SI->getCondition()); + LatticeVal &SCValue = getValueState(SI->getCondition()); if (SCValue.isOverdefined()) { // Overdefined condition? // All destinations are executable! return true; @@ -409,7 +410,7 @@ // successors executable. // void SCCPSolver::visitPHINode(PHINode &PN) { - InstVal &PNIV = getValueState(&PN); + LatticeVal &PNIV = getValueState(&PN); if (PNIV.isOverdefined()) { // There may be instructions using this PHI node that are not overdefined // themselves. If so, make sure that they know that the PHI node operand @@ -443,7 +444,7 @@ // Constant *OperandVal = 0; for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { - InstVal &IV = getValueState(PN.getIncomingValue(i)); + LatticeVal &IV = getValueState(PN.getIncomingValue(i)); if (IV.isUndefined()) continue; // Doesn't influence PHI node. if (isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent())) { @@ -494,7 +495,7 @@ void SCCPSolver::visitCastInst(CastInst &I) { Value *V = I.getOperand(0); - InstVal &VState = getValueState(V); + LatticeVal &VState = getValueState(V); if (VState.isOverdefined()) // Inherit overdefinedness of operand markOverdefined(&I); else if (VState.isConstant()) // Propagate constant value @@ -502,18 +503,18 @@ } void SCCPSolver::visitSelectInst(SelectInst &I) { - InstVal &CondValue = getValueState(I.getCondition()); + LatticeVal &CondValue = getValueState(I.getCondition()); if (CondValue.isOverdefined()) markOverdefined(&I); else if (CondValue.isConstant()) { if (CondValue.getConstant() == ConstantBool::True) { - InstVal &Val = getValueState(I.getTrueValue()); + LatticeVal &Val = getValueState(I.getTrueValue()); if (Val.isOverdefined()) markOverdefined(&I); else if (Val.isConstant()) markConstant(&I, Val.getConstant()); } else if (CondValue.getConstant() == ConstantBool::False) { - InstVal &Val = getValueState(I.getFalseValue()); + LatticeVal &Val = getValueState(I.getFalseValue()); if (Val.isOverdefined()) markOverdefined(&I); else if (Val.isConstant()) @@ -525,11 +526,11 @@ // Handle BinaryOperators and Shift Instructions... void SCCPSolver::visitBinaryOperator(Instruction &I) { - InstVal &IV = ValueState[&I]; + LatticeVal &IV = ValueState[&I]; if (IV.isOverdefined()) return; - InstVal &V1State = getValueState(I.getOperand(0)); - InstVal &V2State = getValueState(I.getOperand(1)); + LatticeVal &V1State = getValueState(I.getOperand(0)); + LatticeVal &V2State = getValueState(I.getOperand(1)); if (V1State.isOverdefined() || V2State.isOverdefined()) { // If both operands are PHI nodes, it is possible that this instruction has @@ -544,11 +545,12 @@ // evaluating this expression with all incoming value pairs is the // same, then this expression is a constant even though the PHI node // is not a constant! - InstVal Result; + LatticeVal Result; for (unsigned i = 0, e = PN1->getNumIncomingValues(); i != e; ++i) { - InstVal &In1 = getValueState(PN1->getIncomingValue(i)); + LatticeVal &In1 = getValueState(PN1->getIncomingValue(i)); BasicBlock *InBlock = PN1->getIncomingBlock(i); - InstVal &In2 =getValueState(PN2->getIncomingValueForBlock(InBlock)); + LatticeVal &In2 = + getValueState(PN2->getIncomingValueForBlock(InBlock)); if (In1.isOverdefined() || In2.isOverdefined()) { Result.markOverdefined(); @@ -611,14 +613,14 @@ // can turn this into a getelementptr ConstantExpr. // void SCCPSolver::visitGetElementPtrInst(GetElementPtrInst &I) { - InstVal &IV = ValueState[&I]; + LatticeVal &IV = ValueState[&I]; if (IV.isOverdefined()) return; std::vector Operands; Operands.reserve(I.getNumOperands()); for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { - InstVal &State = getValueState(I.getOperand(i)); + LatticeVal &State = getValueState(I.getOperand(i)); if (State.isUndefined()) return; // Operands are not resolved yet... else if (State.isOverdefined()) { @@ -664,10 +666,10 @@ // Handle load instructions. If the operand is a constant pointer to a constant // global, we can replace the load with the loaded constant value! void SCCPSolver::visitLoadInst(LoadInst &I) { - InstVal &IV = ValueState[&I]; + LatticeVal &IV = ValueState[&I]; if (IV.isOverdefined()) return; - InstVal &PtrVal = getValueState(I.getOperand(0)); + LatticeVal &PtrVal = getValueState(I.getOperand(0)); if (PtrVal.isUndefined()) return; // The pointer is not resolved yet! if (PtrVal.isConstant() && !I.isVolatile()) { Value *Ptr = PtrVal.getConstant(); @@ -702,7 +704,7 @@ } void SCCPSolver::visitCallInst(CallInst &I) { - InstVal &IV = ValueState[&I]; + LatticeVal &IV = ValueState[&I]; if (IV.isOverdefined()) return; Function *F = I.getCalledFunction(); @@ -715,7 +717,7 @@ Operands.reserve(I.getNumOperands()-1); for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) { - InstVal &State = getValueState(I.getOperand(i)); + LatticeVal &State = getValueState(I.getOperand(i)); if (State.isUndefined()) return; // Operands are not resolved yet... else if (State.isOverdefined()) { @@ -845,12 +847,12 @@ // constants if we have found them to be of constant values. // bool MadeChanges = false; - hash_map &Values = Solver.getValueMapping(); + hash_map &Values = Solver.getValueMapping(); for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) for (BasicBlock::iterator BI = BB->begin(), E = BB->end(); BI != E; ) { Instruction *Inst = BI++; if (Inst->getType() != Type::VoidTy) { - InstVal &IV = Values[Inst]; + LatticeVal &IV = Values[Inst]; if (IV.isConstant() || IV.isUndefined()) { Constant *Const; if (IV.isConstant()) { From brukman at cs.uiuc.edu Sun Nov 14 23:20:04 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Sun, 14 Nov 2004 23:20:04 -0600 Subject: [llvm-commits] CVS: llvm/docs/GettingStarted.html Message-ID: <200411150520.XAA27985@zion.cs.uiuc.edu> Changes in directory llvm/docs: GettingStarted.html updated: 1.72 -> 1.73 --- Log message: Replace the textual description with table specifying disk space requirements --- Diffs of the changes: (+55 -60) Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.72 llvm/docs/GettingStarted.html:1.73 --- llvm/docs/GettingStarted.html:1.72 Thu Nov 11 01:30:27 2004 +++ llvm/docs/GettingStarted.html Sun Nov 14 23:19:53 2004 @@ -188,66 +188,61 @@

    LLVM is known to work on the following platforms:

    -
      - -
    • Linux on x86 (Pentium and above) -
        -
      • Approximately 2.6 GB of Free Disk Space -
          -
        • Source code: 57 MB
        • -
        • Object code: 2.5 GB
        • -
        • GCC front end: 30 MB
        • -
      • -
      -
    • - -
    • Solaris on SparcV9 (Ultrasparc) -
        -
      • Approximately 2.6 GB of Free Disk Space -
          -
        • Source code: 57 MB
        • -
        • Object code: 2.5 GB
        • -
        • GCC front end: 46 MB
        • -
      • -
      -
    • - -
    • FreeBSD on x86 (Pentium and above) -
        -
      • Approximately 1 GB of Free Disk Space -
          -
        • Source code: 57 MB
        • -
        • Object code: 850 MB
        • -
        • GCC front end: 40 MB
        • -
      • -
      -
    • - -
    • MacOS X on PowerPC -
        -
      • Experimental support for static native code generation -
      • Approximately 1.6 GB of Free Disk Space -
          -
        • Source code: 57 MB
        • -
        • Object code: 1.5 GB
        • -
        • GCC front end: 36 MB
        • -
      • -
      -
    • - -
    • AIX on PowerPC -
        -
      • No native code generation
        -
      • Approximately 2 GB of Free Disk Space -
          -
        • Source code: 92 MB
        • -
        • Object code: 2.8 GB
        • -
        • GCC front end: 123 MB
        • -
      • -
      -
    • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      OSArchSource codeObject codeGCC front endTotal space
      Linuxx86157 MB2.5 GB30 MB2.6 GB
      SolarisV9 (Ultrasparc)57 MB2.5 GB46 MB2.6 GB
      FreeBSDx86157 MB850 GB40 MB1 GB
      MacOS XPowerPC57 MB1.5 GB36 MB1.6 GB
      AIX2PowerPC92 MB2.8 GB123 MB3 GB
      -
    +

    +1 Code generation supported for Pentium processors and up
    +2 No native code generation +

    The LLVM suite may compile on other platforms, but it is not guaranteed to do so. If compilation is successful, the LLVM utilities should be @@ -1318,7 +1313,7 @@ Chris Lattner
    Reid Spencer
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/11/11 07:30:27 $ + Last modified: $Date: 2004/11/15 05:19:53 $ From lattner at cs.uiuc.edu Sun Nov 14 23:45:47 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 23:45:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200411150545.iAF5jlKm032234@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: SCCP.cpp updated: 1.107 -> 1.108 --- Log message: Two minor improvements: 1. Speedup getValueState by having it not consider Arguments. It's better to just add them before we start SCCP'ing. 2. SCCP can delete the contents of dead blocks. No really, it's ok! This reduces the size of the IR for subsequent passes, even though simplifycfg would do the same job. In practice, simplifycfg does not run until much later than sccp in gccas --- Diffs of the changes: (+37 -13) Index: llvm/lib/Transforms/Scalar/SCCP.cpp diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.107 llvm/lib/Transforms/Scalar/SCCP.cpp:1.108 --- llvm/lib/Transforms/Scalar/SCCP.cpp:1.107 Sun Nov 14 23:03:30 2004 +++ llvm/lib/Transforms/Scalar/SCCP.cpp Sun Nov 14 23:45:33 2004 @@ -185,12 +185,12 @@ hash_map::iterator I = ValueState.find(V); if (I != ValueState.end()) return I->second; // Common case, in the map - if (isa(V)) { - // Nothing to do, remain undefined. - } else if (Constant *CPV = dyn_cast(V)) { - ValueState[CPV].markConstant(CPV); // Constants are constant - } else if (isa(V)) { // Arguments are overdefined - ValueState[V].markOverdefined(); + if (Constant *CPV = dyn_cast(V)) { + if (isa(V)) { + // Nothing to do, remain undefined. + } else { + ValueState[CPV].markConstant(CPV); // Constants are constant + } } // All others are underdefined by default... return ValueState[V]; @@ -829,25 +829,49 @@ // and return true if the function was modified. // bool SCCP::runOnFunction(Function &F) { + DEBUG(std::cerr << "SCCP on function '" << F.getName() << "'\n"); SCCPSolver Solver; // Mark the first block of the function as being executable. Solver.MarkBlockExecutable(F.begin()); + // Mark all arguments to the function as being overdefined. + hash_map &Values = Solver.getValueMapping(); + for (Function::aiterator AI = F.abegin(), E = F.aend(); AI != E; ++AI) + Values[AI].markOverdefined(); + // Solve for constants. Solver.Solve(); - DEBUG(std::cerr << "SCCP on function '" << F.getName() << "'\n"); - DEBUG(std::set &ExecutableBBs = Solver.getExecutableBlocks(); - for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) - if (!ExecutableBBs.count(I)) - std::cerr << " BasicBlock Dead:" << *I); + bool MadeChanges = false; + + // If we decided that there are basic blocks that are dead in this function, + // delete their contents now. Note that we cannot actually delete the blocks, + // as we cannot modify the CFG of the function. + // + std::set &ExecutableBBs = Solver.getExecutableBlocks(); + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + if (!ExecutableBBs.count(BB)) { + DEBUG(std::cerr << " BasicBlock Dead:" << *BB); + // Delete the instructions backwards, as it has a reduced likelihood of + // having to update as many def-use and use-def chains. + std::vector Insts; + for (BasicBlock::iterator I = BB->begin(), E = BB->getTerminator(); + I != E; ++I) + Insts.push_back(I); + while (!Insts.empty()) { + Instruction *I = Insts.back(); + Insts.pop_back(); + if (!I->use_empty()) + I->replaceAllUsesWith(UndefValue::get(I->getType())); + BB->getInstList().erase(I); + MadeChanges = true; + } + } // Iterate over all of the instructions in a function, replacing them with // constants if we have found them to be of constant values. // - bool MadeChanges = false; - hash_map &Values = Solver.getValueMapping(); for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) for (BasicBlock::iterator BI = BB->begin(), E = BB->end(); BI != E; ) { Instruction *Inst = BI++; From lattner at cs.uiuc.edu Sun Nov 14 23:54:19 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 14 Nov 2004 23:54:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200411150554.iAF5sJOT032434@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.284 -> 1.285 --- Log message: Quiet warnings on the persephone tester --- Diffs of the changes: (+2 -2) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.284 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.285 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.284 Sun Nov 14 13:29:34 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 14 23:54:07 2004 @@ -329,10 +329,10 @@ if (V->hasOneUse() && V->getType()->isInteger()) if (Instruction *I = dyn_cast(V)) { if (I->getOpcode() == Instruction::Mul) - if (CST = dyn_cast(I->getOperand(1))) + if ((CST = dyn_cast(I->getOperand(1)))) return I->getOperand(0); if (I->getOpcode() == Instruction::Shl) - if (CST = dyn_cast(I->getOperand(1))) { + if ((CST = dyn_cast(I->getOperand(1)))) { // The multiplier is really 1 << CST. Constant *One = ConstantInt::get(V->getType(), 1); CST = cast(ConstantExpr::getShl(One, CST));